diff options
4 files changed, 76 insertions, 9 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 0d8103675cc2..0f54ce5f7a91 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -361,6 +361,10 @@ public class ActivityOptions extends ComponentOptions { private static final String KEY_LAUNCH_INTO_PIP_PARAMS = "android.activity.launchIntoPipParams"; + /** See {@link #setDismissKeyguardIfInsecure()}. */ + private static final String KEY_DISMISS_KEYGUARD_IF_INSECURE = + "android.activity.dismissKeyguardIfInsecure"; + /** * @see #setLaunchCookie * @hide @@ -457,6 +461,7 @@ public class ActivityOptions extends ComponentOptions { private boolean mLaunchedFromBubble; private boolean mTransientLaunch; private PictureInPictureParams mLaunchIntoPipParams; + private boolean mDismissKeyguardIfInsecure; /** * Create an ActivityOptions specifying a custom animation to run when @@ -1254,6 +1259,7 @@ public class ActivityOptions extends ComponentOptions { mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS); mIsEligibleForLegacyPermissionPrompt = opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE); + mDismissKeyguardIfInsecure = opts.getBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE); } /** @@ -1850,6 +1856,27 @@ public class ActivityOptions extends ComponentOptions { } /** + * Sets whether the insecure keyguard should go away when this activity launches. In case the + * keyguard is secure, this option will be ignored. + * + * @see Activity#setShowWhenLocked(boolean) + * @see android.R.attr#showWhenLocked + * @hide + */ + public void setDismissKeyguardIfInsecure() { + mDismissKeyguardIfInsecure = true; + } + + /** + * @see #setDismissKeyguardIfInsecure() + * @return whether the insecure keyguard should go away when the activity launches. + * @hide + */ + public boolean getDismissKeyguardIfInsecure() { + return mDismissKeyguardIfInsecure; + } + + /** * Update the current values in this ActivityOptions from those supplied * in <var>otherOptions</var>. Any values * defined in <var>otherOptions</var> replace those in the base options. @@ -2110,6 +2137,9 @@ public class ActivityOptions extends ComponentOptions { b.putBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE, mIsEligibleForLegacyPermissionPrompt); } + if (mDismissKeyguardIfInsecure) { + b.putBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE, mDismissKeyguardIfInsecure); + } return b; } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 2b61e7fd2752..5024a4a1cba0 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -183,6 +183,7 @@ final class ActivityManagerShellCommand extends ShellCommand { private boolean mAsync; private BroadcastOptions mBroadcastOptions; private boolean mShowSplashScreen; + private boolean mDismissKeyguardIfInsecure; final boolean mDumping; @@ -439,6 +440,8 @@ final class ActivityManagerShellCommand extends ShellCommand { mAsync = true; } else if (opt.equals("--splashscreen-show-icon")) { mShowSplashScreen = true; + } else if (opt.equals("--dismiss-keyguard-if-insecure")) { + mDismissKeyguardIfInsecure = true; } else { return false; } @@ -583,6 +586,12 @@ final class ActivityManagerShellCommand extends ShellCommand { } options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON); } + if (mDismissKeyguardIfInsecure) { + if (options == null) { + options = ActivityOptions.makeBasic(); + } + options.setDismissKeyguardIfInsecure(); + } if (mWaitOption) { result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, null, intent, mimeType, null, null, 0, mStartFlags, profilerInfo, diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 94f86462045a..0b52fd643a1c 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -856,6 +856,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A boolean mEnteringAnimation; boolean mOverrideTaskTransition; + boolean mDismissKeyguardIfInsecure; boolean mAppStopped; // A hint to override the window specified rotation animation, or -1 to use the window specified @@ -1953,6 +1954,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } mOverrideTaskTransition = options.getOverrideTaskTransition(); + mDismissKeyguardIfInsecure = options.getDismissKeyguardIfInsecure(); } ColorDisplayService.ColorDisplayServiceInternal cds = LocalServices.getService( diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 7bf150b18e9b..2ebb59751634 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -28,6 +28,7 @@ import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_W import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE; import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; +import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS; import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS; @@ -408,6 +409,25 @@ class KeyguardController { } /** + * Called when keyguard going away state changed. + */ + private void handleKeyguardGoingAwayChanged(DisplayContent dc) { + mService.deferWindowLayout(); + try { + dc.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, 0 /* transitFlags */); + // We are deprecating TRANSIT_KEYGUARD_GOING_AWAY for Shell transition and use + // TRANSIT_FLAG_KEYGUARD_GOING_AWAY to indicate that it should animate keyguard going + // away. + dc.mAtmService.getTransitionController().requestTransitionIfNeeded( + TRANSIT_OPEN, TRANSIT_FLAG_KEYGUARD_GOING_AWAY, null /* trigger */, dc); + updateKeyguardSleepToken(); + mWindowManager.executeAppTransition(); + } finally { + mService.continueWindowLayout(); + } + } + + /** * Called when somebody wants to dismiss the Keyguard via the flag. */ private void handleDismissKeyguard(int displayId) { @@ -533,11 +553,13 @@ class KeyguardController { } /** - * Updates {@link #mOccluded}, {@link #mTopTurnScreenOnActivity} and - * {@link #mDismissingKeyguardActivity} if the top task could be visible. + * Updates keyguard status if the top task could be visible. The top task may occlude + * keyguard, request to dismiss keyguard or make insecure keyguard go away based on its + * properties. */ void updateVisibility(KeyguardController controller, DisplayContent display) { final boolean lastOccluded = mOccluded; + final boolean lastKeyguardGoingAway = mKeyguardGoingAway; final ActivityRecord lastDismissKeyguardActivity = mDismissingKeyguardActivity; final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity; @@ -561,14 +583,18 @@ class KeyguardController { mTopTurnScreenOnActivity = top; } - final boolean showWhenLocked = top.canShowWhenLocked(); - if (showWhenLocked) { + final boolean isKeyguardSecure = controller.mWindowManager.isKeyguardSecure( + controller.mService.getCurrentUserId()); + if (top.mDismissKeyguardIfInsecure && mKeyguardShowing && !isKeyguardSecure) { + mKeyguardGoingAway = true; + } else if (top.canShowWhenLocked()) { mTopOccludesActivity = top; } // Only the top activity may control occluded, as we can't occlude the Keyguard // if the top app doesn't want to occlude it. - occludedByActivity = showWhenLocked || (mDismissingKeyguardActivity != null + occludedByActivity = mTopOccludesActivity != null + || (mDismissingKeyguardActivity != null && task.topRunningActivity() == mDismissingKeyguardActivity && controller.canShowWhileOccluded( true /* dismissKeyguard */, false /* showWhenLocked */)); @@ -583,10 +609,8 @@ class KeyguardController { && top.getActivityType() == ACTIVITY_TYPE_DREAM); mOccluded = mShowingDream || occludedByActivity; mRequestDismissKeyguard = lastDismissKeyguardActivity != mDismissingKeyguardActivity - && !mOccluded - && mDismissingKeyguardActivity != null - && controller.mWindowManager.isKeyguardSecure( - controller.mService.getCurrentUserId()); + && !mOccluded && !mKeyguardGoingAway + && mDismissingKeyguardActivity != null; if (mTopTurnScreenOnActivity != lastTurnScreenOnActivity && mTopTurnScreenOnActivity != null @@ -598,6 +622,8 @@ class KeyguardController { if (lastOccluded != mOccluded) { controller.handleOccludedChanged(mDisplayId, mTopOccludesActivity); + } else if (!lastKeyguardGoingAway && mKeyguardGoingAway) { + controller.handleKeyguardGoingAwayChanged(display); } } |