Merge "Fix ChoosePat/Pin/Pwd crash from async task" into mnc-dr-dev

This commit is contained in:
Xiyuan Xia
2015-08-28 01:46:57 +00:00
committed by Android (Google) Code Review
3 changed files with 301 additions and 181 deletions

View File

@@ -17,11 +17,11 @@
package com.android.settings; package com.android.settings;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.PasswordEntryKeyboardHelper; import com.android.internal.widget.PasswordEntryKeyboardHelper;
import com.android.internal.widget.PasswordEntryKeyboardView; import com.android.internal.widget.PasswordEntryKeyboardView;
import com.android.internal.widget.TextViewInputDisabler; import com.android.internal.widget.TextViewInputDisabler;
import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
import com.android.settings.notification.RedactionInterstitial; import com.android.settings.notification.RedactionInterstitial;
import android.app.Activity; import android.app.Activity;
@@ -30,7 +30,6 @@ import android.app.admin.DevicePolicyManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.inputmethodservice.KeyboardView; import android.inputmethodservice.KeyboardView;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
@@ -122,10 +121,12 @@ public class ChooseLockPassword extends SettingsActivity {
} }
public static class ChooseLockPasswordFragment extends InstrumentedFragment public static class ChooseLockPasswordFragment extends InstrumentedFragment
implements OnClickListener, OnEditorActionListener, TextWatcher { implements OnClickListener, OnEditorActionListener, TextWatcher,
SaveAndFinishWorker.Listener {
private static final String KEY_FIRST_PIN = "first_pin"; private static final String KEY_FIRST_PIN = "first_pin";
private static final String KEY_UI_STAGE = "ui_stage"; private static final String KEY_UI_STAGE = "ui_stage";
private static final String KEY_CURRENT_PASSWORD = "current_password"; private static final String KEY_CURRENT_PASSWORD = "current_password";
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
private String mCurrentPassword; private String mCurrentPassword;
private String mChosenPassword; private String mChosenPassword;
@@ -142,14 +143,11 @@ public class ChooseLockPassword extends SettingsActivity {
private int mPasswordMinNumeric = 0; private int mPasswordMinNumeric = 0;
private int mPasswordMinNonLetter = 0; private int mPasswordMinNonLetter = 0;
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private AsyncTask<?, ?, ?> mPendingLockCheck; private SaveAndFinishWorker mSaveAndFinishWorker;
private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
private ChooseLockSettingsHelper mChooseLockSettingsHelper; private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private Stage mUiStage = Stage.Introduction; private Stage mUiStage = Stage.Introduction;
// True once we have confirmed new PIN/password to prevent virtual keyboard
// re-entries of the same PIN
private boolean mDone = false;
private TextView mHeaderText; private TextView mHeaderText;
private String mFirstPin; private String mFirstPin;
private KeyboardView mKeyboardView; private KeyboardView mKeyboardView;
@@ -305,8 +303,11 @@ public class ChooseLockPassword extends SettingsActivity {
if (mCurrentPassword == null) { if (mCurrentPassword == null) {
mCurrentPassword = savedInstanceState.getString(KEY_CURRENT_PASSWORD); mCurrentPassword = savedInstanceState.getString(KEY_CURRENT_PASSWORD);
} }
// Re-attach to the exiting worker if there is one.
mSaveAndFinishWorker = (SaveAndFinishWorker) getFragmentManager().findFragmentByTag(
FRAGMENT_TAG_SAVE_AND_FINISH);
} }
mDone = false;
if (activity instanceof SettingsActivity) { if (activity instanceof SettingsActivity) {
final SettingsActivity sa = (SettingsActivity) activity; final SettingsActivity sa = (SettingsActivity) activity;
int id = mIsAlphaMode ? R.string.lockpassword_choose_your_password_header int id = mIsAlphaMode ? R.string.lockpassword_choose_your_password_header
@@ -325,16 +326,18 @@ public class ChooseLockPassword extends SettingsActivity {
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
updateStage(mUiStage); updateStage(mUiStage);
mPasswordEntryInputDisabler.setInputEnabled(true); if (mSaveAndFinishWorker != null) {
mSaveAndFinishWorker.setListener(this);
} else {
mKeyboardView.requestFocus(); mKeyboardView.requestFocus();
} }
}
@Override @Override
public void onPause() { public void onPause() {
mHandler.removeMessages(MSG_SHOW_ERROR); mHandler.removeMessages(MSG_SHOW_ERROR);
if (mPendingLockCheck != null) { if (mSaveAndFinishWorker != null) {
mPendingLockCheck.cancel(false); mSaveAndFinishWorker.setListener(null);
mPendingLockCheck = null;
} }
super.onPause(); super.onPause();
@@ -482,39 +485,8 @@ public class ChooseLockPassword extends SettingsActivity {
return null; return null;
} }
private class SaveChosenPasswordAndFinish extends AsyncTask<Void, Void, Void> {
boolean mWasSecureBefore;
@Override
public void onPreExecute() {
mWasSecureBefore = mLockPatternUtils.isSecure(UserHandle.myUserId());
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
mLockPatternUtils.setCredentialRequiredToDecrypt(required);
}
@Override
public Void doInBackground(Void... v) {
mLockPatternUtils.saveLockPassword(mChosenPassword, mCurrentPassword, mRequestedQuality,
UserHandle.myUserId());
return null;
}
@Override
public void onPostExecute(Void v) {
if (mHasChallenge) {
startVerifyPassword(mChosenPassword, mWasSecureBefore);
return;
} else {
getActivity().setResult(RESULT_FINISHED);
}
finishConfirmStage(mWasSecureBefore);
}
}
public void handleNext() { public void handleNext() {
if (mDone) return; if (mSaveAndFinishWorker != null) return;
mChosenPassword = mPasswordEntry.getText().toString(); mChosenPassword = mPasswordEntry.getText().toString();
if (TextUtils.isEmpty(mChosenPassword)) { if (TextUtils.isEmpty(mChosenPassword)) {
return; return;
@@ -529,9 +501,7 @@ public class ChooseLockPassword extends SettingsActivity {
} }
} else if (mUiStage == Stage.NeedToConfirm) { } else if (mUiStage == Stage.NeedToConfirm) {
if (mFirstPin.equals(mChosenPassword)) { if (mFirstPin.equals(mChosenPassword)) {
setNextEnabled(false); startSaveAndFinish();
mDone = true;
new SaveChosenPasswordAndFinish().execute();
} else { } else {
CharSequence tmp = mPasswordEntry.getText(); CharSequence tmp = mPasswordEntry.getText();
if (tmp != null) { if (tmp != null) {
@@ -545,49 +515,6 @@ public class ChooseLockPassword extends SettingsActivity {
} }
} }
private void startVerifyPassword(final String pin, final boolean wasSecureBefore) {
mPasswordEntryInputDisabler.setInputEnabled(false);
setNextEnabled(false);
if (mPendingLockCheck != null) {
mPendingLockCheck.cancel(false);
}
mPendingLockCheck = LockPatternChecker.verifyPassword(
mLockPatternUtils,
pin,
mChallenge,
UserHandle.myUserId(),
new LockPatternChecker.OnVerifyCallback() {
@Override
public void onVerified(byte[] token, int timeoutMs) {
if (token == null) {
Log.e(TAG, "critical: no token returned from known good password");
}
mPasswordEntryInputDisabler.setInputEnabled(true);
setNextEnabled(true);
mPendingLockCheck = null;
Intent intent = new Intent();
intent.putExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN,
token);
getActivity().setResult(RESULT_FINISHED, intent);
finishConfirmStage(wasSecureBefore);
}
});
}
private void finishConfirmStage(boolean wasSecureBefore) {
getActivity().finish();
if (!wasSecureBefore) {
Intent intent = getRedactionInterstitialIntent(getActivity());
if (intent != null) {
startActivity(intent);
}
}
}
protected void setNextEnabled(boolean enabled) { protected void setNextEnabled(boolean enabled) {
mNextButton.setEnabled(enabled); mNextButton.setEnabled(enabled);
} }
@@ -631,6 +558,7 @@ public class ChooseLockPassword extends SettingsActivity {
* Update the hint based on current Stage and length of password entry * Update the hint based on current Stage and length of password entry
*/ */
private void updateUi() { private void updateUi() {
final boolean canInput = mSaveAndFinishWorker == null;
String password = mPasswordEntry.getText().toString(); String password = mPasswordEntry.getText().toString();
final int length = password.length(); final int length = password.length();
if (mUiStage == Stage.Introduction) { if (mUiStage == Stage.Introduction) {
@@ -651,9 +579,10 @@ public class ChooseLockPassword extends SettingsActivity {
} }
} else { } else {
mHeaderText.setText(mIsAlphaMode ? mUiStage.alphaHint : mUiStage.numericHint); mHeaderText.setText(mIsAlphaMode ? mUiStage.alphaHint : mUiStage.numericHint);
setNextEnabled(length > 0); setNextEnabled(canInput && length > 0);
} }
setNextText(mUiStage.buttonText); setNextText(mUiStage.buttonText);
mPasswordEntryInputDisabler.setInputEnabled(canInput);
} }
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
@@ -671,5 +600,83 @@ public class ChooseLockPassword extends SettingsActivity {
public void onTextChanged(CharSequence s, int start, int before, int count) { public void onTextChanged(CharSequence s, int start, int before, int count) {
} }
private void startSaveAndFinish() {
if (mSaveAndFinishWorker != null) {
Log.w(TAG, "startSaveAndFinish with an existing SaveAndFinishWorker.");
return;
}
mPasswordEntryInputDisabler.setInputEnabled(false);
setNextEnabled(false);
mSaveAndFinishWorker = new SaveAndFinishWorker();
getFragmentManager().beginTransaction().add(mSaveAndFinishWorker,
FRAGMENT_TAG_SAVE_AND_FINISH).commit();
mSaveAndFinishWorker.setListener(this);
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
mSaveAndFinishWorker.start(mLockPatternUtils, required, mHasChallenge, mChallenge,
mChosenPassword, mCurrentPassword, mRequestedQuality);
}
@Override
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
getActivity().setResult(RESULT_FINISHED, resultData);
getActivity().finish();
if (!wasSecureBefore) {
Intent intent = getRedactionInterstitialIntent(getActivity());
if (intent != null) {
startActivity(intent);
}
}
}
}
private static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
private String mChosenPassword;
private String mCurrentPassword;
private int mRequestedQuality;
public void start(LockPatternUtils utils, boolean required,
boolean hasChallenge, long challenge,
String chosenPassword, String currentPassword, int requestedQuality) {
prepare(utils, required, hasChallenge, challenge);
mChosenPassword = chosenPassword;
mCurrentPassword = currentPassword;
mRequestedQuality = requestedQuality;
start();
}
@Override
protected Intent saveAndVerifyInBackground() {
Intent result = null;
final int userId = UserHandle.myUserId();
mUtils.saveLockPassword(mChosenPassword, mCurrentPassword, mRequestedQuality,
userId);
if (mHasChallenge) {
byte[] token;
try {
token = mUtils.verifyPassword(mChosenPassword, mChallenge, userId);
} catch (RequestThrottledException e) {
token = null;
}
if (token == null) {
Log.e(TAG, "critical: no token returned for known good password.");
}
result = new Intent();
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
}
return result;
}
} }
} }

View File

@@ -19,8 +19,8 @@ package com.android.settings;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.google.android.collect.Lists; import com.google.android.collect.Lists;
import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient; import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockPatternView;
import com.android.internal.widget.LockPatternView.Cell; import com.android.internal.widget.LockPatternView.Cell;
import com.android.settings.notification.RedactionInterstitial; import com.android.settings.notification.RedactionInterstitial;
@@ -31,7 +31,6 @@ import android.app.Activity;
import android.app.Fragment; import android.app.Fragment;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
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.Log;
@@ -125,7 +124,7 @@ public class ChooseLockPattern extends SettingsActivity {
} }
public static class ChooseLockPatternFragment extends InstrumentedFragment public static class ChooseLockPatternFragment extends InstrumentedFragment
implements View.OnClickListener { implements View.OnClickListener, SaveAndFinishWorker.Listener {
public static final int CONFIRM_EXISTING_REQUEST = 55; public static final int CONFIRM_EXISTING_REQUEST = 55;
@@ -137,6 +136,8 @@ public class ChooseLockPattern extends SettingsActivity {
private static final int ID_EMPTY_MESSAGE = -1; private static final int ID_EMPTY_MESSAGE = -1;
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
private String mCurrentPattern; private String mCurrentPattern;
private boolean mHasChallenge; private boolean mHasChallenge;
private long mChallenge; private long mChallenge;
@@ -354,7 +355,7 @@ public class ChooseLockPattern extends SettingsActivity {
}; };
private ChooseLockSettingsHelper mChooseLockSettingsHelper; private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private AsyncTask<?, ?, ?> mPendingLockCheck; private SaveAndFinishWorker mSaveAndFinishWorker;
private static final String KEY_UI_STAGE = "uiStage"; private static final String KEY_UI_STAGE = "uiStage";
private static final String KEY_PATTERN_CHOICE = "chosenPattern"; private static final String KEY_PATTERN_CHOICE = "chosenPattern";
@@ -433,21 +434,29 @@ public class ChooseLockPattern extends SettingsActivity {
mCurrentPattern = savedInstanceState.getString(KEY_CURRENT_PATTERN); mCurrentPattern = savedInstanceState.getString(KEY_CURRENT_PATTERN);
} }
updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]); updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
// Re-attach to the exiting worker if there is one.
mSaveAndFinishWorker = (SaveAndFinishWorker) getFragmentManager().findFragmentByTag(
FRAGMENT_TAG_SAVE_AND_FINISH);
} }
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (mSaveAndFinishWorker != null) {
setRightButtonEnabled(false);
mSaveAndFinishWorker.setListener(this);
} else {
mLockPatternView.enableInput(); mLockPatternView.enableInput();
} }
}
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
if (mPendingLockCheck != null) { if (mSaveAndFinishWorker != null) {
mPendingLockCheck.cancel(false); mSaveAndFinishWorker.setListener(null);
mPendingLockCheck = null;
} }
} }
@@ -481,7 +490,7 @@ public class ChooseLockPattern extends SettingsActivity {
throw new IllegalStateException("expected ui stage " + Stage.ChoiceConfirmed throw new IllegalStateException("expected ui stage " + Stage.ChoiceConfirmed
+ " when button is " + RightButtonMode.Confirm); + " when button is " + RightButtonMode.Confirm);
} }
new SaveChosenPatternAndFinish().execute(); startSaveAndFinish();
} else if (mUiStage.rightMode == RightButtonMode.Ok) { } else if (mUiStage.rightMode == RightButtonMode.Ok) {
if (mUiStage != Stage.HelpScreen) { if (mUiStage != Stage.HelpScreen) {
throw new IllegalStateException("Help screen is only mode with ok button, " throw new IllegalStateException("Help screen is only mode with ok button, "
@@ -568,7 +577,7 @@ public class ChooseLockPattern extends SettingsActivity {
setRightButtonText(stage.rightMode.text); setRightButtonText(stage.rightMode.text);
setRightButtonEnabled(stage.rightMode.enabled); setRightButtonEnabled(stage.rightMode.enabled);
// same for whether the patten is enabled // same for whether the pattern is enabled
if (stage.patternEnabled) { if (stage.patternEnabled) {
mLockPatternView.enableInput(); mLockPatternView.enableInput();
} else { } else {
@@ -613,7 +622,6 @@ public class ChooseLockPattern extends SettingsActivity {
} }
} }
// clear the wrong pattern unless they have started a new one // clear the wrong pattern unless they have started a new one
// already // already
private void postClearPatternRunnable() { private void postClearPatternRunnable() {
@@ -621,72 +629,29 @@ public class ChooseLockPattern extends SettingsActivity {
mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS); mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
} }
private class SaveChosenPatternAndFinish extends AsyncTask<Void,Void,Void> { private void startSaveAndFinish() {
boolean mLockVirgin; if (mSaveAndFinishWorker != null) {
LockPatternUtils mUtils; Log.w(TAG, "startSaveAndFinish with an existing SaveAndFinishWorker.");
boolean mWasSecureBefore; return;
}
@Override
protected void onPreExecute(){
setRightButtonEnabled(false); setRightButtonEnabled(false);
mUtils = mChooseLockSettingsHelper.utils();
mLockVirgin = !mUtils.isPatternEverChosen(UserHandle.myUserId());
mWasSecureBefore = mUtils.isSecure(UserHandle.myUserId()); mSaveAndFinishWorker = new SaveAndFinishWorker();
getFragmentManager().beginTransaction().add(mSaveAndFinishWorker,
FRAGMENT_TAG_SAVE_AND_FINISH).commit();
mSaveAndFinishWorker.setListener(this);
final boolean required = getActivity().getIntent().getBooleanExtra( final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
mSaveAndFinishWorker.start(mChooseLockSettingsHelper.utils(), required,
mUtils.setCredentialRequiredToDecrypt(required); mHasChallenge, mChallenge, mChosenPattern, mCurrentPattern);
} }
@Override @Override
protected Void doInBackground(Void... params){ public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
mUtils.saveLockPattern(mChosenPattern, mCurrentPattern, UserHandle.myUserId()); getActivity().setResult(RESULT_FINISHED, resultData);
return null; getActivity().finish();
}
@Override
protected void onPostExecute(Void param) {
if (mLockVirgin) {
mUtils.setVisiblePatternEnabled(true, UserHandle.myUserId());
}
if (mHasChallenge) {
startVerifyPattern(mUtils, mWasSecureBefore);
} else {
if (!mWasSecureBefore) {
Intent intent = getRedactionInterstitialIntent(getActivity());
if (intent != null) {
startActivity(intent);
}
}
getActivity().setResult(RESULT_FINISHED);
doFinish();
}
}
}
private void startVerifyPattern(LockPatternUtils utils, final boolean wasSecureBefore) {
mLockPatternView.disableInput();
if (mPendingLockCheck != null) {
mPendingLockCheck.cancel(false);
}
mPendingLockCheck = LockPatternChecker.verifyPattern(
utils,
mChosenPattern,
mChallenge,
UserHandle.myUserId(),
new LockPatternChecker.OnVerifyCallback() {
@Override
public void onVerified(byte[] token, int timeoutMs) {
if (token == null) {
Log.e(TAG, "critical: no token returned for known good pattern");
}
mLockPatternView.enableInput();
mPendingLockCheck = null;
if (!wasSecureBefore) { if (!wasSecureBefore) {
Intent intent = getRedactionInterstitialIntent(getActivity()); Intent intent = getRedactionInterstitialIntent(getActivity());
@@ -694,18 +659,60 @@ public class ChooseLockPattern extends SettingsActivity {
startActivity(intent); startActivity(intent);
} }
} }
Intent intent = new Intent();
intent.putExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
getActivity().setResult(RESULT_FINISHED, intent);
doFinish();
} }
});
} }
private void doFinish() { private static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
getActivity().finish();
private List<LockPatternView.Cell> mChosenPattern;
private String mCurrentPattern;
private boolean mLockVirgin;
public void start(LockPatternUtils utils, boolean credentialRequired,
boolean hasChallenge, long challenge,
List<LockPatternView.Cell> chosenPattern, String currentPattern) {
prepare(utils, credentialRequired, hasChallenge, challenge);
mCurrentPattern = currentPattern;
mChosenPattern = chosenPattern;
mLockVirgin = !mUtils.isPatternEverChosen(UserHandle.myUserId());
start();
}
@Override
protected Intent saveAndVerifyInBackground() {
Intent result = null;
final int userId = UserHandle.myUserId();
mUtils.saveLockPattern(mChosenPattern, mCurrentPattern, userId);
if (mHasChallenge) {
byte[] token;
try {
token = mUtils.verifyPattern(mChosenPattern, mChallenge, userId);
} catch (RequestThrottledException e) {
token = null;
}
if (token == null) {
Log.e(TAG, "critical: no token returned for known good pattern");
}
result = new Intent();
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
}
return result;
}
@Override
protected void finish(Intent resultData) {
if (mLockVirgin) {
mUtils.setVisiblePatternEnabled(true, UserHandle.myUserId());
}
super.finish(resultData);
} }
} }
} }

View File

@@ -0,0 +1,106 @@
/*
* 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;
import android.app.Fragment;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.UserHandle;
import com.android.internal.widget.LockPatternUtils;
/**
* 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 mHasChallenge;
protected long mChallenge;
protected boolean mWasSecureBefore;
@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 credentialRequired,
boolean hasChallenge, long challenge) {
mUtils = utils;
mHasChallenge = hasChallenge;
mChallenge = challenge;
mWasSecureBefore = mUtils.isSecure(UserHandle.myUserId());
mUtils.setCredentialRequiredToDecrypt(credentialRequired);
mFinished = false;
mResultData = null;
}
protected void start() {
new Task().execute();
}
/**
* Executes the save and verify work in background.
* @return Intent with challenge token or null.
*/
protected abstract Intent saveAndVerifyInBackground();
protected void finish(Intent resultData) {
mFinished = true;
mResultData = resultData;
if (mListener != null) {
mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData);
}
}
private class Task extends AsyncTask<Void, Void, Intent> {
@Override
protected Intent doInBackground(Void... params){
return saveAndVerifyInBackground();
}
@Override
protected void onPostExecute(Intent resultData) {
finish(resultData);
}
}
interface Listener {
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData);
}
}