Extract common code to SaveChosenLockWorkerBase

* Extract common code of ChooseLockPassword.SaveAndFinishWorker and
ChooseLockPattern.SaveAndFinishWorker to the parent class.

* Make setters return this to make it easy to chain setter calls.

* Rename SaveChosenLockWorkerBase to SaveAndFinishWorker.

This will make the code changes in the next CL much easier.

Bug: 271968977
Bug: 277561275
Test: 1. Add screen lock (password/PIN/pattern) using Settings
      2. check screen lock works correctly
Change-Id: I98acd25f2dd81ab4608cc6943e4f238070003c17
This commit is contained in:
JW Wang
2023-06-28 14:53:14 +08:00
committed by Chun-Wei Wang
parent 250f2727b0
commit 73dcb47ecb
6 changed files with 79 additions and 132 deletions

View File

@@ -65,7 +65,6 @@ import android.text.Spannable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log; import android.util.Log;
import android.util.Pair;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -87,7 +86,6 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.PasswordValidationError; import com.android.internal.widget.PasswordValidationError;
import com.android.internal.widget.TextViewInputDisabler; import com.android.internal.widget.TextViewInputDisabler;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.SetupWizardUtils; import com.android.settings.SetupWizardUtils;
@@ -1009,7 +1007,9 @@ public class ChooseLockPassword extends SettingsActivity {
setNextEnabled(false); setNextEnabled(false);
mSaveAndFinishWorker = new SaveAndFinishWorker(); mSaveAndFinishWorker = new SaveAndFinishWorker();
mSaveAndFinishWorker.setListener(this); mSaveAndFinishWorker
.setListener(this)
.setRequestGatekeeperPasswordHandle(mRequestGatekeeperPassword);
getFragmentManager().beginTransaction().add(mSaveAndFinishWorker, getFragmentManager().beginTransaction().add(mSaveAndFinishWorker,
FRAGMENT_TAG_SAVE_AND_FINISH).commit(); FRAGMENT_TAG_SAVE_AND_FINISH).commit();
@@ -1029,7 +1029,7 @@ public class ChooseLockPassword extends SettingsActivity {
(mAutoPinConfirmOption != null && mAutoPinConfirmOption.isChecked()), (mAutoPinConfirmOption != null && mAutoPinConfirmOption.isChecked()),
mUserId); mUserId);
mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword, mSaveAndFinishWorker.start(mLockPatternUtils,
mChosenPassword, mCurrentCredential, mUserId); mChosenPassword, mCurrentCredential, mUserId);
} }
@@ -1082,50 +1082,4 @@ public class ChooseLockPassword extends SettingsActivity {
} }
} }
} }
public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
private LockscreenCredential mChosenPassword;
private LockscreenCredential mCurrentCredential;
public void start(LockPatternUtils utils, boolean requestGatekeeperPassword,
LockscreenCredential chosenPassword, LockscreenCredential currentCredential,
int userId) {
prepare(utils, requestGatekeeperPassword, userId);
mChosenPassword = chosenPassword;
mCurrentCredential = currentCredential != null ? currentCredential
: LockscreenCredential.createNone();
mUserId = userId;
start();
}
@Override
protected Pair<Boolean, Intent> saveAndVerifyInBackground() {
final boolean success = mUtils.setLockCredential(
mChosenPassword, mCurrentCredential, mUserId);
if (success) {
unifyProfileCredentialIfRequested();
}
Intent result = null;
if (success && mRequestGatekeeperPassword) {
// If a Gatekeeper Password was requested, invoke the LockSettingsService code
// path to return a Gatekeeper Password based on the credential that the user
// chose. This should only be run if the credential was successfully set.
final VerifyCredentialResponse response = mUtils.verifyCredential(mChosenPassword,
mUserId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE);
if (!response.isMatched() || !response.containsGatekeeperPasswordHandle()) {
Log.e(TAG, "critical: bad response or missing GK PW handle for known good"
+ " password: " + response.toString());
}
result = new Intent();
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE,
response.getGatekeeperPasswordHandle());
}
return Pair.create(success, result);
}
}
} }

View File

@@ -34,7 +34,6 @@ import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.util.Log; import android.util.Log;
import android.util.Pair;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -53,7 +52,6 @@ import com.android.internal.widget.LockPatternView;
import com.android.internal.widget.LockPatternView.Cell; import com.android.internal.widget.LockPatternView.Cell;
import com.android.internal.widget.LockPatternView.DisplayMode; import com.android.internal.widget.LockPatternView.DisplayMode;
import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.SetupWizardUtils; import com.android.settings.SetupWizardUtils;
@@ -827,7 +825,9 @@ public class ChooseLockPattern extends SettingsActivity {
setRightButtonEnabled(false); setRightButtonEnabled(false);
mSaveAndFinishWorker = new SaveAndFinishWorker(); mSaveAndFinishWorker = new SaveAndFinishWorker();
mSaveAndFinishWorker.setListener(this); mSaveAndFinishWorker
.setListener(this)
.setRequestGatekeeperPasswordHandle(mRequestGatekeeperPassword);
getFragmentManager().beginTransaction().add(mSaveAndFinishWorker, getFragmentManager().beginTransaction().add(mSaveAndFinishWorker,
FRAGMENT_TAG_SAVE_AND_FINISH).commit(); FRAGMENT_TAG_SAVE_AND_FINISH).commit();
@@ -843,7 +843,7 @@ public class ChooseLockPattern extends SettingsActivity {
profileCredential); profileCredential);
} }
} }
mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword, mSaveAndFinishWorker.start(mLockPatternUtils,
mChosenPattern, mCurrentCredential, mUserId); mChosenPattern, mCurrentCredential, mUserId);
} }
@@ -867,51 +867,4 @@ public class ChooseLockPattern extends SettingsActivity {
getActivity().finish(); getActivity().finish();
} }
} }
public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
private LockscreenCredential mChosenPattern;
private LockscreenCredential mCurrentCredential;
public void start(LockPatternUtils utils, boolean requestGatekeeperPassword,
LockscreenCredential chosenPattern, LockscreenCredential currentCredential,
int userId) {
prepare(utils, requestGatekeeperPassword, userId);
mCurrentCredential = currentCredential != null ? currentCredential
: LockscreenCredential.createNone();
mChosenPattern = chosenPattern;
mUserId = userId;
start();
}
@Override
protected Pair<Boolean, Intent> saveAndVerifyInBackground() {
final int userId = mUserId;
final boolean success = mUtils.setLockCredential(mChosenPattern, mCurrentCredential,
userId);
if (success) {
unifyProfileCredentialIfRequested();
}
Intent result = null;
if (success && mRequestGatekeeperPassword) {
// If a Gatekeeper Password was requested, invoke the LockSettingsService code
// path to return a Gatekeeper Password based on the credential that the user
// chose. This should only be run if the credential was successfully set.
final VerifyCredentialResponse response = mUtils.verifyCredential(mChosenPattern,
userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE);
if (!response.isMatched() || !response.containsGatekeeperPasswordHandle()) {
Log.e(TAG, "critical: bad response or missing GK PW handle for known good"
+ " pattern: " + response.toString());
}
result = new Intent();
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE,
response.getGatekeeperPasswordHandle());
}
return Pair.create(success, result);
}
}
} }

View File

@@ -125,7 +125,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
public static class ConfirmLockPasswordFragment extends ConfirmDeviceCredentialBaseFragment public static class ConfirmLockPasswordFragment extends ConfirmDeviceCredentialBaseFragment
implements OnClickListener, OnEditorActionListener, implements OnClickListener, OnEditorActionListener,
CredentialCheckResultTracker.Listener, SaveChosenLockWorkerBase.Listener, CredentialCheckResultTracker.Listener, SaveAndFinishWorker.Listener,
RemoteLockscreenValidationFragment.Listener { RemoteLockscreenValidationFragment.Listener {
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result"; private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
private ImeAwareEditText mPasswordEntry; private ImeAwareEditText mPasswordEntry;
@@ -633,15 +633,15 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
if (mCheckBox.isChecked() && mRemoteLockscreenValidationFragment if (mCheckBox.isChecked() && mRemoteLockscreenValidationFragment
.getLockscreenCredential() != null) { .getLockscreenCredential() != null) {
Log.i(TAG, "Setting device screen lock to the other device's screen lock."); Log.i(TAG, "Setting device screen lock to the other device's screen lock.");
ChooseLockPassword.SaveAndFinishWorker saveAndFinishWorker = SaveAndFinishWorker saveAndFinishWorker = new SaveAndFinishWorker();
new ChooseLockPassword.SaveAndFinishWorker();
getFragmentManager().beginTransaction().add(saveAndFinishWorker, null) getFragmentManager().beginTransaction().add(saveAndFinishWorker, null)
.commit(); .commit();
getFragmentManager().executePendingTransactions(); getFragmentManager().executePendingTransactions();
saveAndFinishWorker.setListener(this); saveAndFinishWorker
.setListener(this)
.setRequestGatekeeperPasswordHandle(true);
saveAndFinishWorker.start( saveAndFinishWorker.start(
mLockPatternUtils, mLockPatternUtils,
/* requestGatekeeperPassword= */ true,
mRemoteLockscreenValidationFragment.getLockscreenCredential(), mRemoteLockscreenValidationFragment.getLockscreenCredential(),
/* currentCredential= */ null, /* currentCredential= */ null,
mEffectiveUserId); mEffectiveUserId);

View File

@@ -93,7 +93,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment
implements AppearAnimationCreator<Object>, CredentialCheckResultTracker.Listener, implements AppearAnimationCreator<Object>, CredentialCheckResultTracker.Listener,
SaveChosenLockWorkerBase.Listener, RemoteLockscreenValidationFragment.Listener { SaveAndFinishWorker.Listener, RemoteLockscreenValidationFragment.Listener {
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result"; private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
@@ -630,15 +630,15 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
if (mCheckBox.isChecked() && mRemoteLockscreenValidationFragment if (mCheckBox.isChecked() && mRemoteLockscreenValidationFragment
.getLockscreenCredential() != null) { .getLockscreenCredential() != null) {
Log.i(TAG, "Setting device screen lock to the other device's screen lock."); Log.i(TAG, "Setting device screen lock to the other device's screen lock.");
ChooseLockPattern.SaveAndFinishWorker saveAndFinishWorker = SaveAndFinishWorker saveAndFinishWorker = new SaveAndFinishWorker();
new ChooseLockPattern.SaveAndFinishWorker();
getFragmentManager().beginTransaction().add(saveAndFinishWorker, null) getFragmentManager().beginTransaction().add(saveAndFinishWorker, null)
.commit(); .commit();
getFragmentManager().executePendingTransactions(); getFragmentManager().executePendingTransactions();
saveAndFinishWorker.setListener(this); saveAndFinishWorker
.setListener(this)
.setRequestGatekeeperPasswordHandle(true);
saveAndFinishWorker.start( saveAndFinishWorker.start(
mLockPatternUtils, mLockPatternUtils,
/* requestGatekeeperPassword= */ true,
mRemoteLockscreenValidationFragment.getLockscreenCredential(), mRemoteLockscreenValidationFragment.getLockscreenCredential(),
/* currentCredential= */ null, /* currentCredential= */ null,
mEffectiveUserId); mEffectiveUserId);

View File

@@ -20,6 +20,7 @@ import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.widget.Toast; import android.widget.Toast;
@@ -27,6 +28,7 @@ import androidx.fragment.app.Fragment;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.safetycenter.LockScreenSafetySource; import com.android.settings.safetycenter.LockScreenSafetySource;
@@ -34,18 +36,21 @@ import com.android.settings.safetycenter.LockScreenSafetySource;
* An invisible retained worker fragment to track the AsyncWork that saves (and optionally * An invisible retained worker fragment to track the AsyncWork that saves (and optionally
* verifies if a challenge is given) the chosen lock credential (pattern/pin/password). * verifies if a challenge is given) the chosen lock credential (pattern/pin/password).
*/ */
abstract class SaveChosenLockWorkerBase extends Fragment { public class SaveAndFinishWorker extends Fragment {
private static final String TAG = "SaveAndFinishWorker";
private Listener mListener; private Listener mListener;
private boolean mFinished; private boolean mFinished;
private Intent mResultData; private Intent mResultData;
protected LockPatternUtils mUtils; private LockPatternUtils mUtils;
protected boolean mRequestGatekeeperPassword; private boolean mRequestGatekeeperPassword;
protected boolean mWasSecureBefore; private boolean mWasSecureBefore;
protected int mUserId; private int mUserId;
protected int mUnificationProfileId = UserHandle.USER_NULL; private int mUnificationProfileId = UserHandle.USER_NULL;
protected LockscreenCredential mUnificationProfileCredential; private LockscreenCredential mUnificationProfileCredential;
private LockscreenCredential mChosenCredential;
private LockscreenCredential mCurrentCredential;
private boolean mBlocking; private boolean mBlocking;
@@ -55,28 +60,31 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
setRetainInstance(true); setRetainInstance(true);
} }
public void setListener(Listener listener) { public SaveAndFinishWorker setListener(Listener listener) {
if (mListener == listener) { if (mListener == listener) {
return; return this;
} }
mListener = listener; mListener = listener;
if (mFinished && mListener != null) { if (mFinished && mListener != null) {
mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData); mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData);
} }
return this;
} }
protected void prepare(LockPatternUtils utils, boolean requestGatekeeperPassword, int userId) { public void start(LockPatternUtils utils, LockscreenCredential chosenCredential,
LockscreenCredential currentCredential, int userId) {
mUtils = utils; mUtils = utils;
mUserId = userId; mUserId = userId;
mRequestGatekeeperPassword = requestGatekeeperPassword;
// This will be a no-op for non managed profiles. // This will be a no-op for non managed profiles.
mWasSecureBefore = mUtils.isSecure(mUserId); mWasSecureBefore = mUtils.isSecure(mUserId);
mFinished = false; mFinished = false;
mResultData = null; mResultData = null;
}
protected void start() { mChosenCredential = chosenCredential;
mCurrentCredential = currentCredential != null ? currentCredential
: LockscreenCredential.createNone();
if (mBlocking) { if (mBlocking) {
finish(saveAndVerifyInBackground().second); finish(saveAndVerifyInBackground().second);
} else { } else {
@@ -89,9 +97,34 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
* @return pair where the first is a boolean confirming whether the change was successful or not * @return pair where the first is a boolean confirming whether the change was successful or not
* and second is the Intent which has the challenge token or is null. * and second is the Intent which has the challenge token or is null.
*/ */
protected abstract Pair<Boolean, Intent> saveAndVerifyInBackground(); private Pair<Boolean, Intent> saveAndVerifyInBackground() {
final int userId = mUserId;
final boolean success = mUtils.setLockCredential(mChosenCredential, mCurrentCredential,
userId);
if (success) {
unifyProfileCredentialIfRequested();
}
Intent result = null;
if (success && mRequestGatekeeperPassword) {
// If a Gatekeeper Password was requested, invoke the LockSettingsService code
// path to return a Gatekeeper Password based on the credential that the user
// chose. This should only be run if the credential was successfully set.
final VerifyCredentialResponse response = mUtils.verifyCredential(mChosenCredential,
userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE);
protected void finish(Intent resultData) { if (!response.isMatched() || !response.containsGatekeeperPasswordHandle()) {
Log.e(TAG, "critical: bad response or missing GK PW handle for known good"
+ " credential: " + response.toString());
}
result = new Intent();
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE,
response.getGatekeeperPasswordHandle());
}
return Pair.create(success, result);
}
private void finish(Intent resultData) {
mFinished = true; mFinished = true;
mResultData = resultData; mResultData = resultData;
if (mListener != null) { if (mListener != null) {
@@ -103,16 +136,24 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
LockScreenSafetySource.onLockScreenChange(getContext()); LockScreenSafetySource.onLockScreenChange(getContext());
} }
public void setBlocking(boolean blocking) { public SaveAndFinishWorker setRequestGatekeeperPasswordHandle(boolean value) {
mBlocking = blocking; mRequestGatekeeperPassword = value;
return this;
} }
public void setProfileToUnify(int profileId, LockscreenCredential credential) { public SaveAndFinishWorker setBlocking(boolean blocking) {
mBlocking = blocking;
return this;
}
public SaveAndFinishWorker setProfileToUnify(
int profileId, LockscreenCredential credential) {
mUnificationProfileId = profileId; mUnificationProfileId = profileId;
mUnificationProfileCredential = credential.duplicate(); mUnificationProfileCredential = credential.duplicate();
return this;
} }
protected void unifyProfileCredentialIfRequested() { private void unifyProfileCredentialIfRequested() {
if (mUnificationProfileId != UserHandle.USER_NULL) { if (mUnificationProfileId != UserHandle.USER_NULL) {
mUtils.setSeparateProfileChallengeEnabled(mUnificationProfileId, false, mUtils.setSeparateProfileChallengeEnabled(mUnificationProfileId, false,
mUnificationProfileCredential); mUnificationProfileCredential);

View File

@@ -1,8 +1,7 @@
com.android.settings.deletionhelper.ActivationWarningFragment com.android.settings.deletionhelper.ActivationWarningFragment
com.android.settings.applications.appops.AppOpsCategory com.android.settings.applications.appops.AppOpsCategory
com.android.settings.CustomListPreference$CustomListPreferenceDialogFragment com.android.settings.CustomListPreference$CustomListPreferenceDialogFragment
com.android.settings.password.ChooseLockPassword$SaveAndFinishWorker com.android.settings.password.SaveAndFinishWorker
com.android.settings.password.ChooseLockPattern$SaveAndFinishWorker
com.android.settings.RestrictedListPreference$RestrictedListPreferenceDialogFragment com.android.settings.RestrictedListPreference$RestrictedListPreferenceDialogFragment
com.android.settings.password.ConfirmDeviceCredentialBaseFragment$LastTryDialog com.android.settings.password.ConfirmDeviceCredentialBaseFragment$LastTryDialog
com.android.settings.password.CredentialCheckResultTracker com.android.settings.password.CredentialCheckResultTracker