diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 21b3fa4a5b3..f5374159df6 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2785,6 +2785,7 @@
+
-
+
+
-
-
-
\ No newline at end of file
+ android:pathData="M18.92,4.4L12.56,2.1C12.38,2.03 12.19,2 12,2C11.81,2 11.62,2.03 11.44,2.1L5.08,4.4C4.43,4.63 4,5.25 4,5.94V10.32C4.02,11.07 4.07,11.79 4.17,12.54C4.64,15.72 6.44,19.33 11.37,21.85C11.57,21.95 11.78,22 12,22C12.22,22 12.43,21.95 12.63,21.85C13.08,21.62 13.5,21.37 13.9,21.12C14.04,21.05 14.18,20.96 14.32,20.86C17.98,18.43 19.41,15.32 19.82,12.54C19.92,11.8 19.98,11.07 19.99,10.32V5.94C19.99,5.25 19.56,4.64 18.91,4.4H18.92ZM12.25,19.78C12.1,19.87 11.9,19.87 11.74,19.78C8.5,17.97 6.62,15.43 6.15,12.27C6.06,11.59 6.01,10.94 6,10.32V6.55C6,6.34 6.13,6.15 6.33,6.08L8.26,5.38C8.11,5.89 8.03,6.44 8.03,7.04C8.04,8.91 9.03,10.68 10.7,11.8C11.15,12.08 12.39,12.89 12.78,13.19C13.27,13.57 13.95,14.21 14.26,14.74C15.29,16.52 14.26,18.46 13.1,19.27C12.83,19.45 12.55,19.62 12.25,19.79V19.78ZM17.85,12.24C17.66,13.49 17.26,14.63 16.65,15.68C16.57,15.04 16.37,14.38 15.99,13.74C15.42,12.75 14.33,11.86 14.01,11.61C13.47,11.19 11.94,10.22 11.79,10.12C10.69,9.39 10.04,8.23 10.03,6.99C10.03,5.01 11.25,4.34 11.98,4.12C12.08,4.09 12.19,4.1 12.29,4.13L17.68,6.08C17.88,6.15 18.01,6.34 18.01,6.55V10.28C18,10.94 17.95,11.59 17.86,12.24H17.85Z"
+ android:fillColor="#000000"/>
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f47620c1466..dea4320fc22 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4946,6 +4946,8 @@
adjust color
turn screen dark, turn screen light
+
+ color contrast
@@ -12021,6 +12023,15 @@
Cancel
+
+ Contrast
+
+ Standard
+
+ Medium
+
+ High
+
"This app can only be opened in 1 window"
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 3b514b77f9e..9e1dbad8ba3 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -515,6 +515,12 @@
android:title="@string/transparent_navigation_bar"
android:summary="@string/transparent_navigation_bar_summary" />
+
+
{
if (hasAlternateButton) {
getActivity().setResult(KeyguardManager.RESULT_ALTERNATE);
+ getActivity().finish();
+ } else if (mRemoteValidation) {
+ onRemoteLockscreenValidationFailure("Forgot lockscreen credential button pressed.");
}
- getActivity().finish();
});
setupForgotButtonIfManagedProfile(view);
@@ -299,17 +309,11 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
if (mRemoteLockscreenValidationClient != null) {
mRemoteLockscreenValidationClient.disconnect();
}
- if (mDeviceCredentialGuess != null) {
- mDeviceCredentialGuess.zeroize();
- }
super.onDestroy();
}
protected abstract void authenticationSucceeded();
- protected abstract void onRemoteDeviceCredentialValidationResult(
- RemoteLockscreenValidationResult result);
-
public void prepareEnterAnimation() {
}
@@ -411,43 +415,33 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
}
protected void validateGuess(LockscreenCredential credentialGuess) {
- if (mCheckBox.isChecked()) {
- // Keep credential in memory since user wants to set guess as screen lock.
- mDeviceCredentialGuess = credentialGuess;
- } else if (mDeviceCredentialGuess != null) {
- mDeviceCredentialGuess.zeroize();
- }
-
- mRemoteLockscreenValidationClient.validateLockscreenGuess(
- encryptDeviceCredentialGuess(credentialGuess.getCredential()),
- new IRemoteLockscreenValidationCallback.Stub() {
- @Override
- public void onSuccess(RemoteLockscreenValidationResult result) {
- mHandler.post(()->onRemoteDeviceCredentialValidationResult(result));
- }
-
- @Override
- public void onFailure(String message) {
- Log.e(TAG, "A failure occurred while trying "
- + "to validate lockscreen guess: " + message);
- mHandler.post(()->getActivity().finish());
- }
- });
+ mRemoteLockscreenValidationFragment.validateLockscreenGuess(
+ mRemoteLockscreenValidationClient, credentialGuess,
+ mRemoteLockscreenValidationSession.getSourcePublicKey(), mCheckBox.isChecked());
}
- private byte[] encryptDeviceCredentialGuess(byte[] guess) {
- try {
- byte[] encodedPublicKey = mRemoteLockscreenValidationSession.getSourcePublicKey();
- PublicKey publicKey = SecureBox.decodePublicKey(encodedPublicKey);
- return SecureBox.encrypt(
- publicKey,
- /* sharedSecret= */ null,
- LockPatternUtils.ENCRYPTED_REMOTE_CREDENTIALS_HEADER,
- guess);
- } catch (NoSuchAlgorithmException | InvalidKeyException e) {
- Log.w(TAG, "Error encrypting device credential guess. Returning empty byte[].", e);
- return new byte[0];
+ protected void updateRemoteLockscreenValidationViews() {
+ if (!mRemoteValidation || mRemoteLockscreenValidationFragment == null) {
+ return;
}
+
+ boolean enable = mRemoteLockscreenValidationFragment.isRemoteValidationInProgress();
+ mGlifLayout.setProgressBarShown(enable);
+ mCheckBox.setEnabled(!enable);
+ mCancelButton.setEnabled(!enable);
+ }
+
+ /**
+ * Finishes the activity with result code {@link android.app.Activity#RESULT_FIRST_USER}
+ * after logging the error message.
+ * @param message Optional message to log.
+ */
+ public void onRemoteLockscreenValidationFailure(String message) {
+ if (!TextUtils.isEmpty(message)) {
+ Log.w(TAG, message);
+ }
+ getActivity().setResult(RESULT_FIRST_USER);
+ getActivity().finish();
}
protected abstract void onShowError();
diff --git a/src/com/android/settings/password/ConfirmLockPassword.java b/src/com/android/settings/password/ConfirmLockPassword.java
index 81bd8c231a6..03b89f25051 100644
--- a/src/com/android/settings/password/ConfirmLockPassword.java
+++ b/src/com/android/settings/password/ConfirmLockPassword.java
@@ -71,8 +71,6 @@ import com.android.settings.R;
import com.android.settingslib.animation.AppearAnimationUtils;
import com.android.settingslib.animation.DisappearAnimationUtils;
-import com.google.android.setupdesign.GlifLayout;
-
import java.util.ArrayList;
public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
@@ -127,7 +125,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
public static class ConfirmLockPasswordFragment extends ConfirmDeviceCredentialBaseFragment
implements OnClickListener, OnEditorActionListener,
- CredentialCheckResultTracker.Listener, SaveChosenLockWorkerBase.Listener {
+ CredentialCheckResultTracker.Listener, SaveChosenLockWorkerBase.Listener,
+ RemoteLockscreenValidationFragment.Listener {
private static final String FRAGMENT_TAG_CHECK_LOCK_RESULT = "check_lock_result";
private ImeAwareEditText mPasswordEntry;
private TextViewInputDisabler mPasswordEntryInputDisabler;
@@ -140,7 +139,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
private AppearAnimationUtils mAppearAnimationUtils;
private DisappearAnimationUtils mDisappearAnimationUtils;
private boolean mIsManagedProfile;
- private GlifLayout mGlifLayout;
private CharSequence mCheckBoxLabel;
// required constructor for fragments
@@ -255,6 +253,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
? R.string.lockpassword_forgot_password
: R.string.lockpassword_forgot_pin);
}
+ updateRemoteLockscreenValidationViews();
}
if (mForgotButton != null) {
@@ -405,6 +404,9 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
mCountdownTimer = null;
}
mCredentialCheckResultTracker.setListener(null);
+ if (mRemoteLockscreenValidationFragment != null) {
+ mRemoteLockscreenValidationFragment.setListener(null, /* handler= */ null);
+ }
}
@Override
@@ -426,6 +428,9 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId));
}
mCredentialCheckResultTracker.setListener(this);
+ if (mRemoteLockscreenValidationFragment != null) {
+ mRemoteLockscreenValidationFragment.setListener(this, mHandler);
+ }
}
@Override
@@ -436,13 +441,17 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
private void updatePasswordEntry() {
final boolean isLockedOut =
mLockPatternUtils.getLockoutAttemptDeadline(mEffectiveUserId) != 0;
- mPasswordEntry.setEnabled(!isLockedOut);
- mPasswordEntryInputDisabler.setInputEnabled(!isLockedOut);
- if (isLockedOut) {
- mImm.hideSoftInputFromWindow(mPasswordEntry.getWindowToken(), 0 /*flags*/);
- } else {
+ final boolean isRemoteLockscreenValidationInProgress =
+ mRemoteLockscreenValidationFragment != null
+ && mRemoteLockscreenValidationFragment.isRemoteValidationInProgress();
+ boolean shouldEnableInput = !isLockedOut && !isRemoteLockscreenValidationInProgress;
+ mPasswordEntry.setEnabled(shouldEnableInput);
+ mPasswordEntryInputDisabler.setInputEnabled(shouldEnableInput);
+ if (shouldEnableInput) {
mPasswordEntry.scheduleShowSoftInput();
mPasswordEntry.requestFocus();
+ } else {
+ mImm.hideSoftInputFromWindow(mPasswordEntry.getWindowToken(), /* flags= */0);
}
}
@@ -472,7 +481,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
if (mRemoteValidation) {
validateGuess(credential);
- mGlifLayout.setProgressBarShown(true);
+ updateRemoteLockscreenValidationViews();
+ updatePasswordEntry();
return;
}
@@ -604,14 +614,15 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
}
@Override
- protected void onRemoteDeviceCredentialValidationResult(
+ public void onRemoteLockscreenValidationResult(
RemoteLockscreenValidationResult result) {
switch (result.getResultCode()) {
case RemoteLockscreenValidationResult.RESULT_GUESS_VALID:
- if (mCheckBox.isChecked()) {
+ 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();
- Log.i(TAG, "Setting device screen lock to the other device's screen lock.");
getFragmentManager().beginTransaction().add(saveAndFinishWorker, null)
.commit();
getFragmentManager().executePendingTransactions();
@@ -619,14 +630,14 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
saveAndFinishWorker.start(
mLockPatternUtils,
/* requestGatekeeperPassword= */ true,
- mDeviceCredentialGuess,
+ mRemoteLockscreenValidationFragment.getLockscreenCredential(),
/* currentCredential= */ null,
mEffectiveUserId);
- return;
+ } else {
+ mCredentialCheckResultTracker.setResult(/* matched= */ true, new Intent(),
+ /* timeoutMs= */ 0, mEffectiveUserId);
}
- mCredentialCheckResultTracker.setResult(/* matched= */ true, new Intent(),
- /* timeoutMs= */ 0, mEffectiveUserId);
- break;
+ return;
case RemoteLockscreenValidationResult.RESULT_GUESS_INVALID:
mCredentialCheckResultTracker.setResult(/* matched= */ false, new Intent(),
/* timeoutMs= */ 0, mEffectiveUserId);
@@ -636,12 +647,15 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
(int) result.getTimeoutMillis(), mEffectiveUserId);
break;
case RemoteLockscreenValidationResult.RESULT_NO_REMAINING_ATTEMPTS:
- getActivity().finish();
- break;
case RemoteLockscreenValidationResult.RESULT_SESSION_EXPIRED:
- getActivity().finish();
+ onRemoteLockscreenValidationFailure(String.format(
+ "Cannot continue remote lockscreen validation. ResultCode=%d",
+ result.getResultCode()));
+ break;
}
- mGlifLayout.setProgressBarShown(false);
+ updateRemoteLockscreenValidationViews();
+ updatePasswordEntry();
+ mRemoteLockscreenValidationFragment.clearLockscreenCredential();
}
@Override
@@ -701,21 +715,18 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
}
/**
- * Callback for when the device credential guess used for remote validation was set as the
- * current device's device credential.
+ * Callback for when the current device's lockscreen was set to the guess used for
+ * remote lockscreen validation.
*/
@Override
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
- if (mDeviceCredentialGuess != null) {
- mDeviceCredentialGuess.zeroize();
- }
+ Log.i(TAG, "Device lockscreen has been set to remote device's lockscreen.");
+ mRemoteLockscreenValidationFragment.clearLockscreenCredential();
Intent result = new Intent();
if (mRemoteValidation && containsGatekeeperPasswordHandle(resultData)) {
result.putExtra(EXTRA_KEY_GK_PW_HANDLE, getGatekeeperPasswordHandle(resultData));
}
-
- mGlifLayout.setProgressBarShown(false);
mCredentialCheckResultTracker.setResult(/* matched= */ true, result,
/* timeoutMs= */ 0, mEffectiveUserId);
}
diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java
index 7c217399cd5..7db25fd830f 100644
--- a/src/com/android/settings/password/ConfirmLockPattern.java
+++ b/src/com/android/settings/password/ConfirmLockPattern.java
@@ -59,8 +59,6 @@ import com.android.settingslib.animation.AppearAnimationCreator;
import com.android.settingslib.animation.AppearAnimationUtils;
import com.android.settingslib.animation.DisappearAnimationUtils;
-import com.google.android.setupdesign.GlifLayout;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -97,7 +95,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
public static class ConfirmLockPatternFragment extends ConfirmDeviceCredentialBaseFragment
implements AppearAnimationCreator