1/n: Make ChooseLockSettingsHelper into a builder

The multitude of slightly different launchConfirmationActivity(*)
methods are a big unsustainable pyramid. It's too difficult to
read, too difficult to track which clients are interested in which
parameters, and too difficult to add new parameters, since we need to

1) Read through all of them and find one that's the closest
2) Try not to affect other callers, so potentially add yet another
3) Modify the internal paths, which all basically call each other
   until it reaches the biggest launchConfirmationActivity which
   has ALL of the parameters

This change should have no behavioral change.

Note: CredentialStorage doesn't need returnCredentials anymore as of
      ag/6073449

Test: make -j56 RunSettingsRoboTests
Test: Manually traced code paths for each invocation. A few hidden
      dependencies (such as explicitly setting challenge=0 with
      hasChallenge=true) were found. Left them the way they were in
      case they were intended
Test: Enroll face, fingerprint
Test: Enable developer options
Test: Change to PIN, Pattern, Password, then back to PIN (so each
      type requests confirmation)
Test: adb shell am start -a android.app.action.CONFIRM_DEVICE_CREDENTIAL,
      authenticate
Test: adb shell am start -a android.app.action.CONFIRM_FRP_CREDENTIAL
      (shows confirm credential screen)
Fixes: 138453993

Change-Id: Ic82ef3c3ac2e14d624281921f2d816bcdacbd82b
This commit is contained in:
Kevin Chyn
2020-07-20 23:35:21 -07:00
parent bc7c42621b
commit b13bc50542
23 changed files with 403 additions and 446 deletions

View File

@@ -139,8 +139,11 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
*/ */
private boolean runKeyguardConfirmation(int request) { private boolean runKeyguardConfirmation(int request) {
Resources res = getActivity().getResources(); Resources res = getActivity().getResources();
return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity( final ChooseLockSettingsHelper.Builder builder =
request, res.getText(R.string.master_clear_short_title)); new ChooseLockSettingsHelper.Builder(getActivity(), this);
return builder.setRequestCode(request)
.setTitle(res.getText(R.string.master_clear_short_title))
.show();
} }
@VisibleForTesting @VisibleForTesting

View File

@@ -92,8 +92,11 @@ public class ResetNetwork extends InstrumentedFragment {
*/ */
private boolean runKeyguardConfirmation(int request) { private boolean runKeyguardConfirmation(int request) {
Resources res = getActivity().getResources(); Resources res = getActivity().getResources();
return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity( final ChooseLockSettingsHelper.Builder builder =
request, res.getText(R.string.reset_network_title)); new ChooseLockSettingsHelper.Builder(getActivity(), this);
return builder.setRequestCode(request)
.setTitle(res.getText(R.string.reset_network_title))
.show();
} }
@Override @Override

View File

@@ -634,7 +634,7 @@ public final class Utils extends com.android.settingslib.Utils {
* *
* @param isInternal indicating if the caller is "internal" to the system, * @param isInternal indicating if the caller is "internal" to the system,
* meaning we're willing to trust extras like * meaning we're willing to trust extras like
* {@link ChooseLockSettingsHelper#EXTRA_ALLOW_ANY_USER}. * {@link ChooseLockSettingsHelper#EXTRA_KEY_ALLOW_ANY_USER}.
* @throws SecurityException if the given userId does not belong to the * @throws SecurityException if the given userId does not belong to the
* current user group. * current user group.
*/ */
@@ -643,7 +643,7 @@ public final class Utils extends com.android.settingslib.Utils {
return getCredentialOwnerUserId(context); return getCredentialOwnerUserId(context);
} }
final boolean allowAnyUser = isInternal final boolean allowAnyUser = isInternal
&& bundle.getBoolean(ChooseLockSettingsHelper.EXTRA_ALLOW_ANY_USER, false); && bundle.getBoolean(ChooseLockSettingsHelper.EXTRA_KEY_ALLOW_ANY_USER, false);
final int userId = bundle.getInt(Intent.EXTRA_USER_ID, UserHandle.myUserId()); final int userId = bundle.getInt(Intent.EXTRA_USER_ID, UserHandle.myUserId());
if (userId == LockPatternUtils.USER_FRP) { if (userId == LockPatternUtils.USER_FRP) {
return allowAnyUser ? userId : enforceSystemUser(context, userId); return allowAnyUser ? userId : enforceSystemUser(context, userId);

View File

@@ -163,11 +163,13 @@ public class AddAccountSettings extends Activity {
} else { } else {
// If the user is locked by fbe: we couldn't start the authenticator. So we must ask the // If the user is locked by fbe: we couldn't start the authenticator. So we must ask the
// user to unlock it first. // user to unlock it first.
ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(this); final ChooseLockSettingsHelper.Builder builder =
if (!helper.launchConfirmationActivity(UNLOCK_WORK_PROFILE_REQUEST, new ChooseLockSettingsHelper.Builder(this);
getString(R.string.unlock_set_unlock_launch_picker_title), final boolean launched = builder.setRequestCode(UNLOCK_WORK_PROFILE_REQUEST)
false, .setTitle(getString(R.string.unlock_set_unlock_launch_picker_title))
mUserHandle.getIdentifier())) { .setUserId(mUserHandle.getIdentifier())
.show();
if (!launched) {
requestChooseAccount(); requestChooseAccount();
} }
} }

View File

@@ -39,9 +39,11 @@ public class ConvertToFbe extends InstrumentedFragment {
private boolean runKeyguardConfirmation(int request) { private boolean runKeyguardConfirmation(int request) {
Resources res = getActivity().getResources(); Resources res = getActivity().getResources();
return new ChooseLockSettingsHelper(getActivity(), this) final ChooseLockSettingsHelper.Builder builder =
.launchConfirmationActivity(request, new ChooseLockSettingsHelper.Builder(getActivity(), this);
res.getText(R.string.convert_to_file_encryption)); return builder.setRequestCode(request)
.setTitle(res.getText(R.string.convert_to_file_encryption))
.show();
} }
@Override @Override

View File

@@ -181,18 +181,19 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity {
} }
protected void launchConfirmLock(int titleResId, long challenge) { protected void launchConfirmLock(int titleResId, long challenge) {
ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(this); final ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(this);
boolean launchedConfirmationActivity; builder.setRequestCode(CONFIRM_REQUEST)
if (mUserId == UserHandle.USER_NULL) { .setTitle(getString(titleResId))
launchedConfirmationActivity = helper.launchConfirmationActivity(CONFIRM_REQUEST, .setChallenge(challenge)
getString(titleResId), .setForegroundOnly(true)
null, null, challenge, true /* foregroundOnly */); .setReturnCredentials(true);
} else {
launchedConfirmationActivity = helper.launchConfirmationActivity(CONFIRM_REQUEST, if (mUserId != UserHandle.USER_NULL) {
getString(titleResId), builder.setUserId(mUserId);
null, null, challenge, mUserId, true /* foregroundOnly */);
} }
if (!launchedConfirmationActivity) {
final boolean launched = builder.show();
if (!launched) {
// This shouldn't happen, as we should only end up at this step if a lock thingy is // This shouldn't happen, as we should only end up at this step if a lock thingy is
// already set. // already set.
finish(); finish();

View File

@@ -184,7 +184,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
} }
private void updatePasswordQuality() { private void updatePasswordQuality() {
final int passwordQuality = new ChooseLockSettingsHelper(this).utils() final int passwordQuality = new LockPatternUtils(this)
.getActivePasswordQuality(mUserManager.getCredentialOwnerProfile(mUserId)); .getActivePasswordQuality(mUserManager.getCredentialOwnerProfile(mUserId));
mHasPassword = passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; mHasPassword = passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
} }

View File

@@ -206,12 +206,18 @@ public class FaceSettings extends DashboardFragment {
// created while Keyguard is showing, in which case the resetLockout revokeChallenge // created while Keyguard is showing, in which case the resetLockout revokeChallenge
// will invalidate the too-early created challenge here. // will invalidate the too-early created challenge here.
final long challenge = mFaceManager.generateChallengeBlocking(); final long challenge = mFaceManager.generateChallengeBlocking();
ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this); final ChooseLockSettingsHelper.Builder builder =
new ChooseLockSettingsHelper.Builder(getActivity(), this);
final boolean launched = builder.setRequestCode(CONFIRM_REQUEST)
.setTitle(getString(R.string.security_settings_face_preference_title))
.setChallenge(challenge)
.setUserId(mUserId)
.setForegroundOnly(true)
.setReturnCredentials(true)
.show();
mConfirmingPassword = true; mConfirmingPassword = true;
if (!helper.launchConfirmationActivity(CONFIRM_REQUEST, if (!launched) {
getString(R.string.security_settings_face_preference_title),
null, null, challenge, mUserId, true /* foregroundOnly */)) {
Log.e(TAG, "Password not set"); Log.e(TAG, "Password not set");
finish(); finish();
} }

View File

@@ -634,12 +634,19 @@ public class FingerprintSettings extends SubSettings {
} }
private void launchChooseOrConfirmLock() { private void launchChooseOrConfirmLock() {
Intent intent = new Intent(); final Intent intent = new Intent();
long challenge = mFingerprintManager.generateChallengeBlocking(); final long challenge = mFingerprintManager.generateChallengeBlocking();
ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this); final ChooseLockSettingsHelper.Builder builder =
if (!helper.launchConfirmationActivity(CONFIRM_REQUEST, new ChooseLockSettingsHelper.Builder(getActivity(), this);
getString(R.string.security_settings_fingerprint_preference_title), final boolean launched = builder.setRequestCode(CONFIRM_REQUEST)
null, null, challenge, mUserId, true /* foregroundOnly */)) { .setTitle(getString(R.string.security_settings_fingerprint_preference_title))
.setChallenge(challenge)
.setUserId(mUserId)
.setForegroundOnly(true)
.setReturnCredentials(true)
.show();
if (!launched) {
intent.setClassName(SETTINGS_PACKAGE_NAME, ChooseLockGeneric.class.getName()); intent.setClassName(SETTINGS_PACKAGE_NAME, ChooseLockGeneric.class.getName());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);

View File

@@ -52,8 +52,8 @@ public class OemUnlockPreferenceController extends DeveloperOptionsPreferenceCon
private final OemLockManager mOemLockManager; private final OemLockManager mOemLockManager;
private final UserManager mUserManager; private final UserManager mUserManager;
private final TelephonyManager mTelephonyManager; private final TelephonyManager mTelephonyManager;
private final Activity mActivity;
private final DevelopmentSettingsDashboardFragment mFragment; private final DevelopmentSettingsDashboardFragment mFragment;
private final ChooseLockSettingsHelper mChooseLockSettingsHelper;
private RestrictedSwitchPreference mPreference; private RestrictedSwitchPreference mPreference;
public OemUnlockPreferenceController(Context context, Activity activity, public OemUnlockPreferenceController(Context context, Activity activity,
@@ -69,12 +69,8 @@ public class OemUnlockPreferenceController extends DeveloperOptionsPreferenceCon
} }
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
mActivity = activity;
mFragment = fragment; mFragment = fragment;
if (activity != null || mFragment != null) {
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(activity, mFragment);
} else {
mChooseLockSettingsHelper = null;
}
} }
@Override @Override
@@ -204,8 +200,11 @@ public class OemUnlockPreferenceController extends DeveloperOptionsPreferenceCon
@VisibleForTesting @VisibleForTesting
boolean showKeyguardConfirmation(Resources resources, int requestCode) { boolean showKeyguardConfirmation(Resources resources, int requestCode) {
return mChooseLockSettingsHelper.launchConfirmationActivity( final ChooseLockSettingsHelper.Builder builder =
requestCode, resources.getString(R.string.oem_unlock_enable)); new ChooseLockSettingsHelper.Builder(mActivity, mFragment);
return builder.setRequestCode(requestCode)
.setTitle(resources.getString(R.string.oem_unlock_enable))
.show();
} }
@VisibleForTesting @VisibleForTesting

View File

@@ -160,11 +160,16 @@ public class BuildNumberPreferenceController extends BasePreferenceController im
if (mDevHitCountdown == 0 && !mProcessingLastDevHit) { if (mDevHitCountdown == 0 && !mProcessingLastDevHit) {
// Add 1 count back, then start password confirmation flow. // Add 1 count back, then start password confirmation flow.
mDevHitCountdown++; mDevHitCountdown++;
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(mActivity, mFragment); final String title = mContext
mProcessingLastDevHit = helper.launchConfirmationActivity( .getString(R.string.unlock_set_unlock_launch_picker_title);
REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF, final ChooseLockSettingsHelper.Builder builder =
mContext.getString(R.string.unlock_set_unlock_launch_picker_title)); new ChooseLockSettingsHelper.Builder(mActivity, mFragment);
mProcessingLastDevHit = builder
.setRequestCode(REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF)
.setTitle(title)
.show();
if (!mProcessingLastDevHit) { if (!mProcessingLastDevHit) {
enableDevelopmentSettings(); enableDevelopmentSettings();
} }

View File

@@ -103,8 +103,14 @@ public class StorageWizardMigrateConfirm extends StorageWizardBase {
Log.d(TAG, "User " + user.id + " is currently locked; requesting unlock"); Log.d(TAG, "User " + user.id + " is currently locked; requesting unlock");
final CharSequence description = TextUtils.expandTemplate( final CharSequence description = TextUtils.expandTemplate(
getText(R.string.storage_wizard_move_unlock), user.name); getText(R.string.storage_wizard_move_unlock), user.name);
new ChooseLockSettingsHelper(this).launchConfirmationActivityForAnyUser( final ChooseLockSettingsHelper.Builder builder =
REQUEST_CREDENTIAL, null, null, description, user.id); new ChooseLockSettingsHelper.Builder(this);
builder.setRequestCode(REQUEST_CREDENTIAL)
.setDescription(description)
.setUserId(user.id)
.setAllowAnyUserId(true)
.setChallenge(0L)
.show();
return; return;
} }
} }

View File

@@ -85,8 +85,14 @@ public class StorageWizardMoveConfirm extends StorageWizardBase {
Log.d(TAG, "User " + user.id + " is currently locked; requesting unlock"); Log.d(TAG, "User " + user.id + " is currently locked; requesting unlock");
final CharSequence description = TextUtils.expandTemplate( final CharSequence description = TextUtils.expandTemplate(
getText(R.string.storage_wizard_move_unlock), user.name); getText(R.string.storage_wizard_move_unlock), user.name);
new ChooseLockSettingsHelper(this).launchConfirmationActivityForAnyUser( final ChooseLockSettingsHelper.Builder builder =
REQUEST_CREDENTIAL, null, null, description, user.id); new ChooseLockSettingsHelper.Builder(this);
builder.setRequestCode(REQUEST_CREDENTIAL)
.setDescription(description)
.setUserId(user.id)
.setChallenge(0L)
.setAllowAnyUserId(true)
.show();
return; return;
} }
} }

View File

@@ -142,7 +142,7 @@ public class ChooseLockGeneric extends SettingsActivity {
@VisibleForTesting @VisibleForTesting
static final int SKIP_FINGERPRINT_REQUEST = 104; static final int SKIP_FINGERPRINT_REQUEST = 104;
private ChooseLockSettingsHelper mChooseLockSettingsHelper; private LockPatternUtils mLockPatternUtils;
private DevicePolicyManager mDpm; private DevicePolicyManager mDpm;
private boolean mHasChallenge = false; private boolean mHasChallenge = false;
private long mChallenge; private long mChallenge;
@@ -150,7 +150,6 @@ public class ChooseLockGeneric extends SettingsActivity {
private boolean mWaitingForConfirmation = false; private boolean mWaitingForConfirmation = false;
private boolean mForChangeCredRequiredForBoot = false; private boolean mForChangeCredRequiredForBoot = false;
private LockscreenCredential mUserPassword; private LockscreenCredential mUserPassword;
private LockPatternUtils mLockPatternUtils;
private FingerprintManager mFingerprintManager; private FingerprintManager mFingerprintManager;
private FaceManager mFaceManager; private FaceManager mFaceManager;
private int mUserId; private int mUserId;
@@ -199,7 +198,6 @@ public class ChooseLockGeneric extends SettingsActivity {
mFingerprintManager = Utils.getFingerprintManagerOrNull(activity); mFingerprintManager = Utils.getFingerprintManagerOrNull(activity);
mFaceManager = Utils.getFaceManagerOrNull(activity); mFaceManager = Utils.getFaceManagerOrNull(activity);
mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(activity);
mLockPatternUtils = new LockPatternUtils(activity); mLockPatternUtils = new LockPatternUtils(activity);
mIsSetNewPassword = ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(chooseLockAction) mIsSetNewPassword = ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(chooseLockAction)
|| ACTION_SET_NEW_PASSWORD.equals(chooseLockAction); || ACTION_SET_NEW_PASSWORD.equals(chooseLockAction);
@@ -274,15 +272,17 @@ public class ChooseLockGeneric extends SettingsActivity {
mUserId), false); mUserId), false);
} }
} else if (!mWaitingForConfirmation) { } else if (!mWaitingForConfirmation) {
ChooseLockSettingsHelper helper = final ChooseLockSettingsHelper.Builder builder =
new ChooseLockSettingsHelper(activity, this); new ChooseLockSettingsHelper.Builder(activity, this);
builder.setRequestCode(CONFIRM_EXISTING_REQUEST)
.setTitle(getString(R.string.unlock_set_unlock_launch_picker_title))
.setReturnCredentials(true)
.setUserId(mUserId);
boolean managedProfileWithUnifiedLock = boolean managedProfileWithUnifiedLock =
UserManager.get(activity).isManagedProfile(mUserId) UserManager.get(activity).isManagedProfile(mUserId)
&& !mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId); && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId);
boolean skipConfirmation = managedProfileWithUnifiedLock && !mIsSetNewPassword; boolean skipConfirmation = managedProfileWithUnifiedLock && !mIsSetNewPassword;
if (skipConfirmation if (skipConfirmation || !builder.show()) {
|| !helper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST,
getString(R.string.unlock_set_unlock_launch_picker_title), true, mUserId)) {
mPasswordConfirmed = true; // no password set, so no need to confirm mPasswordConfirmed = true; // no password set, so no need to confirm
updatePreferencesOrFinish(savedInstanceState != null); updatePreferencesOrFinish(savedInstanceState != null);
} else { } else {
@@ -797,10 +797,10 @@ public class ChooseLockGeneric extends SettingsActivity {
if (mUserPassword != null) { if (mUserPassword != null) {
// No need to call setLockCredential if the user currently doesn't // No need to call setLockCredential if the user currently doesn't
// have a password // have a password
mChooseLockSettingsHelper.utils().setLockCredential( mLockPatternUtils.setLockCredential(
LockscreenCredential.createNone(), mUserPassword, mUserId); LockscreenCredential.createNone(), mUserPassword, mUserId);
} }
mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId); mLockPatternUtils.setLockScreenDisabled(disabled, mUserId);
getActivity().setResult(Activity.RESULT_OK); getActivity().setResult(Activity.RESULT_OK);
finish(); finish();
} }

View File

@@ -228,7 +228,6 @@ public class ChooseLockPassword extends SettingsActivity {
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private SaveAndFinishWorker mSaveAndFinishWorker; private SaveAndFinishWorker mSaveAndFinishWorker;
private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
protected Stage mUiStage = Stage.Introduction; protected Stage mUiStage = Stage.Introduction;
private PasswordRequirementAdapter mPasswordRequirementAdapter; private PasswordRequirementAdapter mPasswordRequirementAdapter;
private GlifLayout mLayout; private GlifLayout mLayout;
@@ -396,8 +395,6 @@ public class ChooseLockPassword extends SettingsActivity {
mLockPatternUtils.getRequestedPasswordMetrics(mUnificationProfileId)); mLockPatternUtils.getRequestedPasswordMetrics(mUnificationProfileId));
} }
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
if (intent.getBooleanExtra( if (intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) { ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {
SaveAndFinishWorker w = new SaveAndFinishWorker(); SaveAndFinishWorker w = new SaveAndFinishWorker();
@@ -406,10 +403,11 @@ public class ChooseLockPassword extends SettingsActivity {
LockscreenCredential currentCredential = intent.getParcelableExtra( LockscreenCredential currentCredential = intent.getParcelableExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
final LockPatternUtils utils = new LockPatternUtils(getActivity());
w.setBlocking(true); w.setBlocking(true);
w.setListener(this); w.setListener(this);
w.start(mChooseLockSettingsHelper.utils(), required, false, 0, w.start(utils, required, false, 0, currentCredential, currentCredential, mUserId);
currentCredential, currentCredential, mUserId);
} }
mTextChangedHandler = new TextChangedHandler(); mTextChangedHandler = new TextChangedHandler();
} }
@@ -499,9 +497,13 @@ public class ChooseLockPassword extends SettingsActivity {
if (savedInstanceState == null) { if (savedInstanceState == null) {
updateStage(Stage.Introduction); updateStage(Stage.Introduction);
if (confirmCredentials) { if (confirmCredentials) {
mChooseLockSettingsHelper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST, final ChooseLockSettingsHelper.Builder builder =
getString(R.string.unlock_set_unlock_launch_picker_title), true, new ChooseLockSettingsHelper.Builder(getActivity());
mUserId); builder.setRequestCode(CONFIRM_EXISTING_REQUEST)
.setTitle(getString(R.string.unlock_set_unlock_launch_picker_title))
.setReturnCredentials(true)
.setUserId(mUserId)
.show();
} }
} else { } else {

View File

@@ -452,7 +452,7 @@ public class ChooseLockPattern extends SettingsActivity {
} }
}; };
private ChooseLockSettingsHelper mChooseLockSettingsHelper; private LockPatternUtils mLockPatternUtils;
private SaveAndFinishWorker mSaveAndFinishWorker; private SaveAndFinishWorker mSaveAndFinishWorker;
protected int mUserId; protected int mUserId;
protected boolean mForFingerprint; protected boolean mForFingerprint;
@@ -465,7 +465,6 @@ public class ChooseLockPattern extends SettingsActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
if (!(getActivity() instanceof ChooseLockPattern)) { if (!(getActivity() instanceof ChooseLockPattern)) {
throw new SecurityException("Fragment contained in wrong activity"); throw new SecurityException("Fragment contained in wrong activity");
} }
@@ -473,6 +472,8 @@ public class ChooseLockPattern extends SettingsActivity {
// Only take this argument into account if it belongs to the current profile. // Only take this argument into account if it belongs to the current profile.
mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras()); mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras());
mLockPatternUtils = new LockPatternUtils(getActivity());
if (intent.getBooleanExtra( if (intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) { ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {
SaveAndFinishWorker w = new SaveAndFinishWorker(); SaveAndFinishWorker w = new SaveAndFinishWorker();
@@ -482,8 +483,7 @@ public class ChooseLockPattern extends SettingsActivity {
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
w.setBlocking(true); w.setBlocking(true);
w.setListener(this); w.setListener(this);
w.start(mChooseLockSettingsHelper.utils(), required, w.start(mLockPatternUtils, required, false, 0, current, current, mUserId);
false, 0, current, current, mUserId);
} }
mForFingerprint = intent.getBooleanExtra( mForFingerprint = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
@@ -543,7 +543,7 @@ public class ChooseLockPattern extends SettingsActivity {
mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern); mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener); mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
mLockPatternView.setTactileFeedbackEnabled( mLockPatternView.setTactileFeedbackEnabled(
mChooseLockSettingsHelper.utils().isTactileFeedbackEnabled()); mLockPatternUtils.isTactileFeedbackEnabled());
mLockPatternView.setFadePattern(false); mLockPatternView.setFadePattern(false);
mFooterText = (TextView) view.findViewById(R.id.footerText); mFooterText = (TextView) view.findViewById(R.id.footerText);
@@ -572,12 +572,16 @@ public class ChooseLockPattern extends SettingsActivity {
// first launch. As a security measure, we're in NeedToConfirm mode until we // first launch. As a security measure, we're in NeedToConfirm mode until we
// know there isn't an existing password or the user confirms their password. // know there isn't an existing password or the user confirms their password.
updateStage(Stage.NeedToConfirm); updateStage(Stage.NeedToConfirm);
boolean launchedConfirmationActivity =
mChooseLockSettingsHelper.launchConfirmationActivity( final ChooseLockSettingsHelper.Builder builder =
CONFIRM_EXISTING_REQUEST, new ChooseLockSettingsHelper.Builder(getActivity());
getString(R.string.unlock_set_unlock_launch_picker_title), true, final boolean launched = builder.setRequestCode(CONFIRM_EXISTING_REQUEST)
mUserId); .setTitle(getString(R.string.unlock_set_unlock_launch_picker_title))
if (!launchedConfirmationActivity) { .setReturnCredentials(true)
.setUserId(mUserId)
.show();
if (!launched) {
updateStage(Stage.Introduction); updateStage(Stage.Introduction);
} }
} else { } else {
@@ -853,7 +857,7 @@ public class ChooseLockPattern extends SettingsActivity {
profileCredential); profileCredential);
} }
} }
mSaveAndFinishWorker.start(mChooseLockSettingsHelper.utils(), required, mSaveAndFinishWorker.start(mLockPatternUtils, required,
mHasChallenge, mChallenge, mChosenPattern, mCurrentCredential, mUserId); mHasChallenge, mChallenge, mChosenPattern, mCurrentCredential, mUserId);
} }

View File

@@ -18,14 +18,15 @@ package com.android.settings.password;
import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME; import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.Activity; import android.app.Activity;
import android.app.KeyguardManager; import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.content.Intent; import android.content.Intent;
import android.content.IntentSender; import android.content.IntentSender;
import android.os.Bundle;
import android.os.UserManager; import android.os.UserManager;
import android.util.Log;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@@ -39,6 +40,8 @@ import com.google.android.setupcompat.util.WizardManagerHelper;
public final class ChooseLockSettingsHelper { public final class ChooseLockSettingsHelper {
private static final String TAG = "ChooseLockSettingsHelper";
public static final String EXTRA_KEY_TYPE = "type"; public static final String EXTRA_KEY_TYPE = "type";
public static final String EXTRA_KEY_PASSWORD = "password"; public static final String EXTRA_KEY_PASSWORD = "password";
public static final String EXTRA_KEY_RETURN_CREDENTIALS = "return_credentials"; public static final String EXTRA_KEY_RETURN_CREDENTIALS = "return_credentials";
@@ -84,319 +87,192 @@ public final class ChooseLockSettingsHelper {
* controls if we relax the enforcement of * controls if we relax the enforcement of
* {@link Utils#enforceSameOwner(android.content.Context, int)}. * {@link Utils#enforceSameOwner(android.content.Context, int)}.
*/ */
public static final String EXTRA_ALLOW_ANY_USER = "allow_any_user"; public static final String EXTRA_KEY_ALLOW_ANY_USER = "allow_any_user";
@VisibleForTesting LockPatternUtils mLockPatternUtils; @VisibleForTesting @NonNull LockPatternUtils mLockPatternUtils;
private Activity mActivity; @NonNull private final Activity mActivity;
private Fragment mFragment; @Nullable private final Fragment mFragment;
@NonNull private final Builder mBuilder;
public ChooseLockSettingsHelper(Activity activity) { private ChooseLockSettingsHelper(@NonNull Builder builder, @NonNull Activity activity,
@Nullable Fragment fragment) {
mBuilder = builder;
mActivity = activity; mActivity = activity;
mFragment = fragment;
mLockPatternUtils = new LockPatternUtils(activity); mLockPatternUtils = new LockPatternUtils(activity);
} }
public ChooseLockSettingsHelper(Activity activity, Fragment fragment) { public static class Builder {
this(activity); @NonNull private final Activity mActivity;
mFragment = fragment; @Nullable private Fragment mFragment;
}
public LockPatternUtils utils() { private int mRequestCode;
return mLockPatternUtils; @Nullable private CharSequence mTitle;
@Nullable private CharSequence mHeader;
@Nullable private CharSequence mDescription;
@Nullable private CharSequence mAlternateButton;
private boolean mReturnCredentials;
private boolean mExternal;
private boolean mForegroundOnly;
// ChooseLockSettingsHelper will determine the caller's userId if none provided.
private int mUserId;
private boolean mAllowAnyUserId;
// The challenge can be 0, which is different than "no challenge"
@Nullable Long mChallenge;
public Builder(@NonNull Activity activity) {
mActivity = activity;
mUserId = Utils.getCredentialOwnerUserId(mActivity);
}
public Builder(@NonNull Activity activity, @NonNull Fragment fragment) {
this(activity);
mFragment = fragment;
}
/**
* @param requestCode for onActivityResult
*/
@NonNull public Builder setRequestCode(int requestCode) {
mRequestCode = requestCode;
return this;
}
/**
* @param title of the confirmation screen; shown in the action bar
*/
@NonNull public Builder setTitle(@Nullable CharSequence title) {
mTitle = title;
return this;
}
/**
* @param header of the confirmation screen; shown as large text
*/
@NonNull public Builder setHeader(@Nullable CharSequence header) {
mHeader = header;
return this;
}
/**
* @param description of the confirmation screen
*/
@NonNull public Builder setDescription(@Nullable CharSequence description) {
mDescription = description;
return this;
}
/**
* @param alternateButton text for an alternate button
*/
@NonNull public Builder setAlternateButton(@Nullable CharSequence alternateButton) {
mAlternateButton = alternateButton;
return this;
}
/**
* @param returnCredentials if true, puts the following credentials into intent for
* onActivityResult with the following keys:
* {@link #EXTRA_KEY_TYPE}, {@link #EXTRA_KEY_PASSWORD},
* {@link #EXTRA_KEY_CHALLENGE_TOKEN}.
* Note that if this is true, this can only be called internally.
*/
@NonNull public Builder setReturnCredentials(boolean returnCredentials) {
mReturnCredentials = returnCredentials;
return this;
}
/**
* @param userId for whom the credential should be confirmed.
*/
@NonNull public Builder setUserId(int userId) {
mUserId = userId;
return this;
}
/**
* @param allowAnyUserId Allows the caller to prompt for credentials of any user, including
* those which aren't associated with the current user. As an example,
* this is useful when unlocking the storage for secondary users.
*/
@NonNull public Builder setAllowAnyUserId(boolean allowAnyUserId) {
mAllowAnyUserId = allowAnyUserId;
return this;
}
/**
* @param external specifies whether this activity is launched externally, meaning that it
* will get a dark theme, allow biometric authentication, and it will
* forward the activity result.
*/
@NonNull public Builder setExternal(boolean external) {
mExternal = external;
return this;
}
/**
* @param foregroundOnly if true, the confirmation activity will be finished if it loses
* foreground.
*/
@NonNull public Builder setForegroundOnly(boolean foregroundOnly) {
mForegroundOnly = foregroundOnly;
return this;
}
/**
* @param challenge an opaque payload that will be wrapped in the Gatekeeper's payload
* if authentication is successful. Common use case is for the caller's
* secure layer (e.g. Trusted Execution Environment) to 1) verify that
* the Gatekeeper HAT's HMAC is valid, and 2) if so, perform an operation
* based on the challenge.
*/
@NonNull public Builder setChallenge(long challenge) {
mChallenge = challenge;
return this;
}
@NonNull public ChooseLockSettingsHelper build() {
if (!mAllowAnyUserId && mUserId != LockPatternUtils.USER_FRP) {
Utils.enforceSameOwner(mActivity, mUserId);
}
if (mExternal && mReturnCredentials) {
throw new IllegalArgumentException("External and ReturnCredentials specified. "
+ " External callers should never be allowed to receive credentials in"
+ " onActivityResult");
}
if (mChallenge != null && !mReturnCredentials) {
// HAT containing the signed challenge will not be available to the caller.
Log.w(TAG, "Challenge set but not requesting ReturnCredentials. Are you sure this"
+ " is what you want?");
}
return new ChooseLockSettingsHelper(this, mActivity, mFragment);
}
public boolean show() {
return build().launch();
}
} }
/** /**
* If a pattern, password or PIN exists, prompt the user before allowing them to change it. * If a PIN, Pattern, or Password exists, prompt the user to confirm it.
* * @return true if the confirmation activity is shown (e.g. user has a credential set up)
* @param title title of the confirmation screen; shown in the action bar
* @return true if one exists and we launched an activity to confirm it
* @see Activity#onActivityResult(int, int, android.content.Intent)
*/ */
public boolean launchConfirmationActivity(int request, CharSequence title) { public boolean launch() {
return launchConfirmationActivity( final long challenge = mBuilder.mChallenge != null ? mBuilder.mChallenge : 0L;
request /* request */, return launchConfirmationActivity(mBuilder.mRequestCode, mBuilder.mTitle, mBuilder.mHeader,
title /* title */, mBuilder.mDescription, mBuilder.mReturnCredentials, mBuilder.mExternal,
null /* header */, mBuilder.mChallenge != null, challenge, mBuilder.mUserId,
null /* description */, mBuilder.mAlternateButton, mBuilder.mAllowAnyUserId, mBuilder.mForegroundOnly);
false /* returnCredentials */,
false /* external */,
false /* foregroundOnly */);
}
/**
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
*
* @param title title of the confirmation screen; shown in the action bar
* @param returnCredentials if true, put credentials into intent. Note that if this is true,
* this can only be called internally.
* @return true if one exists and we launched an activity to confirm it
* @see Activity#onActivityResult(int, int, android.content.Intent)
*/
public boolean launchConfirmationActivity(int request, CharSequence title, boolean returnCredentials) {
return launchConfirmationActivity(
request /* request */,
title /* title */,
null /* header */,
null /* description */,
returnCredentials /* returnCredentials */,
false /* external */,
false /* foregroundOnly */);
}
/**
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
*
* @param title title of the confirmation screen; shown in the action bar
* @param returnCredentials if true, put credentials into intent. Note that if this is true,
* this can only be called internally.
* @param userId The userId for whom the lock should be confirmed.
* @return true if one exists and we launched an activity to confirm it
* @see Activity#onActivityResult(int, int, android.content.Intent)
*/
public boolean launchConfirmationActivity(int request, CharSequence title,
boolean returnCredentials, int userId) {
return launchConfirmationActivity(
request /* request */,
title /* title */,
null /* header */,
null /* description */,
returnCredentials /* returnCredentials */,
false /* external */,
false /* hasChallenge */,
0 /* challenge */,
Utils.enforceSameOwner(mActivity, userId) /* userId */,
false /* foregroundOnly */);
}
/**
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
*
* @param title title of the confirmation screen; shown in the action bar
* @param header header of the confirmation screen; shown as large text
* @param description description of the confirmation screen
* @param returnCredentials if true, put credentials into intent. Note that if this is true,
* this can only be called internally.
* @param external specifies whether this activity is launched externally, meaning that it will
* get a dark theme, allow fingerprint authentication and it will forward
* activity result.
* @param foregroundOnly if the confirmation activity should be finished if it loses foreground.
* @return true if one exists and we launched an activity to confirm it
* @see Activity#onActivityResult(int, int, android.content.Intent)
*/
boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@Nullable CharSequence header, @Nullable CharSequence description,
boolean returnCredentials, boolean external, boolean foregroundOnly) {
return launchConfirmationActivity(
request /* request */,
title /* title */,
header /* header */,
description /* description */,
returnCredentials /* returnCredentials */,
external /* external */,
false /* hasChallenge */,
0 /* challenge */,
Utils.getCredentialOwnerUserId(mActivity) /* userId */,
foregroundOnly /* foregroundOnly */);
}
/**
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
*
* @param title title of the confirmation screen; shown in the action bar
* @param header header of the confirmation screen; shown as large text
* @param description description of the confirmation screen
* @param returnCredentials if true, put credentials into intent. Note that if this is true,
* this can only be called internally.
* @param external specifies whether this activity is launched externally, meaning that it will
* get a dark theme, allow fingerprint authentication and it will forward
* activity result.
* @param userId The userId for whom the lock should be confirmed.
* @return true if one exists and we launched an activity to confirm it
* @see Activity#onActivityResult(int, int, android.content.Intent)
*/
boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@Nullable CharSequence header, @Nullable CharSequence description,
boolean returnCredentials, boolean external, int userId) {
return launchConfirmationActivity(
request /* request */,
title /* title */,
header /* header */,
description /* description */,
returnCredentials /* returnCredentials */,
external /* external */,
false /* hasChallenge */,
0 /* challenge */,
Utils.enforceSameOwner(mActivity, userId) /* userId */,
false /* foregroundOnly */);
}
/**
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
*
* @param title title of the confirmation screen; shown in the action bar
* @param header header of the confirmation screen; shown as large text
* @param description description of the confirmation screen
* @param challenge a challenge to be verified against the device credential.
* @param foregroundOnly if the confirmation activity should be finished if it loses foreground.
* @return true if one exists and we launched an activity to confirm it
* @see Activity#onActivityResult(int, int, android.content.Intent)
*/
public boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@Nullable CharSequence header, @Nullable CharSequence description,
long challenge, boolean foregroundOnly) {
return launchConfirmationActivity(
request /* request */,
title /* title */,
header /* header */,
description /* description */,
true /* returnCredentials */,
false /* external */,
true /* hasChallenge */,
challenge /* challenge */,
Utils.getCredentialOwnerUserId(mActivity) /* userId */,
foregroundOnly /* foregroundOnly */);
}
/**
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
*
* @param title title of the confirmation screen; shown in the action bar
* @param header header of the confirmation screen; shown as large text
* @param description description of the confirmation screen
* @param challenge a challenge to be verified against the device credential.
* @param userId The userId for whom the lock should be confirmed.
* @param foregroundOnly if the confirmation activity should be finished if it loses foreground.
* @return true if one exists and we launched an activity to confirm it
* @see Activity#onActivityResult(int, int, android.content.Intent)
*/
public boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@Nullable CharSequence header, @Nullable CharSequence description,
long challenge, int userId, boolean foregroundOnly) {
return launchConfirmationActivity(
request /* request */,
title /* title */,
header /* header */,
description /* description */,
true /* returnCredentials */,
false /* external */,
true /* hasChallenge */,
challenge /* challenge */,
Utils.enforceSameOwner(mActivity, userId) /* userId */,
foregroundOnly);
}
/**
* If a pattern, password or PIN exists, prompt the user before allowing them to change it.
*
* @param title title of the confirmation screen; shown in the action bar
* @param header header of the confirmation screen; shown as large text
* @param description description of the confirmation screen
* @param external specifies whether this activity is launched externally, meaning that it will
* get a dark theme, allow fingerprint authentication and it will forward
* activity result.
* @param challenge a challenge to be verified against the device credential.
* @param userId The userId for whom the lock should be confirmed.
* @return true if one exists and we launched an activity to confirm it
* @see Activity#onActivityResult(int, int, android.content.Intent)
*/
public boolean launchConfirmationActivityWithExternalAndChallenge(int request,
@Nullable CharSequence title, @Nullable CharSequence header,
@Nullable CharSequence description, boolean external, long challenge, int userId) {
return launchConfirmationActivity(
request /* request */,
title /* title */,
header /* header */,
description /* description */,
false /* returnCredentials */,
external /* external */,
true /* hasChallenge */,
challenge /* challenge */,
Utils.enforceSameOwner(mActivity, userId) /* userId */,
false /* foregroundOnly */);
}
/**
* Variant that allows you to prompt for credentials of any user, including
* those which aren't associated with the current user. As an example, this
* is useful when unlocking the storage for secondary users.
*/
public boolean launchConfirmationActivityForAnyUser(int request,
@Nullable CharSequence title, @Nullable CharSequence header,
@Nullable CharSequence description, int userId) {
final Bundle extras = new Bundle();
extras.putBoolean(EXTRA_ALLOW_ANY_USER, true);
return launchConfirmationActivity(
request /* request */,
title /* title */,
header /* header */,
description /* description */,
false /* returnCredentials */,
false /* external */,
true /* hasChallenge */,
0 /* challenge */,
userId /* userId */,
extras /* extras */);
} }
private boolean launchConfirmationActivity(int request, @Nullable CharSequence title, private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@Nullable CharSequence header, @Nullable CharSequence description, @Nullable CharSequence header, @Nullable CharSequence description,
boolean returnCredentials, boolean external, boolean hasChallenge, boolean returnCredentials, boolean external, boolean hasChallenge,
long challenge, int userId, boolean foregroundOnly) { long challenge, int userId, @Nullable CharSequence alternateButton,
return launchConfirmationActivity( boolean allowAnyUser, boolean foregroundOnly) {
request /* request */,
title /* title */,
header /* header */,
description /* description */,
returnCredentials /* returnCredentials */,
external /* external */,
hasChallenge /* hasChallenge */,
challenge /* challenge */,
userId /* userId */,
null /* alternateButton */,
null /* extras */,
foregroundOnly /* foregroundOnly */);
}
private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@Nullable CharSequence header, @Nullable CharSequence description,
boolean returnCredentials, boolean external, boolean hasChallenge,
long challenge, int userId, Bundle extras) {
return launchConfirmationActivity(
request /* request */,
title /* title */,
header /* header */,
description /* description */,
returnCredentials /* returnCredentials */,
external /* external */,
hasChallenge /* hasChallenge */,
challenge /* challenge */,
userId /* userId */,
null /* alternateButton */,
extras /* extras */,
false /* foregroundOnly */);
}
public boolean launchFrpConfirmationActivity(int request, @Nullable CharSequence header,
@Nullable CharSequence description, @Nullable CharSequence alternateButton) {
return launchConfirmationActivity(
request /* request */,
null /* title */,
header /* header */,
description /* description */,
false /* returnCredentials */,
true /* external */,
false /* hasChallenge */,
0 /* challenge */,
LockPatternUtils.USER_FRP /* userId */,
alternateButton /* alternateButton */,
null /* extras */,
false /* foregroundOnly */);
}
private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@Nullable CharSequence header, @Nullable CharSequence description,
boolean returnCredentials, boolean external, boolean hasChallenge,
long challenge, int userId, @Nullable CharSequence alternateButton, Bundle extras,
boolean foregroundOnly) {
final int effectiveUserId = UserManager.get(mActivity).getCredentialOwnerProfile(userId); final int effectiveUserId = UserManager.get(mActivity).getCredentialOwnerProfile(userId);
boolean launched = false; boolean launched = false;
@@ -406,7 +282,7 @@ public final class ChooseLockSettingsHelper {
returnCredentials || hasChallenge returnCredentials || hasChallenge
? ConfirmLockPattern.InternalActivity.class ? ConfirmLockPattern.InternalActivity.class
: ConfirmLockPattern.class, returnCredentials, external, : ConfirmLockPattern.class, returnCredentials, external,
hasChallenge, challenge, userId, alternateButton, extras, hasChallenge, challenge, userId, alternateButton, allowAnyUser,
foregroundOnly); foregroundOnly);
break; break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
@@ -419,7 +295,7 @@ public final class ChooseLockSettingsHelper {
returnCredentials || hasChallenge returnCredentials || hasChallenge
? ConfirmLockPassword.InternalActivity.class ? ConfirmLockPassword.InternalActivity.class
: ConfirmLockPassword.class, returnCredentials, external, : ConfirmLockPassword.class, returnCredentials, external,
hasChallenge, challenge, userId, alternateButton, extras, hasChallenge, challenge, userId, alternateButton, allowAnyUser,
foregroundOnly); foregroundOnly);
break; break;
} }
@@ -429,7 +305,7 @@ public final class ChooseLockSettingsHelper {
private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header, private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header,
CharSequence message, Class<?> activityClass, boolean returnCredentials, CharSequence message, Class<?> activityClass, boolean returnCredentials,
boolean external, boolean hasChallenge, long challenge, boolean external, boolean hasChallenge, long challenge,
int userId, @Nullable CharSequence alternateButton, Bundle extras, int userId, @Nullable CharSequence alternateButton, boolean allowAnyUser,
boolean foregroundOnly) { boolean foregroundOnly) {
final Intent intent = new Intent(); final Intent intent = new Intent();
intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title); intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
@@ -446,9 +322,8 @@ public final class ChooseLockSettingsHelper {
intent.putExtra(Intent.EXTRA_USER_ID, userId); intent.putExtra(Intent.EXTRA_USER_ID, userId);
intent.putExtra(KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL, alternateButton); intent.putExtra(KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL, alternateButton);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOREGROUND_ONLY, foregroundOnly); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOREGROUND_ONLY, foregroundOnly);
if (extras != null) { intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_ALLOW_ANY_USER, allowAnyUser);
intent.putExtras(extras);
}
intent.setClassName(SETTINGS_PACKAGE_NAME, activityClass.getName()); intent.setClassName(SETTINGS_PACKAGE_NAME, activityClass.getName());
if (external) { if (external) {
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);

View File

@@ -98,7 +98,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private UserManager mUserManager; private UserManager mUserManager;
private TrustManager mTrustManager; private TrustManager mTrustManager;
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private Handler mHandler = new Handler(Looper.getMainLooper()); private Handler mHandler = new Handler(Looper.getMainLooper());
private Context mContext; private Context mContext;
private boolean mCheckDevicePolicyManager; private boolean mCheckDevicePolicyManager;
@@ -214,8 +213,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
mTitle = getTitleFromOrganizationName(mUserId); mTitle = getTitleFromOrganizationName(mUserId);
} }
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
final LockPatternUtils lockPatternUtils = new LockPatternUtils(this); final LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
final PromptInfo promptInfo = new PromptInfo(); final PromptInfo promptInfo = new PromptInfo();
@@ -240,8 +237,14 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
// tied profile so it will enable work mode and unlock managed profile, when personal // tied profile so it will enable work mode and unlock managed profile, when personal
// challenge is unlocked. // challenge is unlocked.
if (frp) { if (frp) {
launchedCDC = mChooseLockSettingsHelper.launchFrpConfirmationActivity( final ChooseLockSettingsHelper.Builder builder =
0, mTitle, mDetails, alternateButton); new ChooseLockSettingsHelper.Builder(this);
launchedCDC = builder.setHeader(mTitle) // Show the title in the header location
.setDescription(mDetails)
.setAlternateButton(alternateButton)
.setExternal(true)
.setUserId(LockPatternUtils.USER_FRP)
.show();
} else if (isManagedProfile && isInternalActivity() } else if (isManagedProfile && isInternalActivity()
&& !lockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) { && !lockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
mCredentialMode = CREDENTIAL_MANAGED; mCredentialMode = CREDENTIAL_MANAGED;
@@ -385,15 +388,22 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
// LockPatternChecker and LockPatternUtils. verifyPassword should be the only API to use, // LockPatternChecker and LockPatternUtils. verifyPassword should be the only API to use,
// which optionally accepts a challenge. // which optionally accepts a challenge.
if (mCredentialMode == CREDENTIAL_MANAGED) { if (mCredentialMode == CREDENTIAL_MANAGED) {
launched = mChooseLockSettingsHelper final ChooseLockSettingsHelper.Builder builder =
.launchConfirmationActivityWithExternalAndChallenge( new ChooseLockSettingsHelper.Builder(this);
0 /* request code */, null /* title */, mTitle, mDetails, launched = builder.setHeader(mTitle)
true /* isExternal */, 0L /* challenge */, mUserId); .setDescription(mDetails)
.setExternal(true)
.setUserId(mUserId)
.setChallenge(0L)
.show();
} else if (mCredentialMode == CREDENTIAL_NORMAL) { } else if (mCredentialMode == CREDENTIAL_NORMAL) {
launched = mChooseLockSettingsHelper.launchConfirmationActivity( final ChooseLockSettingsHelper.Builder builder =
0 /* request code */, null /* title */, new ChooseLockSettingsHelper.Builder(this);
mTitle, mDetails, false /* returnCredentials */, true /* isExternal */, launched = builder.setHeader(mTitle) // Show the title string in the header area
mUserId); .setDescription(mDetails)
.setExternal(true)
.setUserId(mUserId)
.show();
} }
if (!launched) { if (!launched) {
Log.d(TAG, "No pin/pattern/pass set"); Log.d(TAG, "No pin/pattern/pass set");

View File

@@ -357,9 +357,11 @@ public final class CredentialStorage extends FragmentActivity {
*/ */
private boolean confirmKeyGuard(int requestCode) { private boolean confirmKeyGuard(int requestCode) {
final Resources res = getResources(); final Resources res = getResources();
return new ChooseLockSettingsHelper(this) final ChooseLockSettingsHelper.Builder builder =
.launchConfirmationActivity(requestCode, new ChooseLockSettingsHelper.Builder(this);
res.getText(R.string.credentials_title), true); return builder.setRequestCode(requestCode)
.setTitle(res.getText(R.string.credentials_title))
.show();
} }
@Override @Override

View File

@@ -37,6 +37,7 @@ import android.widget.Button;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference; import androidx.preference.Preference;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.LockscreenCredential;
import com.android.settings.CryptKeeperConfirm; import com.android.settings.CryptKeeperConfirm;
import com.android.settings.R; import com.android.settings.R;
@@ -169,17 +170,20 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
* @return true if confirmation launched * @return true if confirmation launched
*/ */
private boolean runKeyguardConfirmation(int request) { private boolean runKeyguardConfirmation(int request) {
Resources res = getActivity().getResources(); final LockPatternUtils utils = new LockPatternUtils(getActivity());
ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this); if (utils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())
if (helper.utils().getKeyguardStoredPasswordQuality(UserHandle.myUserId())
== DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, "".getBytes()); showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, "".getBytes());
return true; return true;
} }
return helper.launchConfirmationActivity(request, final Resources res = getActivity().getResources();
res.getText(R.string.crypt_keeper_encrypt_title), true); final ChooseLockSettingsHelper.Builder builder =
new ChooseLockSettingsHelper.Builder(getActivity(), this);
return builder.setRequestCode(request)
.setTitle(res.getText(R.string.crypt_keeper_encrypt_title))
.setReturnCredentials(true)
.show();
} }
@Override @Override

View File

@@ -118,11 +118,15 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
startUnification(); startUnification();
} else { } else {
final String title = mContext.getString(R.string.unlock_set_unlock_launch_picker_title); final String title = mContext.getString(R.string.unlock_set_unlock_launch_picker_title);
final ChooseLockSettingsHelper helper = final ChooseLockSettingsHelper.Builder builder =
new ChooseLockSettingsHelper(mHost.getActivity(), mHost); new ChooseLockSettingsHelper.Builder(mHost.getActivity(), mHost);
if (!helper.launchConfirmationActivity( final boolean launched = builder.setRequestCode(UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST)
UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST, .setTitle(title)
title, true /* returnCredentials */, MY_USER_ID)) { .setReturnCredentials(true)
.setUserId(MY_USER_ID)
.show();
if (!launched) {
ununifyLocks(); ununifyLocks();
} }
} }
@@ -176,10 +180,14 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
// Confirm profile lock // Confirm profile lock
final String title = mContext.getString( final String title = mContext.getString(
R.string.unlock_set_unlock_launch_picker_title_profile); R.string.unlock_set_unlock_launch_picker_title_profile);
final ChooseLockSettingsHelper helper = final ChooseLockSettingsHelper.Builder builder =
new ChooseLockSettingsHelper(mHost.getActivity(), mHost); new ChooseLockSettingsHelper.Builder(mHost.getActivity(), mHost);
if (!helper.launchConfirmationActivity( final boolean launched = builder.setRequestCode(UNIFY_LOCK_CONFIRM_PROFILE_REQUEST)
UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileUserId)) { .setTitle(title)
.setReturnCredentials(true)
.setUserId(mProfileUserId)
.show();
if (!launched) {
// If profile has no lock, go straight to unification. // If profile has no lock, go straight to unification.
unifyLocks(); unifyLocks();
// TODO: update relevant prefs. // TODO: update relevant prefs.

View File

@@ -120,11 +120,14 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro
if (!mTrustAgentsKeyList.contains(preference.getKey())) { if (!mTrustAgentsKeyList.contains(preference.getKey())) {
return super.handlePreferenceTreeClick(preference); return super.handlePreferenceTreeClick(preference);
} }
final ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(
mHost.getActivity(), mHost); final ChooseLockSettingsHelper.Builder builder =
new ChooseLockSettingsHelper.Builder(mHost.getActivity(), mHost);
final boolean confirmationLaunched = builder.setRequestCode(CHANGE_TRUST_AGENT_SETTINGS)
.setTitle(preference.getTitle())
.show();
mTrustAgentClickIntent = preference.getIntent(); mTrustAgentClickIntent = preference.getIntent();
boolean confirmationLaunched = helper.launchConfirmationActivity(
CHANGE_TRUST_AGENT_SETTINGS, preference.getTitle());
if (!confirmationLaunched && mTrustAgentClickIntent != null) { if (!confirmationLaunched && mTrustAgentClickIntent != null) {
// If this returns false, it means no password confirmation is required. // If this returns false, it means no password confirmation is required.

View File

@@ -38,16 +38,17 @@ public class ChooseLockSettingsHelperTest {
@Test @Test
public void testLaunchConfirmationActivityWithExternalAndChallenge() { public void testLaunchConfirmationActivityWithExternalAndChallenge() {
final Activity activity = Robolectric.setupActivity(Activity.class); final Activity activity = Robolectric.setupActivity(Activity.class);
ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(activity);
helper.launchConfirmationActivityWithExternalAndChallenge( ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity);
100, // request builder.setRequestCode(100)
"title", .setTitle("title")
"header", .setHeader("header")
"description", .setDescription("description")
true, // external .setExternal(true)
10000L, .setChallenge(10000L)
UserHandle.myUserId() .setUserId(UserHandle.myUserId());
); ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder);
helper.launch();
ShadowActivity shadowActivity = Shadows.shadowOf(activity); ShadowActivity shadowActivity = Shadows.shadowOf(activity);
Intent startedIntent = shadowActivity.getNextStartedActivity(); Intent startedIntent = shadowActivity.getNextStartedActivity();
@@ -73,16 +74,17 @@ public class ChooseLockSettingsHelperTest {
@Test @Test
public void testLaunchConfirmationActivityInternalAndChallenge() { public void testLaunchConfirmationActivityInternalAndChallenge() {
final Activity activity = Robolectric.setupActivity(Activity.class); final Activity activity = Robolectric.setupActivity(Activity.class);
ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(activity);
helper.launchConfirmationActivityWithExternalAndChallenge( ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity);
100, builder.setRequestCode(100)
"title", .setTitle("title")
"header", .setHeader("header")
"description", .setDescription("description")
false, // external .setChallenge(10000L)
10000L, .setUserId(UserHandle.myUserId());
UserHandle.myUserId() ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder);
); helper.launch();
ShadowActivity shadowActivity = Shadows.shadowOf(activity); ShadowActivity shadowActivity = Shadows.shadowOf(activity);
Intent startedIntent = shadowActivity.getNextStartedActivity(); Intent startedIntent = shadowActivity.getNextStartedActivity();
@@ -109,8 +111,14 @@ public class ChooseLockSettingsHelperTest {
Intent intent = new Intent() Intent intent = new Intent()
.putExtra(WizardManagerHelper.EXTRA_THEME, ThemeHelper.THEME_GLIF_V2); .putExtra(WizardManagerHelper.EXTRA_THEME, ThemeHelper.THEME_GLIF_V2);
Activity activity = Robolectric.buildActivity(Activity.class, intent).get(); Activity activity = Robolectric.buildActivity(Activity.class, intent).get();
ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(activity);
helper.launchConfirmationActivity(123, "test title", true, 0 /* userId */); ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity);
builder.setRequestCode(123)
.setTitle("test title")
.setReturnCredentials(true)
.setUserId(0);
ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder);
helper.launch();
ShadowActivity shadowActivity = Shadows.shadowOf(activity); ShadowActivity shadowActivity = Shadows.shadowOf(activity);
IntentForResult startedActivity = shadowActivity.getNextStartedActivityForResult(); IntentForResult startedActivity = shadowActivity.getNextStartedActivityForResult();
@@ -119,12 +127,13 @@ public class ChooseLockSettingsHelperTest {
.isEqualTo(ThemeHelper.THEME_GLIF_V2); .isEqualTo(ThemeHelper.THEME_GLIF_V2);
} }
private ChooseLockSettingsHelper getChooseLockSettingsHelper(Activity activity) { private ChooseLockSettingsHelper getChooseLockSettingsHelper(
ChooseLockSettingsHelper.Builder builder) {
LockPatternUtils mockLockPatternUtils = mock(LockPatternUtils.class); LockPatternUtils mockLockPatternUtils = mock(LockPatternUtils.class);
when(mockLockPatternUtils.getKeyguardStoredPasswordQuality(anyInt())) when(mockLockPatternUtils.getKeyguardStoredPasswordQuality(anyInt()))
.thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(activity); ChooseLockSettingsHelper helper = builder.build();
helper.mLockPatternUtils = mockLockPatternUtils; helper.mLockPatternUtils = mockLockPatternUtils;
return helper; return helper;
} }