1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.screenshot; 18 19 import static android.view.Display.DEFAULT_DISPLAY; 20 21 import static com.android.systemui.screenshot.ScreenshotController.ACTION_TYPE_EDIT; 22 import static com.android.systemui.screenshot.ScreenshotController.ACTION_TYPE_SHARE; 23 import static com.android.systemui.screenshot.ScreenshotController.EXTRA_ACTION_INTENT; 24 import static com.android.systemui.screenshot.ScreenshotController.EXTRA_DISALLOW_ENTER_PIP; 25 import static com.android.systemui.screenshot.ScreenshotController.EXTRA_ID; 26 import static com.android.systemui.screenshot.ScreenshotController.EXTRA_SMART_ACTIONS_ENABLED; 27 import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_SCREENSHOT; 28 29 import android.app.ActivityOptions; 30 import android.app.PendingIntent; 31 import android.content.BroadcastReceiver; 32 import android.content.Context; 33 import android.content.Intent; 34 import android.util.Log; 35 import android.view.RemoteAnimationAdapter; 36 import android.view.WindowManagerGlobal; 37 38 import com.android.systemui.shared.system.ActivityManagerWrapper; 39 import com.android.systemui.statusbar.phone.StatusBar; 40 41 import java.util.Optional; 42 43 import javax.inject.Inject; 44 45 /** 46 * Receiver to proxy the share or edit intent, used to clean up the notification and send 47 * appropriate signals to the system (ie. to dismiss the keyguard if necessary). 48 */ 49 public class ActionProxyReceiver extends BroadcastReceiver { 50 private static final String TAG = "ActionProxyReceiver"; 51 52 private final StatusBar mStatusBar; 53 private final ActivityManagerWrapper mActivityManagerWrapper; 54 private final ScreenshotSmartActions mScreenshotSmartActions; 55 56 @Inject ActionProxyReceiver(Optional<StatusBar> statusBar, ActivityManagerWrapper activityManagerWrapper, ScreenshotSmartActions screenshotSmartActions)57 public ActionProxyReceiver(Optional<StatusBar> statusBar, 58 ActivityManagerWrapper activityManagerWrapper, 59 ScreenshotSmartActions screenshotSmartActions) { 60 mStatusBar = statusBar.orElse(null); 61 mActivityManagerWrapper = activityManagerWrapper; 62 mScreenshotSmartActions = screenshotSmartActions; 63 } 64 65 @Override onReceive(Context context, final Intent intent)66 public void onReceive(Context context, final Intent intent) { 67 Runnable startActivityRunnable = () -> { 68 mActivityManagerWrapper.closeSystemWindows(SYSTEM_DIALOG_REASON_SCREENSHOT); 69 70 PendingIntent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT); 71 ActivityOptions opts = ActivityOptions.makeBasic(); 72 opts.setDisallowEnterPictureInPictureWhileLaunching( 73 intent.getBooleanExtra(EXTRA_DISALLOW_ENTER_PIP, false)); 74 try { 75 actionIntent.send(context, 0, null, null, null, null, opts.toBundle()); 76 if (intent.getBooleanExtra(ScreenshotController.EXTRA_OVERRIDE_TRANSITION, false)) { 77 RemoteAnimationAdapter runner = new RemoteAnimationAdapter( 78 ScreenshotController.SCREENSHOT_REMOTE_RUNNER, 0, 0); 79 try { 80 WindowManagerGlobal.getWindowManagerService() 81 .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY); 82 } catch (Exception e) { 83 Log.e(TAG, "Error overriding screenshot app transition", e); 84 } 85 } 86 } catch (PendingIntent.CanceledException e) { 87 Log.e(TAG, "Pending intent canceled", e); 88 } 89 90 }; 91 92 if (mStatusBar != null) { 93 mStatusBar.executeRunnableDismissingKeyguard(startActivityRunnable, null, 94 true /* dismissShade */, true /* afterKeyguardGone */, 95 true /* deferred */); 96 } else { 97 startActivityRunnable.run(); 98 } 99 100 if (intent.getBooleanExtra(EXTRA_SMART_ACTIONS_ENABLED, false)) { 101 String actionType = Intent.ACTION_EDIT.equals(intent.getAction()) 102 ? ACTION_TYPE_EDIT 103 : ACTION_TYPE_SHARE; 104 mScreenshotSmartActions.notifyScreenshotAction( 105 context, intent.getStringExtra(EXTRA_ID), actionType, false, null); 106 } 107 } 108 } 109