Enable auth check for profiles with shared credentials

This change adds a separate block to handle auth checks for all profiles
that have the property alwaysRequireAuthenticationToDisableQuietMode set
to true. The force verify path is to be invoked for all such profiles
that share credentials with parent.

Test: m -j RunSettingsRoboTests or atest SettingsRoboTest
Bug: 293571176

Change-Id: Iec133bd9dfb22299cbd56ab811f341fa3957ead3
This commit is contained in:
Jigar Thakkar
2023-11-06 20:23:43 +00:00
parent 56f5e53ae8
commit 41cda1f8bb

View File

@@ -31,6 +31,7 @@ import android.app.trust.TrustManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.UserProperties;
import android.content.res.Configuration;
import android.graphics.Color;
import android.hardware.biometrics.BiometricConstants;
@@ -61,11 +62,6 @@ import java.util.concurrent.Executor;
public class ConfirmDeviceCredentialActivity extends FragmentActivity {
public static final String TAG = ConfirmDeviceCredentialActivity.class.getSimpleName();
// The normal flow that apps go through
private static final int CREDENTIAL_NORMAL = 1;
// Unlocks the managed profile when the primary profile is unlocked
private static final int CREDENTIAL_MANAGED = 2;
private static final String TAG_BIOMETRIC_FRAGMENT = "fragment";
public static class InternalActivity extends ConfirmDeviceCredentialActivity {
@@ -84,7 +80,9 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
private String mTitle;
private CharSequence mDetails;
private int mUserId;
private int mCredentialMode;
// Used to force the verification path required to unlock profile that shares credentials with
// with parent
private boolean mForceVerifyPath = false;
private boolean mGoingToBackground;
private boolean mWaitingForBiometricCallback;
@@ -189,7 +187,9 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
}
final int effectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
final boolean isEffectiveUserManagedProfile =
UserManager.get(this).isManagedProfile(effectiveUserId);
mUserManager.isManagedProfile(effectiveUserId);
final UserProperties userProperties =
mUserManager.getUserProperties(UserHandle.of(mUserId));
// if the client app did not hand in a title and we are about to show the work challenge,
// check whether there is a policy setting the organization name and use that as title
if ((mTitle == null) && isEffectiveUserManagedProfile) {
@@ -278,7 +278,19 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
.setForceVerifyPath(true)
.show();
} else if (isEffectiveUserManagedProfile && isInternalActivity()) {
mCredentialMode = CREDENTIAL_MANAGED;
// When the mForceVerifyPath is set to true, we launch the real confirm credential
// activity with an explicit but fake challenge value (0L). This will result in
// ConfirmLockPassword calling verifyTiedProfileChallenge() (if it's a profile with
// unified challenge), due to the difference between
// ConfirmLockPassword.startVerifyPassword() and
// ConfirmLockPassword.startCheckPassword(). Calling verifyTiedProfileChallenge() here
// is necessary when this is part of the turning on work profile flow, because it forces
// unlocking the work profile even before the profile is running.
// TODO: Remove the duplication of checkPassword and verifyPassword in
// ConfirmLockPassword,
// LockPatternChecker and LockPatternUtils. verifyPassword should be the only API to
// use, which optionally accepts a challenge.
mForceVerifyPath = true;
if (isBiometricAllowed(effectiveUserId, mUserId)) {
showBiometricPrompt(promptInfo);
launchedBiometric = true;
@@ -286,8 +298,19 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
showConfirmCredentials();
launchedCDC = true;
}
} else if (android.os.Flags.allowPrivateProfile()
&& userProperties != null
&& userProperties.isAuthAlwaysRequiredToDisableQuietMode()
&& isInternalActivity()) {
// Force verification path is required to be invoked as we might need to verify the tied
// profile challenge if the profile is using the unified challenge mode. This would
// result in ConfirmLockPassword.startVerifyPassword/
// ConfirmLockPattern.startVerifyPattern being called instead of the
// startCheckPassword/startCheckPattern
mForceVerifyPath = userProperties.isCredentialShareableWithParent();
showConfirmCredentials();
launchedCDC = true;
} else {
mCredentialMode = CREDENTIAL_NORMAL;
if (isBiometricAllowed(effectiveUserId, mUserId)) {
// Don't need to check if biometrics / pin/pattern/pass are enrolled. It will go to
// onAuthenticationError and do the right thing automatically.
@@ -313,11 +336,8 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
private String getTitleFromCredentialType(@LockPatternUtils.CredentialType int credentialType,
boolean isEffectiveUserManagedProfile) {
int overrideStringId;
int defaultStringId;
switch (credentialType) {
case LockPatternUtils.CREDENTIAL_TYPE_PIN:
if (isEffectiveUserManagedProfile) {
return mDevicePolicyManager.getResources().getString(
CONFIRM_WORK_PROFILE_PIN_HEADER,
@@ -410,29 +430,15 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
* Shows ConfirmDeviceCredentials for normal apps.
*/
private void showConfirmCredentials() {
boolean launched = false;
ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(this)
boolean launched = 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
// verifyTiedProfileChallenge() (if it's a profile with unified challenge), due to the
// difference between ConfirmLockPassword.startVerifyPassword() and
// ConfirmLockPassword.startCheckPassword(). Calling verifyTiedProfileChallenge() here is
// necessary when this is part of the turning on work profile flow, because it forces
// unlocking the work profile even before the profile is running.
// TODO: Remove the duplication of checkPassword and verifyPassword in ConfirmLockPassword,
// LockPatternChecker and LockPatternUtils. verifyPassword should be the only API to use,
// which optionally accepts a challenge.
if (mCredentialMode == CREDENTIAL_MANAGED) {
launched = builder.setForceVerifyPath(true).show();
} else if (mCredentialMode == CREDENTIAL_NORMAL) {
launched = builder.show();
}
.setTaskOverlay(mTaskOverlay)
.setForceVerifyPath(mForceVerifyPath)
.show();
if (!launched) {
Log.d(TAG, "No pin/pattern/pass set");
setResult(Activity.RESULT_OK);