Loading packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +28 −80 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.systemui.screenshot; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; Loading @@ -27,11 +26,10 @@ import static java.util.Objects.requireNonNull; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.Notification; import android.content.ComponentName; import android.content.Context; import android.content.res.Configuration; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.Insets; import android.graphics.PixelFormat; Loading Loading @@ -64,6 +62,7 @@ import android.widget.Toast; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.PhoneWindow; import com.android.settingslib.applications.InterestingConfigChanges; import com.android.systemui.R; import com.android.systemui.util.DeviceConfigProxy; Loading Loading @@ -145,7 +144,6 @@ public class ScreenshotController { private final WindowManager mWindowManager; private final WindowManager.LayoutParams mWindowLayoutParams; private final Display mDisplay; private final DisplayMetrics mDisplayMetrics; private final AccessibilityManager mAccessibilityManager; private final MediaActionSound mCameraSound; Loading @@ -162,9 +160,6 @@ public class ScreenshotController { private Animator mScreenshotAnimation; private Runnable mOnCompleteRunnable; private boolean mInDarkMode; private boolean mDirectionLTR; private boolean mOrientationPortrait; private final Handler mScreenshotHandler = new Handler(Looper.getMainLooper()) { @Override Loading @@ -180,6 +175,15 @@ public class ScreenshotController { } }; /** Tracks config changes that require re-creating UI */ private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges( ActivityInfo.CONFIG_ORIENTATION | ActivityInfo.CONFIG_LAYOUT_DIRECTION | ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_UI_MODE | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS); @Inject ScreenshotController( Context context, Loading @@ -194,23 +198,20 @@ public class ScreenshotController { mUiEventLogger = uiEventLogger; final DisplayManager dm = requireNonNull(context.getSystemService(DisplayManager.class)); mDisplay = dm.getDisplay(DEFAULT_DISPLAY); mContext = context.createWindowContext(TYPE_SCREENSHOT, null); final Display display = dm.getDisplay(DEFAULT_DISPLAY); final Context displayContext = context.createDisplayContext(display); mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null); mWindowManager = mContext.getSystemService(WindowManager.class); mAccessibilityManager = AccessibilityManager.getInstance(mContext); mConfigProxy = configProxy; Configuration config = mContext.getResources().getConfiguration(); mInDarkMode = config.isNightModeActive(); mDirectionLTR = config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; mOrientationPortrait = config.orientation == ORIENTATION_PORTRAIT; mWindowToken = new Binder("ScreenshotController"); mScrollCaptureClient.setHostWindowToken(mWindowToken); // Setup the window that we are going to use mWindowLayoutParams = new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT, 0, 0, TYPE_SCREENSHOT, mWindowLayoutParams = new WindowManager.LayoutParams( MATCH_PARENT, MATCH_PARENT, /* xpos */ 0, /* ypos */ 0, TYPE_SCREENSHOT, WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL Loading @@ -235,7 +236,7 @@ public class ScreenshotController { reloadAssets(); mDisplayMetrics = new DisplayMetrics(); mDisplay.getRealMetrics(mDisplayMetrics); display.getRealMetrics(mDisplayMetrics); // Setup the Camera shutter sound mCameraSound = new MediaActionSound(); Loading @@ -245,7 +246,6 @@ public class ScreenshotController { void takeScreenshotFullscreen(Consumer<Uri> finisher, Runnable onComplete) { mOnCompleteRunnable = onComplete; mDisplay.getRealMetrics(mDisplayMetrics); takeScreenshotInternal( finisher, new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels)); Loading @@ -266,19 +266,18 @@ public class ScreenshotController { return; } if (aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) { saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, false); } else { saveScreenshot(screenshot, finisher, new Rect(0, 0, screenshot.getWidth(), screenshot.getHeight()), Insets.NONE, true); boolean showFlash = false; if (!aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) { showFlash = true; visibleInsets = Insets.NONE; screenshotScreenBounds.set(0, 0, screenshot.getWidth(), screenshot.getHeight()); } saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, showFlash); } /** * Displays a screenshot selector */ @SuppressLint("ClickableViewAccessibility") void takeScreenshotPartial(final Consumer<Uri> finisher, Runnable onComplete) { dismissScreenshot(true); mOnCompleteRunnable = onComplete; Loading Loading @@ -308,60 +307,6 @@ public class ScreenshotController { } } private void onConfigChanged(Configuration newConfig) { boolean needsUpdate = false; // dark mode if (newConfig.isNightModeActive()) { // Night mode is active, we're using dark theme if (!mInDarkMode) { mInDarkMode = true; needsUpdate = true; } } else { // Night mode is not active, we're using the light theme if (mInDarkMode) { mInDarkMode = false; needsUpdate = true; } } // RTL configuration switch (newConfig.getLayoutDirection()) { case View.LAYOUT_DIRECTION_LTR: if (!mDirectionLTR) { mDirectionLTR = true; needsUpdate = true; } break; case View.LAYOUT_DIRECTION_RTL: if (mDirectionLTR) { mDirectionLTR = false; needsUpdate = true; } break; } // portrait/landscape orientation switch (newConfig.orientation) { case ORIENTATION_PORTRAIT: if (!mOrientationPortrait) { mOrientationPortrait = true; needsUpdate = true; } break; case ORIENTATION_LANDSCAPE: if (mOrientationPortrait) { mOrientationPortrait = false; needsUpdate = true; } break; } if (needsUpdate) { reloadAssets(); } } /** * Update assets (called when the dark theme status changes). We only need to update the dismiss * button and the actions container background, since the buttons are re-inflated on demand. Loading @@ -373,8 +318,9 @@ public class ScreenshotController { } // respect the display cutout in landscape (since we'd otherwise overlap) but not portrait int orientation = mContext.getResources().getConfiguration().orientation; mWindowLayoutParams.setFitInsetsTypes( mOrientationPortrait ? 0 : WindowInsets.Type.displayCutout()); orientation == ORIENTATION_PORTRAIT ? 0 : WindowInsets.Type.displayCutout()); // ignore system bar insets for the purpose of window layout mDecorView.setOnApplyWindowInsetsListener((v, insets) -> v.onApplyWindowInsets( Loading Loading @@ -469,7 +415,9 @@ public class ScreenshotController { mScreenBitmap.setHasAlpha(false); mScreenBitmap.prepareToDraw(); onConfigChanged(mContext.getResources().getConfiguration()); if (mConfigChanges.applyNewConfig(mContext.getResources())) { reloadAssets(); } // The window is focusable by default setWindowFocusable(true); Loading packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +75 −73 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ import android.os.UserManager; import android.util.Log; import android.view.WindowManager; import androidx.annotation.NonNull; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.ScreenshotHelper; import com.android.systemui.R; Loading @@ -57,9 +59,8 @@ public class TakeScreenshotService extends Service { private final UserManager mUserManager; private final UiEventLogger mUiEventLogger; private final ScreenshotNotificationsController mNotificationsController; private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { private final Handler mHandler; private final BroadcastReceiver mCloseSystemDialogs = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction()) && mScreenshot != null) { Loading @@ -68,24 +69,37 @@ public class TakeScreenshotService extends Service { } }; private Handler mHandler = new Handler(Looper.myLooper()) { @Inject public TakeScreenshotService(ScreenshotController screenshotController, UserManager userManager, UiEventLogger uiEventLogger, ScreenshotNotificationsController notificationsController) { mHandler = new Handler(Looper.getMainLooper(), this::handleMessage); mScreenshot = screenshotController; mUserManager = userManager; mUiEventLogger = uiEventLogger; mNotificationsController = notificationsController; } @Override public void handleMessage(Message msg) { final Messenger callback = msg.replyTo; Consumer<Uri> uriConsumer = uri -> { Message reply = Message.obtain(null, SCREENSHOT_MSG_URI, uri); try { callback.send(reply); } catch (RemoteException e) { public IBinder onBind(@NonNull Intent intent) { registerReceiver(mCloseSystemDialogs, new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS)); return new Messenger(mHandler).getBinder(); } }; Runnable onComplete = () -> { Message reply = Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE); try { callback.send(reply); } catch (RemoteException e) { @Override public boolean onUnbind(Intent intent) { if (mScreenshot != null) { mScreenshot.dismissScreenshot(true); } unregisterReceiver(mCloseSystemDialogs); return false; } }; /** Respond to incoming Message via Binder (Messenger) */ private boolean handleMessage(Message msg) { final Messenger replyTo = msg.replyTo; final Runnable onComplete = () -> sendComplete(replyTo); final Consumer<Uri> uriConsumer = (uri) -> reportUri(replyTo, uri); // If the storage for this user is locked, we have no place to store // the screenshot, so skip taking it instead of showing a misleading Loading @@ -94,9 +108,9 @@ public class TakeScreenshotService extends Service { Log.w(TAG, "Skipping screenshot because storage is locked!"); mNotificationsController.notifyScreenshotError( R.string.screenshot_failed_to_save_user_locked_text); post(() -> uriConsumer.accept(null)); post(onComplete); return; uriConsumer.accept(null); onComplete.run(); return true; } ScreenshotHelper.ScreenshotRequest screenshotRequest = Loading @@ -123,39 +137,27 @@ public class TakeScreenshotService extends Service { taskId, userId, topComponent, uriConsumer, onComplete); break; default: Log.d(TAG, "Invalid screenshot option: " + msg.what); } Log.w(TAG, "Invalid screenshot option: " + msg.what); return false; } return true; }; @Inject public TakeScreenshotService( ScreenshotController screenshotController, UserManager userManager, UiEventLogger uiEventLogger, ScreenshotNotificationsController notificationsController) { mScreenshot = screenshotController; mUserManager = userManager; mUiEventLogger = uiEventLogger; mNotificationsController = notificationsController; private void sendComplete(Messenger target) { try { Log.d(TAG, "sendComplete: " + target); target.send(Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE)); } catch (RemoteException e) { Log.d(TAG, "ignored remote exception", e); } @Override public IBinder onBind(Intent intent) { // register broadcast receiver IntentFilter filter = new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS); registerReceiver(mBroadcastReceiver, filter); return new Messenger(mHandler).getBinder(); } @Override public boolean onUnbind(Intent intent) { if (mScreenshot != null) { mScreenshot.dismissScreenshot(true); private void reportUri(Messenger target, Uri uri) { try { Log.d(TAG, "reportUri: " + target + " -> " + uri); target.send(Message.obtain(null, SCREENSHOT_MSG_URI, uri)); } catch (RemoteException e) { Log.d(TAG, "ignored remote exception", e); } unregisterReceiver(mBroadcastReceiver); return true; } } Loading
packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +28 −80 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.systemui.screenshot; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; Loading @@ -27,11 +26,10 @@ import static java.util.Objects.requireNonNull; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.Notification; import android.content.ComponentName; import android.content.Context; import android.content.res.Configuration; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.Insets; import android.graphics.PixelFormat; Loading Loading @@ -64,6 +62,7 @@ import android.widget.Toast; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.PhoneWindow; import com.android.settingslib.applications.InterestingConfigChanges; import com.android.systemui.R; import com.android.systemui.util.DeviceConfigProxy; Loading Loading @@ -145,7 +144,6 @@ public class ScreenshotController { private final WindowManager mWindowManager; private final WindowManager.LayoutParams mWindowLayoutParams; private final Display mDisplay; private final DisplayMetrics mDisplayMetrics; private final AccessibilityManager mAccessibilityManager; private final MediaActionSound mCameraSound; Loading @@ -162,9 +160,6 @@ public class ScreenshotController { private Animator mScreenshotAnimation; private Runnable mOnCompleteRunnable; private boolean mInDarkMode; private boolean mDirectionLTR; private boolean mOrientationPortrait; private final Handler mScreenshotHandler = new Handler(Looper.getMainLooper()) { @Override Loading @@ -180,6 +175,15 @@ public class ScreenshotController { } }; /** Tracks config changes that require re-creating UI */ private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges( ActivityInfo.CONFIG_ORIENTATION | ActivityInfo.CONFIG_LAYOUT_DIRECTION | ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_UI_MODE | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS); @Inject ScreenshotController( Context context, Loading @@ -194,23 +198,20 @@ public class ScreenshotController { mUiEventLogger = uiEventLogger; final DisplayManager dm = requireNonNull(context.getSystemService(DisplayManager.class)); mDisplay = dm.getDisplay(DEFAULT_DISPLAY); mContext = context.createWindowContext(TYPE_SCREENSHOT, null); final Display display = dm.getDisplay(DEFAULT_DISPLAY); final Context displayContext = context.createDisplayContext(display); mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null); mWindowManager = mContext.getSystemService(WindowManager.class); mAccessibilityManager = AccessibilityManager.getInstance(mContext); mConfigProxy = configProxy; Configuration config = mContext.getResources().getConfiguration(); mInDarkMode = config.isNightModeActive(); mDirectionLTR = config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; mOrientationPortrait = config.orientation == ORIENTATION_PORTRAIT; mWindowToken = new Binder("ScreenshotController"); mScrollCaptureClient.setHostWindowToken(mWindowToken); // Setup the window that we are going to use mWindowLayoutParams = new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT, 0, 0, TYPE_SCREENSHOT, mWindowLayoutParams = new WindowManager.LayoutParams( MATCH_PARENT, MATCH_PARENT, /* xpos */ 0, /* ypos */ 0, TYPE_SCREENSHOT, WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL Loading @@ -235,7 +236,7 @@ public class ScreenshotController { reloadAssets(); mDisplayMetrics = new DisplayMetrics(); mDisplay.getRealMetrics(mDisplayMetrics); display.getRealMetrics(mDisplayMetrics); // Setup the Camera shutter sound mCameraSound = new MediaActionSound(); Loading @@ -245,7 +246,6 @@ public class ScreenshotController { void takeScreenshotFullscreen(Consumer<Uri> finisher, Runnable onComplete) { mOnCompleteRunnable = onComplete; mDisplay.getRealMetrics(mDisplayMetrics); takeScreenshotInternal( finisher, new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels)); Loading @@ -266,19 +266,18 @@ public class ScreenshotController { return; } if (aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) { saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, false); } else { saveScreenshot(screenshot, finisher, new Rect(0, 0, screenshot.getWidth(), screenshot.getHeight()), Insets.NONE, true); boolean showFlash = false; if (!aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) { showFlash = true; visibleInsets = Insets.NONE; screenshotScreenBounds.set(0, 0, screenshot.getWidth(), screenshot.getHeight()); } saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, showFlash); } /** * Displays a screenshot selector */ @SuppressLint("ClickableViewAccessibility") void takeScreenshotPartial(final Consumer<Uri> finisher, Runnable onComplete) { dismissScreenshot(true); mOnCompleteRunnable = onComplete; Loading Loading @@ -308,60 +307,6 @@ public class ScreenshotController { } } private void onConfigChanged(Configuration newConfig) { boolean needsUpdate = false; // dark mode if (newConfig.isNightModeActive()) { // Night mode is active, we're using dark theme if (!mInDarkMode) { mInDarkMode = true; needsUpdate = true; } } else { // Night mode is not active, we're using the light theme if (mInDarkMode) { mInDarkMode = false; needsUpdate = true; } } // RTL configuration switch (newConfig.getLayoutDirection()) { case View.LAYOUT_DIRECTION_LTR: if (!mDirectionLTR) { mDirectionLTR = true; needsUpdate = true; } break; case View.LAYOUT_DIRECTION_RTL: if (mDirectionLTR) { mDirectionLTR = false; needsUpdate = true; } break; } // portrait/landscape orientation switch (newConfig.orientation) { case ORIENTATION_PORTRAIT: if (!mOrientationPortrait) { mOrientationPortrait = true; needsUpdate = true; } break; case ORIENTATION_LANDSCAPE: if (mOrientationPortrait) { mOrientationPortrait = false; needsUpdate = true; } break; } if (needsUpdate) { reloadAssets(); } } /** * Update assets (called when the dark theme status changes). We only need to update the dismiss * button and the actions container background, since the buttons are re-inflated on demand. Loading @@ -373,8 +318,9 @@ public class ScreenshotController { } // respect the display cutout in landscape (since we'd otherwise overlap) but not portrait int orientation = mContext.getResources().getConfiguration().orientation; mWindowLayoutParams.setFitInsetsTypes( mOrientationPortrait ? 0 : WindowInsets.Type.displayCutout()); orientation == ORIENTATION_PORTRAIT ? 0 : WindowInsets.Type.displayCutout()); // ignore system bar insets for the purpose of window layout mDecorView.setOnApplyWindowInsetsListener((v, insets) -> v.onApplyWindowInsets( Loading Loading @@ -469,7 +415,9 @@ public class ScreenshotController { mScreenBitmap.setHasAlpha(false); mScreenBitmap.prepareToDraw(); onConfigChanged(mContext.getResources().getConfiguration()); if (mConfigChanges.applyNewConfig(mContext.getResources())) { reloadAssets(); } // The window is focusable by default setWindowFocusable(true); Loading
packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +75 −73 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ import android.os.UserManager; import android.util.Log; import android.view.WindowManager; import androidx.annotation.NonNull; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.ScreenshotHelper; import com.android.systemui.R; Loading @@ -57,9 +59,8 @@ public class TakeScreenshotService extends Service { private final UserManager mUserManager; private final UiEventLogger mUiEventLogger; private final ScreenshotNotificationsController mNotificationsController; private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { private final Handler mHandler; private final BroadcastReceiver mCloseSystemDialogs = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction()) && mScreenshot != null) { Loading @@ -68,24 +69,37 @@ public class TakeScreenshotService extends Service { } }; private Handler mHandler = new Handler(Looper.myLooper()) { @Inject public TakeScreenshotService(ScreenshotController screenshotController, UserManager userManager, UiEventLogger uiEventLogger, ScreenshotNotificationsController notificationsController) { mHandler = new Handler(Looper.getMainLooper(), this::handleMessage); mScreenshot = screenshotController; mUserManager = userManager; mUiEventLogger = uiEventLogger; mNotificationsController = notificationsController; } @Override public void handleMessage(Message msg) { final Messenger callback = msg.replyTo; Consumer<Uri> uriConsumer = uri -> { Message reply = Message.obtain(null, SCREENSHOT_MSG_URI, uri); try { callback.send(reply); } catch (RemoteException e) { public IBinder onBind(@NonNull Intent intent) { registerReceiver(mCloseSystemDialogs, new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS)); return new Messenger(mHandler).getBinder(); } }; Runnable onComplete = () -> { Message reply = Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE); try { callback.send(reply); } catch (RemoteException e) { @Override public boolean onUnbind(Intent intent) { if (mScreenshot != null) { mScreenshot.dismissScreenshot(true); } unregisterReceiver(mCloseSystemDialogs); return false; } }; /** Respond to incoming Message via Binder (Messenger) */ private boolean handleMessage(Message msg) { final Messenger replyTo = msg.replyTo; final Runnable onComplete = () -> sendComplete(replyTo); final Consumer<Uri> uriConsumer = (uri) -> reportUri(replyTo, uri); // If the storage for this user is locked, we have no place to store // the screenshot, so skip taking it instead of showing a misleading Loading @@ -94,9 +108,9 @@ public class TakeScreenshotService extends Service { Log.w(TAG, "Skipping screenshot because storage is locked!"); mNotificationsController.notifyScreenshotError( R.string.screenshot_failed_to_save_user_locked_text); post(() -> uriConsumer.accept(null)); post(onComplete); return; uriConsumer.accept(null); onComplete.run(); return true; } ScreenshotHelper.ScreenshotRequest screenshotRequest = Loading @@ -123,39 +137,27 @@ public class TakeScreenshotService extends Service { taskId, userId, topComponent, uriConsumer, onComplete); break; default: Log.d(TAG, "Invalid screenshot option: " + msg.what); } Log.w(TAG, "Invalid screenshot option: " + msg.what); return false; } return true; }; @Inject public TakeScreenshotService( ScreenshotController screenshotController, UserManager userManager, UiEventLogger uiEventLogger, ScreenshotNotificationsController notificationsController) { mScreenshot = screenshotController; mUserManager = userManager; mUiEventLogger = uiEventLogger; mNotificationsController = notificationsController; private void sendComplete(Messenger target) { try { Log.d(TAG, "sendComplete: " + target); target.send(Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE)); } catch (RemoteException e) { Log.d(TAG, "ignored remote exception", e); } @Override public IBinder onBind(Intent intent) { // register broadcast receiver IntentFilter filter = new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS); registerReceiver(mBroadcastReceiver, filter); return new Messenger(mHandler).getBinder(); } @Override public boolean onUnbind(Intent intent) { if (mScreenshot != null) { mScreenshot.dismissScreenshot(true); private void reportUri(Messenger target, Uri uri) { try { Log.d(TAG, "reportUri: " + target + " -> " + uri); target.send(Message.obtain(null, SCREENSHOT_MSG_URI, uri)); } catch (RemoteException e) { Log.d(TAG, "ignored remote exception", e); } unregisterReceiver(mBroadcastReceiver); return true; } }