Merge changes from topic "simplify_pw" into udc-qpr-dev
* changes: Handle EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW Extract common code to SaveChosenLockWorkerBase
This commit is contained in:
committed by
Android (Google) Code Review
commit
e414d40e60
@@ -33,6 +33,7 @@ import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_C
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
@@ -795,6 +796,9 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
if (getIntent().getBooleanExtra(EXTRA_SHOW_OPTIONS_BUTTON, false)) {
|
||||
intent.putExtra(EXTRA_SHOW_OPTIONS_BUTTON, chooseLockSkipped);
|
||||
}
|
||||
if (getIntent().getBooleanExtra(EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW, false)) {
|
||||
intent.putExtra(EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW, true);
|
||||
}
|
||||
intent.putExtra(EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS, getIntent().getExtras());
|
||||
// If the caller requested Gatekeeper Password Handle to be returned, we assume it
|
||||
// came from biometric enrollment. onActivityResult will put the LockSettingsService
|
||||
|
@@ -65,7 +65,6 @@ import android.text.Spannable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -89,7 +88,6 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockscreenCredential;
|
||||
import com.android.internal.widget.PasswordValidationError;
|
||||
import com.android.internal.widget.TextViewInputDisabler;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SetupWizardUtils;
|
||||
@@ -236,6 +234,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
private LockscreenCredential mCurrentCredential;
|
||||
private LockscreenCredential mChosenPassword;
|
||||
private boolean mRequestGatekeeperPassword;
|
||||
private boolean mRequestWriteRepairModePassword;
|
||||
private ImeAwareEditText mPasswordEntry;
|
||||
private TextViewInputDisabler mPasswordEntryInputDisabler;
|
||||
|
||||
@@ -565,6 +564,8 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
|
||||
mRequestGatekeeperPassword = intent.getBooleanExtra(
|
||||
ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, false);
|
||||
mRequestWriteRepairModePassword = intent.getBooleanExtra(
|
||||
ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW, false);
|
||||
if (savedInstanceState == null) {
|
||||
updateStage(Stage.Introduction);
|
||||
if (confirmCredentials) {
|
||||
@@ -574,6 +575,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
.setTitle(getString(R.string.unlock_set_unlock_launch_picker_title))
|
||||
.setReturnCredentials(true)
|
||||
.setRequestGatekeeperPasswordHandle(mRequestGatekeeperPassword)
|
||||
.setRequestWriteRepairModePassword(mRequestWriteRepairModePassword)
|
||||
.setUserId(mUserId)
|
||||
.show();
|
||||
}
|
||||
@@ -1035,7 +1037,10 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
setNextEnabled(false);
|
||||
|
||||
mSaveAndFinishWorker = new SaveAndFinishWorker();
|
||||
mSaveAndFinishWorker.setListener(this);
|
||||
mSaveAndFinishWorker
|
||||
.setListener(this)
|
||||
.setRequestGatekeeperPasswordHandle(mRequestGatekeeperPassword)
|
||||
.setRequestWriteRepairModePassword(mRequestWriteRepairModePassword);
|
||||
|
||||
getFragmentManager().beginTransaction().add(mSaveAndFinishWorker,
|
||||
FRAGMENT_TAG_SAVE_AND_FINISH).commit();
|
||||
@@ -1055,7 +1060,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
(mAutoPinConfirmOption != null && mAutoPinConfirmOption.isChecked()),
|
||||
mUserId);
|
||||
|
||||
mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword,
|
||||
mSaveAndFinishWorker.start(mLockPatternUtils,
|
||||
mChosenPassword, mCurrentCredential, mUserId);
|
||||
}
|
||||
|
||||
@@ -1108,50 +1113,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -34,7 +34,6 @@ import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.TypedValue;
|
||||
import android.view.KeyEvent;
|
||||
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.DisplayMode;
|
||||
import com.android.internal.widget.LockscreenCredential;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SetupWizardUtils;
|
||||
@@ -206,6 +204,7 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
|
||||
private LockscreenCredential mCurrentCredential;
|
||||
private boolean mRequestGatekeeperPassword;
|
||||
private boolean mRequestWriteRepairModePassword;
|
||||
protected TextView mHeaderText;
|
||||
protected LockPatternView mLockPatternView;
|
||||
protected TextView mFooterText;
|
||||
@@ -563,6 +562,8 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
intent.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
|
||||
mRequestGatekeeperPassword = intent.getBooleanExtra(
|
||||
ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, false);
|
||||
mRequestWriteRepairModePassword = intent.getBooleanExtra(
|
||||
ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW, false);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
if (confirmCredentials) {
|
||||
@@ -576,6 +577,7 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
.setTitle(getString(R.string.unlock_set_unlock_launch_picker_title))
|
||||
.setReturnCredentials(true)
|
||||
.setRequestGatekeeperPasswordHandle(mRequestGatekeeperPassword)
|
||||
.setRequestWriteRepairModePassword(mRequestWriteRepairModePassword)
|
||||
.setUserId(mUserId)
|
||||
.show();
|
||||
|
||||
@@ -827,7 +829,10 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
setRightButtonEnabled(false);
|
||||
|
||||
mSaveAndFinishWorker = new SaveAndFinishWorker();
|
||||
mSaveAndFinishWorker.setListener(this);
|
||||
mSaveAndFinishWorker
|
||||
.setListener(this)
|
||||
.setRequestGatekeeperPasswordHandle(mRequestGatekeeperPassword)
|
||||
.setRequestWriteRepairModePassword(mRequestWriteRepairModePassword);
|
||||
|
||||
getFragmentManager().beginTransaction().add(mSaveAndFinishWorker,
|
||||
FRAGMENT_TAG_SAVE_AND_FINISH).commit();
|
||||
@@ -843,7 +848,7 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
profileCredential);
|
||||
}
|
||||
}
|
||||
mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword,
|
||||
mSaveAndFinishWorker.start(mLockPatternUtils,
|
||||
mChosenPattern, mCurrentCredential, mUserId);
|
||||
}
|
||||
|
||||
@@ -867,51 +872,4 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -73,6 +73,8 @@ public final class ChooseLockSettingsHelper {
|
||||
public static final String EXTRA_KEY_GK_PW_HANDLE = "gk_pw_handle";
|
||||
public static final String EXTRA_KEY_REQUEST_WRITE_REPAIR_MODE_PW =
|
||||
"request_write_repair_mode_pw";
|
||||
public static final String EXTRA_KEY_WROTE_REPAIR_MODE_CREDENTIAL =
|
||||
"wrote_repair_mode_credential";
|
||||
|
||||
/**
|
||||
* When EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL and EXTRA_KEY_UNIFICATION_PROFILE_ID are
|
||||
|
@@ -125,7 +125,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||
|
||||
public static class ConfirmLockPasswordFragment extends ConfirmDeviceCredentialBaseFragment
|
||||
implements OnClickListener, OnEditorActionListener,
|
||||
CredentialCheckResultTracker.Listener, SaveChosenLockWorkerBase.Listener,
|
||||
CredentialCheckResultTracker.Listener, SaveAndFinishWorker.Listener,
|
||||
RemoteLockscreenValidationFragment.Listener {
|
||||
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
|
||||
private ImeAwareEditText mPasswordEntry;
|
||||
@@ -633,15 +633,15 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||
if (mCheckBox.isChecked() && mRemoteLockscreenValidationFragment
|
||||
.getLockscreenCredential() != null) {
|
||||
Log.i(TAG, "Setting device screen lock to the other device's screen lock.");
|
||||
ChooseLockPassword.SaveAndFinishWorker saveAndFinishWorker =
|
||||
new ChooseLockPassword.SaveAndFinishWorker();
|
||||
SaveAndFinishWorker saveAndFinishWorker = new SaveAndFinishWorker();
|
||||
getFragmentManager().beginTransaction().add(saveAndFinishWorker, null)
|
||||
.commit();
|
||||
getFragmentManager().executePendingTransactions();
|
||||
saveAndFinishWorker.setListener(this);
|
||||
saveAndFinishWorker
|
||||
.setListener(this)
|
||||
.setRequestGatekeeperPasswordHandle(true);
|
||||
saveAndFinishWorker.start(
|
||||
mLockPatternUtils,
|
||||
/* requestGatekeeperPassword= */ true,
|
||||
mRemoteLockscreenValidationFragment.getLockscreenCredential(),
|
||||
/* currentCredential= */ null,
|
||||
mEffectiveUserId);
|
||||
|
@@ -93,7 +93,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
||||
|
||||
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment
|
||||
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";
|
||||
|
||||
@@ -630,15 +630,15 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
||||
if (mCheckBox.isChecked() && mRemoteLockscreenValidationFragment
|
||||
.getLockscreenCredential() != null) {
|
||||
Log.i(TAG, "Setting device screen lock to the other device's screen lock.");
|
||||
ChooseLockPattern.SaveAndFinishWorker saveAndFinishWorker =
|
||||
new ChooseLockPattern.SaveAndFinishWorker();
|
||||
SaveAndFinishWorker saveAndFinishWorker = new SaveAndFinishWorker();
|
||||
getFragmentManager().beginTransaction().add(saveAndFinishWorker, null)
|
||||
.commit();
|
||||
getFragmentManager().executePendingTransactions();
|
||||
saveAndFinishWorker.setListener(this);
|
||||
saveAndFinishWorker
|
||||
.setListener(this)
|
||||
.setRequestGatekeeperPasswordHandle(true);
|
||||
saveAndFinishWorker.start(
|
||||
mLockPatternUtils,
|
||||
/* requestGatekeeperPassword= */ true,
|
||||
mRemoteLockscreenValidationFragment.getLockscreenCredential(),
|
||||
/* currentCredential= */ null,
|
||||
mEffectiveUserId);
|
||||
|
213
src/com/android/settings/password/SaveAndFinishWorker.java
Normal file
213
src/com/android/settings/password/SaveAndFinishWorker.java
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.password;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockscreenCredential;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.safetycenter.LockScreenSafetySource;
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
public class SaveAndFinishWorker extends Fragment {
|
||||
private static final String TAG = "SaveAndFinishWorker";
|
||||
|
||||
private Listener mListener;
|
||||
private boolean mFinished;
|
||||
private Intent mResultData;
|
||||
|
||||
private LockPatternUtils mUtils;
|
||||
private boolean mRequestGatekeeperPassword;
|
||||
private boolean mRequestWriteRepairModePassword;
|
||||
private boolean mWasSecureBefore;
|
||||
private int mUserId;
|
||||
private int mUnificationProfileId = UserHandle.USER_NULL;
|
||||
private LockscreenCredential mUnificationProfileCredential;
|
||||
private LockscreenCredential mChosenCredential;
|
||||
private LockscreenCredential mCurrentCredential;
|
||||
|
||||
private boolean mBlocking;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
public SaveAndFinishWorker setListener(Listener listener) {
|
||||
if (mListener == listener) {
|
||||
return this;
|
||||
}
|
||||
|
||||
mListener = listener;
|
||||
if (mFinished && mListener != null) {
|
||||
mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void prepare(LockPatternUtils utils, LockscreenCredential chosenCredential,
|
||||
LockscreenCredential currentCredential, int userId) {
|
||||
mUtils = utils;
|
||||
mUserId = userId;
|
||||
// This will be a no-op for non managed profiles.
|
||||
mWasSecureBefore = mUtils.isSecure(mUserId);
|
||||
mFinished = false;
|
||||
mResultData = null;
|
||||
|
||||
mChosenCredential = chosenCredential;
|
||||
mCurrentCredential = currentCredential != null ? currentCredential
|
||||
: LockscreenCredential.createNone();
|
||||
}
|
||||
|
||||
public void start(LockPatternUtils utils, LockscreenCredential chosenCredential,
|
||||
LockscreenCredential currentCredential, int userId) {
|
||||
prepare(utils, chosenCredential, currentCredential, userId);
|
||||
if (mBlocking) {
|
||||
finish(saveAndVerifyInBackground().second);
|
||||
} else {
|
||||
new Task().execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the save and verify work in background.
|
||||
* @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.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
Pair<Boolean, Intent> saveAndVerifyInBackground() {
|
||||
final int userId = mUserId;
|
||||
if (!mUtils.setLockCredential(mChosenCredential, mCurrentCredential, userId)) {
|
||||
return Pair.create(false, null);
|
||||
}
|
||||
|
||||
unifyProfileCredentialIfRequested();
|
||||
|
||||
@LockPatternUtils.VerifyFlag int flags = 0;
|
||||
if (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.
|
||||
flags |= LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE;
|
||||
}
|
||||
if (mRequestWriteRepairModePassword) {
|
||||
flags |= LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;
|
||||
}
|
||||
if (flags == 0) {
|
||||
return Pair.create(true, null);
|
||||
}
|
||||
|
||||
Intent result = new Intent();
|
||||
final VerifyCredentialResponse response = mUtils.verifyCredential(mChosenCredential,
|
||||
userId, flags);
|
||||
if (response.isMatched()) {
|
||||
if (mRequestGatekeeperPassword && response.containsGatekeeperPasswordHandle()) {
|
||||
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE,
|
||||
response.getGatekeeperPasswordHandle());
|
||||
} else if (mRequestGatekeeperPassword) {
|
||||
Log.e(TAG, "critical: missing GK PW handle for known good credential: " + response);
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "critical: bad response for known good credential: " + response);
|
||||
}
|
||||
if (mRequestWriteRepairModePassword) {
|
||||
// Notify the caller if repair mode credential is saved successfully
|
||||
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_WROTE_REPAIR_MODE_CREDENTIAL,
|
||||
response.isMatched());
|
||||
}
|
||||
|
||||
return Pair.create(true, result);
|
||||
}
|
||||
|
||||
private void finish(Intent resultData) {
|
||||
mFinished = true;
|
||||
mResultData = resultData;
|
||||
if (mListener != null) {
|
||||
mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData);
|
||||
}
|
||||
if (mUnificationProfileCredential != null) {
|
||||
mUnificationProfileCredential.zeroize();
|
||||
}
|
||||
LockScreenSafetySource.onLockScreenChange(getContext());
|
||||
}
|
||||
|
||||
public SaveAndFinishWorker setRequestGatekeeperPasswordHandle(boolean value) {
|
||||
mRequestGatekeeperPassword = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaveAndFinishWorker setRequestWriteRepairModePassword(boolean value) {
|
||||
mRequestWriteRepairModePassword = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaveAndFinishWorker setBlocking(boolean blocking) {
|
||||
mBlocking = blocking;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaveAndFinishWorker setProfileToUnify(
|
||||
int profileId, LockscreenCredential credential) {
|
||||
mUnificationProfileId = profileId;
|
||||
mUnificationProfileCredential = credential.duplicate();
|
||||
return this;
|
||||
}
|
||||
|
||||
private void unifyProfileCredentialIfRequested() {
|
||||
if (mUnificationProfileId != UserHandle.USER_NULL) {
|
||||
mUtils.setSeparateProfileChallengeEnabled(mUnificationProfileId, false,
|
||||
mUnificationProfileCredential);
|
||||
}
|
||||
}
|
||||
|
||||
private class Task extends AsyncTask<Void, Void, Pair<Boolean, Intent>> {
|
||||
|
||||
@Override
|
||||
protected Pair<Boolean, Intent> doInBackground(Void... params){
|
||||
return saveAndVerifyInBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Pair<Boolean, Intent> resultData) {
|
||||
if (!resultData.first) {
|
||||
Toast.makeText(getContext(), R.string.lockpassword_credential_changed,
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
finish(resultData.second);
|
||||
}
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData);
|
||||
}
|
||||
}
|
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.password;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Pair;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockscreenCredential;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.safetycenter.LockScreenSafetySource;
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
abstract class SaveChosenLockWorkerBase extends Fragment {
|
||||
|
||||
private Listener mListener;
|
||||
private boolean mFinished;
|
||||
private Intent mResultData;
|
||||
|
||||
protected LockPatternUtils mUtils;
|
||||
protected boolean mRequestGatekeeperPassword;
|
||||
protected boolean mWasSecureBefore;
|
||||
protected int mUserId;
|
||||
protected int mUnificationProfileId = UserHandle.USER_NULL;
|
||||
protected LockscreenCredential mUnificationProfileCredential;
|
||||
|
||||
private boolean mBlocking;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
public void setListener(Listener listener) {
|
||||
if (mListener == listener) {
|
||||
return;
|
||||
}
|
||||
|
||||
mListener = listener;
|
||||
if (mFinished && mListener != null) {
|
||||
mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData);
|
||||
}
|
||||
}
|
||||
|
||||
protected void prepare(LockPatternUtils utils, boolean requestGatekeeperPassword, int userId) {
|
||||
mUtils = utils;
|
||||
mUserId = userId;
|
||||
mRequestGatekeeperPassword = requestGatekeeperPassword;
|
||||
// This will be a no-op for non managed profiles.
|
||||
mWasSecureBefore = mUtils.isSecure(mUserId);
|
||||
mFinished = false;
|
||||
mResultData = null;
|
||||
}
|
||||
|
||||
protected void start() {
|
||||
if (mBlocking) {
|
||||
finish(saveAndVerifyInBackground().second);
|
||||
} else {
|
||||
new Task().execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the save and verify work in background.
|
||||
* @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.
|
||||
*/
|
||||
protected abstract Pair<Boolean, Intent> saveAndVerifyInBackground();
|
||||
|
||||
protected void finish(Intent resultData) {
|
||||
mFinished = true;
|
||||
mResultData = resultData;
|
||||
if (mListener != null) {
|
||||
mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData);
|
||||
}
|
||||
if (mUnificationProfileCredential != null) {
|
||||
mUnificationProfileCredential.zeroize();
|
||||
}
|
||||
LockScreenSafetySource.onLockScreenChange(getContext());
|
||||
}
|
||||
|
||||
public void setBlocking(boolean blocking) {
|
||||
mBlocking = blocking;
|
||||
}
|
||||
|
||||
public void setProfileToUnify(int profileId, LockscreenCredential credential) {
|
||||
mUnificationProfileId = profileId;
|
||||
mUnificationProfileCredential = credential.duplicate();
|
||||
}
|
||||
|
||||
protected void unifyProfileCredentialIfRequested() {
|
||||
if (mUnificationProfileId != UserHandle.USER_NULL) {
|
||||
mUtils.setSeparateProfileChallengeEnabled(mUnificationProfileId, false,
|
||||
mUnificationProfileCredential);
|
||||
}
|
||||
}
|
||||
|
||||
private class Task extends AsyncTask<Void, Void, Pair<Boolean, Intent>> {
|
||||
|
||||
@Override
|
||||
protected Pair<Boolean, Intent> doInBackground(Void... params){
|
||||
return saveAndVerifyInBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Pair<Boolean, Intent> resultData) {
|
||||
if (!resultData.first) {
|
||||
Toast.makeText(getContext(), R.string.lockpassword_credential_changed,
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
finish(resultData.second);
|
||||
}
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData);
|
||||
}
|
||||
}
|
@@ -1,8 +1,7 @@
|
||||
com.android.settings.deletionhelper.ActivationWarningFragment
|
||||
com.android.settings.applications.appops.AppOpsCategory
|
||||
com.android.settings.CustomListPreference$CustomListPreferenceDialogFragment
|
||||
com.android.settings.password.ChooseLockPassword$SaveAndFinishWorker
|
||||
com.android.settings.password.ChooseLockPattern$SaveAndFinishWorker
|
||||
com.android.settings.password.SaveAndFinishWorker
|
||||
com.android.settings.RestrictedListPreference$RestrictedListPreferenceDialogFragment
|
||||
com.android.settings.password.ConfirmDeviceCredentialBaseFragment$LastTryDialog
|
||||
com.android.settings.password.CredentialCheckResultTracker
|
||||
|
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.password;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockscreenCredential;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SaveAndFinishWorkerTest {
|
||||
@Test
|
||||
public void testSetRequestWriteRepairModePassword_setLockCredentialFail() {
|
||||
int userId = 0;
|
||||
int flags = LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;
|
||||
var chosenCredential = LockscreenCredential.createPassword("1234");
|
||||
var currentCredential = LockscreenCredential.createNone();
|
||||
var worker = new SaveAndFinishWorker();
|
||||
var lpu = mock(LockPatternUtils.class);
|
||||
|
||||
when(lpu.setLockCredential(chosenCredential, currentCredential, userId)).thenReturn(false);
|
||||
|
||||
worker.setRequestWriteRepairModePassword(true);
|
||||
worker.prepare(lpu, chosenCredential, currentCredential, userId);
|
||||
var result = worker.saveAndVerifyInBackground();
|
||||
|
||||
verify(lpu).setLockCredential(chosenCredential, currentCredential, userId);
|
||||
verify(lpu, never()).verifyCredential(chosenCredential, userId, flags);
|
||||
assertThat(result.first).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRequestWriteRepairModePassword_verifyCredentialFail() {
|
||||
int userId = 0;
|
||||
int flags = LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;
|
||||
var chosenCredential = LockscreenCredential.createPassword("1234");
|
||||
var currentCredential = LockscreenCredential.createNone();
|
||||
var worker = new SaveAndFinishWorker();
|
||||
var lpu = mock(LockPatternUtils.class);
|
||||
var response = VerifyCredentialResponse.fromError();
|
||||
|
||||
when(lpu.setLockCredential(chosenCredential, currentCredential, userId)).thenReturn(true);
|
||||
when(lpu.verifyCredential(chosenCredential, userId, flags)).thenReturn(response);
|
||||
|
||||
worker.setRequestWriteRepairModePassword(true);
|
||||
worker.prepare(lpu, chosenCredential, currentCredential, userId);
|
||||
var result = worker.saveAndVerifyInBackground();
|
||||
|
||||
verify(lpu).setLockCredential(chosenCredential, currentCredential, userId);
|
||||
verify(lpu).verifyCredential(chosenCredential, userId, flags);
|
||||
assertThat(result.first).isTrue();
|
||||
assertThat(result.second.getBooleanExtra(
|
||||
ChooseLockSettingsHelper.EXTRA_KEY_WROTE_REPAIR_MODE_CREDENTIAL, true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRequestWriteRepairModePassword_verifyCredentialSucceed() {
|
||||
int userId = 0;
|
||||
int flags = LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;
|
||||
var chosenCredential = LockscreenCredential.createPassword("1234");
|
||||
var currentCredential = LockscreenCredential.createNone();
|
||||
var worker = new SaveAndFinishWorker();
|
||||
var lpu = mock(LockPatternUtils.class);
|
||||
var response = new VerifyCredentialResponse.Builder().build();
|
||||
|
||||
when(lpu.setLockCredential(chosenCredential, currentCredential, userId)).thenReturn(true);
|
||||
when(lpu.verifyCredential(chosenCredential, userId, flags)).thenReturn(response);
|
||||
|
||||
worker.setRequestWriteRepairModePassword(true);
|
||||
worker.prepare(lpu, chosenCredential, currentCredential, userId);
|
||||
var result = worker.saveAndVerifyInBackground();
|
||||
|
||||
verify(lpu).setLockCredential(chosenCredential, currentCredential, userId);
|
||||
verify(lpu).verifyCredential(chosenCredential, userId, flags);
|
||||
assertThat(result.first).isTrue();
|
||||
assertThat(result.second.getBooleanExtra(
|
||||
ChooseLockSettingsHelper.EXTRA_KEY_WROTE_REPAIR_MODE_CREDENTIAL, false))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRequestWriteRepairModePassword_verifyCredentialSucceed_noGkPwHandle() {
|
||||
int userId = 0;
|
||||
int flags = LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW
|
||||
| LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE;
|
||||
var chosenCredential = LockscreenCredential.createPassword("1234");
|
||||
var currentCredential = LockscreenCredential.createNone();
|
||||
var worker = new SaveAndFinishWorker();
|
||||
var lpu = mock(LockPatternUtils.class);
|
||||
var response = new VerifyCredentialResponse.Builder().build();
|
||||
|
||||
when(lpu.setLockCredential(chosenCredential, currentCredential, userId)).thenReturn(true);
|
||||
when(lpu.verifyCredential(chosenCredential, userId, flags)).thenReturn(response);
|
||||
|
||||
worker.setRequestWriteRepairModePassword(true);
|
||||
worker.setRequestGatekeeperPasswordHandle(true);
|
||||
worker.prepare(lpu, chosenCredential, currentCredential, userId);
|
||||
var result = worker.saveAndVerifyInBackground();
|
||||
|
||||
verify(lpu).setLockCredential(chosenCredential, currentCredential, userId);
|
||||
verify(lpu).verifyCredential(chosenCredential, userId, flags);
|
||||
assertThat(result.first).isTrue();
|
||||
assertThat(result.second.getBooleanExtra(
|
||||
ChooseLockSettingsHelper.EXTRA_KEY_WROTE_REPAIR_MODE_CREDENTIAL, false))
|
||||
.isTrue();
|
||||
assertThat(result.second.getLongExtra(
|
||||
ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, -1))
|
||||
.isEqualTo(-1);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user