From 36f0a83ead4c111c87012eea65a806d7a8415660 Mon Sep 17 00:00:00 2001 From: Issei Suzuki Date: Wed, 27 Apr 2022 11:20:32 +0000 Subject: [PATCH] Add ActivityOption to remove keyguard when an activity is launched. Replaced ActivityOption#dismissKeyguardIfInsecure by ActivityOption#dismissKeyguard, with which the server doesn't check if the keyguard is insecure again. The caller has to make sure if the keygaurd can be dismissed without additional authentication. Bug: 203044476 Test: atest KeyguardLockedTests KeyguardTransitionTests Change-Id: Ia83da6286875f1a539edbaf515fe01c07ce1ba76 Merged-In: Ia83da6286875f1a539edbaf515fe01c07ce1ba76 --- core/java/android/app/ActivityOptions.java | 28 +++++++++---------- .../am/ActivityManagerShellCommand.java | 10 +++---- .../com/android/server/wm/ActivityRecord.java | 4 +-- .../android/server/wm/KeyguardController.java | 4 +-- .../server/wm/SafeActivityOptions.java | 15 ++++++++++ 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 2eebc01ccc04c..d6441a2b629b8 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -16,6 +16,7 @@ package android.app; +import static android.Manifest.permission.CONTROL_KEYGUARD; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; @@ -362,9 +363,8 @@ 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 {@link #setDismissKeyguard()}. */ + private static final String KEY_DISMISS_KEYGUARD = "android.activity.dismissKeyguard"; private static final String KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE = "android.activity.ignorePendingIntentCreatorForegroundState"; @@ -465,7 +465,7 @@ public class ActivityOptions extends ComponentOptions { private boolean mLaunchedFromBubble; private boolean mTransientLaunch; private PictureInPictureParams mLaunchIntoPipParams; - private boolean mDismissKeyguardIfInsecure; + private boolean mDismissKeyguard; private boolean mIgnorePendingIntentCreatorForegroundState; /** @@ -1270,7 +1270,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); + mDismissKeyguard = opts.getBoolean(KEY_DISMISS_KEYGUARD); mIgnorePendingIntentCreatorForegroundState = opts.getBoolean( KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE); } @@ -1869,24 +1869,24 @@ 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. + * Sets whether the keyguard should go away when this activity launches. * * @see Activity#setShowWhenLocked(boolean) * @see android.R.attr#showWhenLocked * @hide */ - public void setDismissKeyguardIfInsecure() { - mDismissKeyguardIfInsecure = true; + @RequiresPermission(CONTROL_KEYGUARD) + public void setDismissKeyguard() { + mDismissKeyguard = true; } /** - * @see #setDismissKeyguardIfInsecure() + * @see #setDismissKeyguard() * @return whether the insecure keyguard should go away when the activity launches. * @hide */ - public boolean getDismissKeyguardIfInsecure() { - return mDismissKeyguardIfInsecure; + public boolean getDismissKeyguard() { + return mDismissKeyguard; } /** @@ -2167,8 +2167,8 @@ public class ActivityOptions extends ComponentOptions { b.putBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE, mIsEligibleForLegacyPermissionPrompt); } - if (mDismissKeyguardIfInsecure) { - b.putBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE, mDismissKeyguardIfInsecure); + if (mDismissKeyguard) { + b.putBoolean(KEY_DISMISS_KEYGUARD, mDismissKeyguard); } if (mIgnorePendingIntentCreatorForegroundState) { b.putBoolean(KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE, diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 397a4420700e9..f83d444c24663 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -183,7 +183,7 @@ final class ActivityManagerShellCommand extends ShellCommand { private boolean mAsync; private BroadcastOptions mBroadcastOptions; private boolean mShowSplashScreen; - private boolean mDismissKeyguardIfInsecure; + private boolean mDismissKeyguard; final boolean mDumping; @@ -442,8 +442,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 if (opt.equals("--dismiss-keyguard")) { + mDismissKeyguard = true; } else { return false; } @@ -588,11 +588,11 @@ final class ActivityManagerShellCommand extends ShellCommand { } options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON); } - if (mDismissKeyguardIfInsecure) { + if (mDismissKeyguard) { if (options == null) { options = ActivityOptions.makeBasic(); } - options.setDismissKeyguardIfInsecure(); + options.setDismissKeyguard(); } if (mWaitOption) { result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, null, intent, diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 9fa68e959810e..beba5ca4d6868 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -873,7 +873,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A boolean mEnteringAnimation; boolean mOverrideTaskTransition; - boolean mDismissKeyguardIfInsecure; + boolean mDismissKeyguard; boolean mAppStopped; // A hint to override the window specified rotation animation, or -1 to use the window specified @@ -1987,7 +1987,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } mOverrideTaskTransition = options.getOverrideTaskTransition(); - mDismissKeyguardIfInsecure = options.getDismissKeyguardIfInsecure(); + mDismissKeyguard = options.getDismissKeyguard(); } 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 f36dbfa2316e7..01c94142f46b3 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -589,9 +589,7 @@ class KeyguardController { mTopTurnScreenOnActivity = top; } - final boolean isKeyguardSecure = controller.mWindowManager.isKeyguardSecure( - controller.mService.getCurrentUserId()); - if (top.mDismissKeyguardIfInsecure && mKeyguardShowing && !isKeyguardSecure) { + if (top.mDismissKeyguard && mKeyguardShowing) { mKeyguardGoingAway = true; } else if (top.canShowWhenLocked()) { mTopOccludesActivity = top; diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java index 2d4aef682d623..fd05f19f54c57 100644 --- a/services/core/java/com/android/server/wm/SafeActivityOptions.java +++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.Manifest.permission.CONTROL_KEYGUARD; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.Manifest.permission.STATUS_BAR_SERVICE; @@ -297,6 +298,20 @@ public class SafeActivityOptions { } } + // Check if the caller is allowed to dismiss keyguard. + final boolean dismissKeyguard = options.getDismissKeyguard(); + if (aInfo != null && dismissKeyguard) { + final int controlKeyguardPerm = ActivityTaskManagerService.checkPermission( + CONTROL_KEYGUARD, callingPid, callingUid); + if (controlKeyguardPerm != PERMISSION_GRANTED) { + final String msg = "Permission Denial: starting " + getIntentString(intent) + + " from " + callerApp + " (pid=" + callingPid + + ", uid=" + callingUid + ") with dismissKeyguard=true"; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + } + // Check permission for remote animations final RemoteAnimationAdapter adapter = options.getRemoteAnimationAdapter(); if (adapter != null && supervisor.mService.checkPermission(