Merge "Enable auth check for profiles with shared credentials" into main

This commit is contained in:
Jigar Thakkar
2023-11-15 12:41:14 +00:00
committed by Android (Google) Code Review

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);