From e5d082b0dc2dc7ed8017f9921f7a043c7c395493 Mon Sep 17 00:00:00 2001 From: Pavel Grafov Date: Wed, 8 Mar 2023 13:38:35 +0000 Subject: [PATCH] Show work lock confirmation in a task overlay WorkLockActivity is added on top of each task that has any work activity when the profile is locked. This activity is a task overlay meaning it stays on top of other activities. It then starts ConfirmDeviceCredentialActivity, also as an overlay because otherwise it will sink under WorkLockActivity. But when CDCA launches CofirmLockPattern, it is not set as an overlay and as a result is not visible. These CLs add a boolean extra to instruct CDCA to launch CLP (or other activities) as an overlay. Bug: 271840143 Bug: 234002331 Test: manual, with TestDPC setting password reset token. Test: m RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.password Change-Id: Ie9b593696a24ad0c435b36eef80e3fe760c588ba --- .../password/ChooseLockSettingsHelper.java | 43 ++++++++++++++---- .../ConfirmDeviceCredentialActivity.java | 44 +++++-------------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java index 020b725f5ad..26e84bed15f 100644 --- a/src/com/android/settings/password/ChooseLockSettingsHelper.java +++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java @@ -21,12 +21,14 @@ import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; +import android.app.ActivityOptions; import android.app.KeyguardManager; import android.app.RemoteLockscreenValidationSession; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Intent; import android.content.IntentSender; +import android.os.Bundle; import android.os.UserManager; import android.util.Log; @@ -147,7 +149,8 @@ public final class ChooseLockSettingsHelper { private boolean mRemoteLockscreenValidation; @Nullable private RemoteLockscreenValidationSession mRemoteLockscreenValidationSession; @Nullable private ComponentName mRemoteLockscreenValidationServiceComponent; - boolean mRequestGatekeeperPasswordHandle; + private boolean mRequestGatekeeperPasswordHandle; + private boolean mTaskOverlay; public Builder(@NonNull Activity activity) { mActivity = activity; @@ -252,6 +255,14 @@ public final class ChooseLockSettingsHelper { return this; } + /** + * @param taskOverlay specifies whether the activity should be launched as a task overlay. + */ + @NonNull public Builder setTaskOverlay(boolean taskOverlay) { + mTaskOverlay = taskOverlay; + return this; + } + /** * @param foregroundOnly if true, the confirmation activity will be finished if it loses * foreground. @@ -371,7 +382,8 @@ public final class ChooseLockSettingsHelper { mBuilder.mCheckBoxLabel, mBuilder.mRemoteLockscreenValidation, mBuilder.mRemoteLockscreenValidationSession, mBuilder.mRemoteLockscreenValidationServiceComponent, mBuilder.mAllowAnyUserId, - mBuilder.mForegroundOnly, mBuilder.mRequestGatekeeperPasswordHandle); + mBuilder.mForegroundOnly, mBuilder.mRequestGatekeeperPasswordHandle, + mBuilder.mTaskOverlay); } private boolean launchConfirmationActivity(int request, @Nullable CharSequence title, @@ -381,7 +393,8 @@ public final class ChooseLockSettingsHelper { @Nullable CharSequence checkboxLabel, boolean remoteLockscreenValidation, @Nullable RemoteLockscreenValidationSession remoteLockscreenValidationSession, @Nullable ComponentName remoteLockscreenValidationServiceComponent, - boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle) { + boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle, + boolean taskOverlay) { Optional> activityClass = determineAppropriateActivityClass( returnCredentials, forceVerifyPath, userId, remoteLockscreenValidationSession); if (activityClass.isEmpty()) { @@ -392,7 +405,7 @@ public final class ChooseLockSettingsHelper { returnCredentials, external, forceVerifyPath, userId, alternateButton, checkboxLabel, remoteLockscreenValidation, remoteLockscreenValidationSession, remoteLockscreenValidationServiceComponent, allowAnyUser, foregroundOnly, - requestGatekeeperPasswordHandle); + requestGatekeeperPasswordHandle, taskOverlay); } private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header, @@ -402,7 +415,8 @@ public final class ChooseLockSettingsHelper { boolean remoteLockscreenValidation, @Nullable RemoteLockscreenValidationSession remoteLockscreenValidationSession, @Nullable ComponentName remoteLockscreenValidationServiceComponent, - boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle) { + boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPasswordHandle, + boolean taskOverlay) { final Intent intent = new Intent(); intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title); intent.putExtra(ConfirmDeviceCredentialBaseFragment.HEADER_TEXT, header); @@ -434,28 +448,39 @@ public final class ChooseLockSettingsHelper { Intent inIntent = mFragment != null ? mFragment.getActivity().getIntent() : mActivity.getIntent(); copyInternalExtras(inIntent, intent); + Bundle launchOptions = createLaunchOptions(taskOverlay); if (external) { intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); copyOptionalExtras(inIntent, intent); if (mActivityResultLauncher != null) { mActivityResultLauncher.launch(intent); } else if (mFragment != null) { - mFragment.startActivity(intent); + mFragment.startActivity(intent, launchOptions); } else { - mActivity.startActivity(intent); + mActivity.startActivity(intent, launchOptions); } } else { if (mActivityResultLauncher != null) { mActivityResultLauncher.launch(intent); } else if (mFragment != null) { - mFragment.startActivityForResult(intent, request); + mFragment.startActivityForResult(intent, request, launchOptions); } else { - mActivity.startActivityForResult(intent, request); + mActivity.startActivityForResult(intent, request, launchOptions); } } return true; } + private Bundle createLaunchOptions(boolean taskOverlay) { + if (!taskOverlay) { + return null; + } + ActivityOptions options = ActivityOptions.makeBasic(); + options.setLaunchTaskId(mActivity.getTaskId()); + options.setTaskOverlay(true /* taskOverlay */, true /* canResume */); + return options.toBundle(); + } + private Optional passwordQualityToLockTypes(int quality) { switch (quality) { case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java index 328e44003e5..fbcebb8fe5f 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java @@ -24,8 +24,6 @@ import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROF import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_PATTERN; import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_PIN; -import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME; - import android.app.Activity; import android.app.KeyguardManager; import android.app.RemoteLockscreenValidationSession; @@ -63,13 +61,6 @@ import java.util.concurrent.Executor; public class ConfirmDeviceCredentialActivity extends FragmentActivity { public static final String TAG = ConfirmDeviceCredentialActivity.class.getSimpleName(); - /** - * If the intent is sent from {@link com.android.systemui.keyguard.WorkLockActivityController} - * then check for device policy management flags. - */ - public static final String EXTRA_FROM_WORK_LOCK_ACTIVITY_CONTROLLER = - "from_work_lock_activity_controller"; - // The normal flow that apps go through private static final int CREDENTIAL_NORMAL = 1; // Unlocks the managed profile when the primary profile is unlocked @@ -80,15 +71,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { public static class InternalActivity extends ConfirmDeviceCredentialActivity { } - public static Intent createIntent(CharSequence title, CharSequence details) { - Intent intent = new Intent(); - intent.setClassName(SETTINGS_PACKAGE_NAME, - ConfirmDeviceCredentialActivity.class.getName()); - intent.putExtra(KeyguardManager.EXTRA_TITLE, title); - intent.putExtra(KeyguardManager.EXTRA_DESCRIPTION, details); - return intent; - } - private BiometricFragment mBiometricFragment; private DevicePolicyManager mDevicePolicyManager; private LockPatternUtils mLockPatternUtils; @@ -97,6 +79,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { private Handler mHandler = new Handler(Looper.getMainLooper()); private Context mContext; private boolean mCheckDevicePolicyManager; + private boolean mTaskOverlay; private String mTitle; private CharSequence mDetails; @@ -186,6 +169,8 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { boolean frp = KeyguardManager.ACTION_CONFIRM_FRP_CREDENTIAL.equals(intent.getAction()); boolean remoteValidation = KeyguardManager.ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL.equals(intent.getAction()); + mTaskOverlay = isInternalActivity() + && intent.getBooleanExtra(KeyguardManager.EXTRA_FORCE_TASK_OVERLAY, false); mUserId = UserHandle.myUserId(); if (isInternalActivity()) { @@ -417,6 +402,12 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { */ private void showConfirmCredentials() { boolean launched = false; + ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(this) + .setHeader(mTitle) + .setDescription(mDetails) + .setExternal(true) + .setUserId(mUserId) + .setTaskOverlay(mTaskOverlay); // The only difference between CREDENTIAL_MANAGED and CREDENTIAL_NORMAL is that for // CREDENTIAL_MANAGED, we launch the real confirm credential activity with an explicit // but fake challenge value (0L). This will result in ConfirmLockPassword calling @@ -429,22 +420,9 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { // LockPatternChecker and LockPatternUtils. verifyPassword should be the only API to use, // which optionally accepts a challenge. if (mCredentialMode == CREDENTIAL_MANAGED) { - final ChooseLockSettingsHelper.Builder builder = - new ChooseLockSettingsHelper.Builder(this); - launched = builder.setHeader(mTitle) - .setDescription(mDetails) - .setExternal(true) - .setUserId(mUserId) - .setForceVerifyPath(true) - .show(); + launched = builder.setForceVerifyPath(true).show(); } else if (mCredentialMode == CREDENTIAL_NORMAL) { - final ChooseLockSettingsHelper.Builder builder = - new ChooseLockSettingsHelper.Builder(this); - launched = builder.setHeader(mTitle) // Show the title string in the header area - .setDescription(mDetails) - .setExternal(true) - .setUserId(mUserId) - .show(); + launched = builder.show(); } if (!launched) { Log.d(TAG, "No pin/pattern/pass set");