Merge \"Improve initial unlock delay (1/2)\" into nyc-mr1-dev

am: 165b011a74

Change-Id: Ib7bfefcd59288d144a22434e5a99124c66fa4826
This commit is contained in:
Jorim Jaggi
2016-07-08 22:08:37 +00:00
committed by android-build-merger
13 changed files with 252 additions and 66 deletions

View File

@@ -343,6 +343,7 @@ LOCAL_SRC_FILES += \
core/java/com/android/internal/view/IInputMethodManager.aidl \
core/java/com/android/internal/view/IInputMethodSession.aidl \
core/java/com/android/internal/view/IInputSessionCallback.aidl \
core/java/com/android/internal/widget/ICheckCredentialProgressCallback.aidl \
core/java/com/android/internal/widget/ILockSettings.aidl \
core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \
core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \

View File

@@ -0,0 +1,22 @@
/*
* Copyright (C) 2016 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.internal.widget;
/** {@hide} */
oneway interface ICheckCredentialProgressCallback {
void onCredentialVerified();
}

View File

@@ -17,6 +17,7 @@
package com.android.internal.widget;
import android.app.trust.IStrongAuthTracker;
import com.android.internal.widget.ICheckCredentialProgressCallback;
import com.android.internal.widget.VerifyCredentialResponse;
/** {@hide} */
@@ -29,10 +30,12 @@ interface ILockSettings {
String getString(in String key, in String defaultValue, in int userId);
void setLockPattern(in String pattern, in String savedPattern, int userId);
void resetKeyStore(int userId);
VerifyCredentialResponse checkPattern(in String pattern, int userId);
VerifyCredentialResponse checkPattern(in String pattern, int userId,
in ICheckCredentialProgressCallback progressCallback);
VerifyCredentialResponse verifyPattern(in String pattern, long challenge, int userId);
void setLockPassword(in String password, in String savedPassword, int userId);
VerifyCredentialResponse checkPassword(in String password, int userId);
VerifyCredentialResponse checkPassword(in String password, int userId,
in ICheckCredentialProgressCallback progressCallback);
VerifyCredentialResponse verifyPassword(in String password, long challenge, int userId);
VerifyCredentialResponse verifyTiedProfileChallenge(String password, boolean isPattern, long challenge, int userId);
boolean checkVoldPassword(int userId);

View File

@@ -14,6 +14,13 @@ public final class LockPatternChecker {
* Interface for a callback to be invoked after security check.
*/
public interface OnCheckCallback {
/**
* Invoked as soon as possible we know that the credentials match. This will be called
* earlier than {@link #onChecked} but only if the credentials match.
*/
default void onEarlyMatched() {}
/**
* Invoked when a security check is finished.
*
@@ -92,7 +99,7 @@ public final class LockPatternChecker {
@Override
protected Boolean doInBackground(Void... args) {
try {
return utils.checkPattern(pattern, userId);
return utils.checkPattern(pattern, userId, callback::onEarlyMatched);
} catch (RequestThrottledException ex) {
mThrottleTimeout = ex.getTimeoutMs();
return false;
@@ -199,7 +206,7 @@ public final class LockPatternChecker {
@Override
protected Boolean doInBackground(Void... args) {
try {
return utils.checkPassword(password, userId);
return utils.checkPassword(password, userId, callback::onEarlyMatched);
} catch (RequestThrottledException ex) {
mThrottleTimeout = ex.getTimeoutMs();
return false;

View File

@@ -17,6 +17,7 @@
package com.android.internal.widget;
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
import android.app.trust.IStrongAuthTracker;
import android.app.trust.TrustManager;
@@ -32,7 +33,6 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.IMountService;
@@ -149,6 +149,7 @@ public class LockPatternUtils {
private DevicePolicyManager mDevicePolicyManager;
private ILockSettings mLockSettingsService;
private UserManager mUserManager;
private final Handler mHandler = new Handler();
/**
* Use {@link TrustManager#isTrustUsuallyManaged(int)}.
@@ -341,10 +342,23 @@ public class LockPatternUtils {
*/
public boolean checkPattern(List<LockPatternView.Cell> pattern, int userId)
throws RequestThrottledException {
return checkPattern(pattern, userId, null /* progressCallback */);
}
/**
* Check to see if a pattern matches the saved pattern. If no pattern exists,
* always returns true.
* @param pattern The pattern to check.
* @return Whether the pattern matches the stored one.
*/
public boolean checkPattern(List<LockPatternView.Cell> pattern, int userId,
@Nullable CheckCredentialProgressCallback progressCallback)
throws RequestThrottledException {
throwIfCalledOnMainThread();
try {
VerifyCredentialResponse response =
getLockSettings().checkPattern(patternToString(pattern), userId);
getLockSettings().checkPattern(patternToString(pattern), userId,
wrapCallback(progressCallback));
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
return true;
@@ -423,10 +437,22 @@ public class LockPatternUtils {
* @return Whether the password matches the stored one.
*/
public boolean checkPassword(String password, int userId) throws RequestThrottledException {
return checkPassword(password, userId, null /* progressCallback */);
}
/**
* Check to see if a password matches the saved password. If no password exists,
* always returns true.
* @param password The password to check.
* @return Whether the password matches the stored one.
*/
public boolean checkPassword(String password, int userId,
@Nullable CheckCredentialProgressCallback progressCallback)
throws RequestThrottledException {
throwIfCalledOnMainThread();
try {
VerifyCredentialResponse response =
getLockSettings().checkPassword(password, userId);
getLockSettings().checkPassword(password, userId, wrapCallback(progressCallback));
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
return true;
} else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
@@ -1475,6 +1501,33 @@ public class LockPatternUtils {
return (getStrongAuthForUser(userId) & ~StrongAuthTracker.ALLOWING_FINGERPRINT) == 0;
}
private ICheckCredentialProgressCallback wrapCallback(
final CheckCredentialProgressCallback callback) {
if (callback == null) {
return null;
} else {
return new ICheckCredentialProgressCallback.Stub() {
@Override
public void onCredentialVerified() throws RemoteException {
mHandler.post(callback::onEarlyMatched);
}
};
}
}
/**
* Callback to be notified about progress when checking credentials.
*/
public interface CheckCredentialProgressCallback {
/**
* Called as soon as possible when we know that the credentials match but the user hasn't
* been fully unlocked.
*/
void onEarlyMatched();
}
/**
* Tracks the global strong authentication state.
*/

View File

@@ -137,12 +137,21 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
entry,
userId,
new LockPatternChecker.OnCheckCallback() {
@Override
public void onEarlyMatched() {
onPasswordChecked(userId, true /* matched */, 0 /* timeoutMs */,
true /* isValidPassword */);
}
@Override
public void onChecked(boolean matched, int timeoutMs) {
setPasswordEntryInputEnabled(true);
mPendingLockCheck = null;
onPasswordChecked(userId, matched, timeoutMs,
true /* isValidPassword */);
if (!matched) {
onPasswordChecked(userId, false /* matched */, timeoutMs,
true /* isValidPassword */);
}
}
});
}

View File

@@ -36,6 +36,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
private final AppearAnimationUtils mAppearAnimationUtils;
private final DisappearAnimationUtils mDisappearAnimationUtils;
private final DisappearAnimationUtils mDisappearAnimationUtilsLocked;
private ViewGroup mContainer;
private ViewGroup mRow0;
private ViewGroup mRow1;
@@ -44,6 +45,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
private View mDivider;
private int mDisappearYTranslation;
private View[][] mViews;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
public KeyguardPINView(Context context) {
this(context, null);
@@ -56,8 +58,14 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
125, 0.6f /* translationScale */,
0.45f /* delayScale */, AnimationUtils.loadInterpolator(
mContext, android.R.interpolator.fast_out_linear_in));
mDisappearAnimationUtilsLocked = new DisappearAnimationUtils(context,
(long) (125 * KeyguardPatternView.DISAPPEAR_MULTIPLIER_LOCKED),
0.6f /* translationScale */,
0.45f /* delayScale */, AnimationUtils.loadInterpolator(
mContext, android.R.interpolator.fast_out_linear_in));
mDisappearYTranslation = getResources().getDimensionPixelSize(
R.dimen.disappear_y_translation);
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
}
@Override
@@ -136,7 +144,10 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
setTranslationY(0);
AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 280 /* duration */,
mDisappearYTranslation, mDisappearAnimationUtils.getInterpolator());
mDisappearAnimationUtils.startAnimation2d(mViews,
DisappearAnimationUtils disappearAnimationUtils = mKeyguardUpdateMonitor.isUserUnlocked()
? mDisappearAnimationUtils
: mDisappearAnimationUtilsLocked;
disappearAnimationUtils.startAnimation2d(mViews,
new Runnable() {
@Override
public void run() {

View File

@@ -55,9 +55,13 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
// how many cells the user has to cross before we poke the wakelock
private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2;
// How much we scale up the duration of the disappear animation when the current user is locked
public static final float DISAPPEAR_MULTIPLIER_LOCKED = 1.5f;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final AppearAnimationUtils mAppearAnimationUtils;
private final DisappearAnimationUtils mDisappearAnimationUtils;
private final DisappearAnimationUtils mDisappearAnimationUtilsLocked;
private CountDownTimer mCountdownTimer = null;
private LockPatternUtils mLockPatternUtils;
@@ -109,6 +113,10 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
125, 1.2f /* translationScale */,
0.6f /* delayScale */, AnimationUtils.loadInterpolator(
mContext, android.R.interpolator.fast_out_linear_in));
mDisappearAnimationUtilsLocked = new DisappearAnimationUtils(context,
(long) (125 * DISAPPEAR_MULTIPLIER_LOCKED), 1.2f /* translationScale */,
0.6f /* delayScale */, AnimationUtils.loadInterpolator(
mContext, android.R.interpolator.fast_out_linear_in));
mDisappearYTranslation = getResources().getDimensionPixelSize(
R.dimen.disappear_y_translation);
}
@@ -239,11 +247,21 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
pattern,
userId,
new LockPatternChecker.OnCheckCallback() {
@Override
public void onEarlyMatched() {
onPatternChecked(userId, true /* matched */, 0 /* timeoutMs */,
true /* isValidPattern */);
}
@Override
public void onChecked(boolean matched, int timeoutMs) {
mLockPatternView.enableInput();
mPendingLockCheck = null;
onPatternChecked(userId, matched, timeoutMs, true);
if (!matched) {
onPatternChecked(userId, false /* matched */, timeoutMs,
true /* isValidPattern */);
}
}
});
if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
@@ -390,25 +408,30 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
@Override
public boolean startDisappearAnimation(final Runnable finishRunnable) {
float durationMultiplier = mKeyguardUpdateMonitor.isUserUnlocked()
? 1f
: DISAPPEAR_MULTIPLIER_LOCKED;
mLockPatternView.clearPattern();
enableClipping(false);
setTranslationY(0);
AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 300 /* duration */,
AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */,
(long) (300 * durationMultiplier),
-mDisappearAnimationUtils.getStartTranslation(),
mDisappearAnimationUtils.getInterpolator());
mDisappearAnimationUtils.startAnimation2d(mLockPatternView.getCellStates(),
new Runnable() {
@Override
public void run() {
enableClipping(true);
if (finishRunnable != null) {
finishRunnable.run();
}
DisappearAnimationUtils disappearAnimationUtils = mKeyguardUpdateMonitor.isUserUnlocked()
? mDisappearAnimationUtils
: mDisappearAnimationUtilsLocked;
disappearAnimationUtils.startAnimation2d(mLockPatternView.getCellStates(),
() -> {
enableClipping(true);
if (finishRunnable != null) {
finishRunnable.run();
}
}, KeyguardPatternView.this);
if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
mDisappearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
200,
(long) (200 * durationMultiplier),
- mDisappearAnimationUtils.getStartTranslation() * 3,
false /* appearing */,
mDisappearAnimationUtils.getInterpolator(),

View File

@@ -16,6 +16,16 @@
package com.android.keyguard;
import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
import static android.os.BatteryManager.EXTRA_HEALTH;
import static android.os.BatteryManager.EXTRA_LEVEL;
import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static android.os.BatteryManager.EXTRA_STATUS;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
@@ -29,7 +39,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
@@ -42,6 +51,7 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
@@ -69,16 +79,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
import static android.os.BatteryManager.EXTRA_HEALTH;
import static android.os.BatteryManager.EXTRA_LEVEL;
import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static android.os.BatteryManager.EXTRA_STATUS;
/**
* Watches for updates that may be interesting to the keyguard, and provides
* the up to date information as well as a registration for callbacks that care
@@ -176,6 +176,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private boolean mGoingToSleep;
private boolean mBouncer;
private boolean mBootCompleted;
private boolean mUserUnlocked;
// Device provisioning state
private boolean mDeviceProvisioned;
@@ -202,6 +203,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private AlarmManager mAlarmManager;
private List<SubscriptionInfo> mSubscriptionInfo;
private TrustManager mTrustManager;
private UserManager mUserManager;
private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
private final Handler mHandler = new Handler() {
@@ -554,6 +556,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
&& !hasFingerprintUnlockTimedOut(sCurrentUser);
}
public boolean isUserUnlocked() {
return mUserUnlocked;
}
public StrongAuthTracker getStrongAuthTracker() {
return mStrongAuthTracker;
}
@@ -1058,6 +1064,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
if (mFpm != null) {
mFpm.addLockoutResetCallback(mLockoutResetCallback);
}
mUserManager = context.getSystemService(UserManager.class);
}
private void updateFingerprintListeningState() {
@@ -1390,6 +1398,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private void handleKeyguardReset() {
if (DEBUG) Log.d(TAG, "handleKeyguardReset");
updateFingerprintListeningState();
mUserUnlocked = mUserManager.isUserUnlocked(getCurrentUser());
}
/**

View File

@@ -234,7 +234,6 @@ public class KeyguardBouncer {
mKeyguardView.setViewMediatorCallback(mCallback);
mContainer.addView(mRoot, mContainer.getChildCount());
mRoot.setVisibility(View.INVISIBLE);
mRoot.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
}
protected void removeView() {

View File

@@ -30,6 +30,7 @@ import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationData;
@@ -46,10 +47,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
public static final long ANIMATION_DURATION = 220;
public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR
= new PathInterpolator(0f, 0, 0.7f, 1f);
public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED
= new PathInterpolator(0.3f, 0f, 0.8f, 1f);
private static final float SCRIM_BEHIND_ALPHA = 0.62f;
private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
private static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = 0.85f;
private static final int TAG_KEY_ANIM = R.id.scrim;
private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
@@ -59,6 +63,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
private final ScrimView mScrimInFront;
private final UnlockMethodCache mUnlockMethodCache;
private final View mHeadsUpScrim;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private float mScrimBehindAlpha = SCRIM_BEHIND_ALPHA;
private float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
@@ -99,6 +104,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
mHeadsUpScrim = headsUpScrim;
final Context context = scrimBehind.getContext();
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
updateHeadsUpScrim(false);
}
@@ -162,11 +168,19 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
mAnimateChange = true;
mSkipFirstFrame = skipFirstFrame;
mOnAnimationFinished = onAnimationFinished;
scheduleUpdate();
// No need to wait for the next frame to be drawn for this case - onPreDraw will execute
// the changes we just scheduled.
onPreDraw();
if (mKeyguardUpdateMonitor.isUserUnlocked()) {
scheduleUpdate();
// No need to wait for the next frame to be drawn for this case - onPreDraw will execute
// the changes we just scheduled.
onPreDraw();
} else {
// In case the user isn't unlocked, make sure to delay a bit because the system is hosed
// with too many things in this case, in order to not skip the initial frames.
mScrimInFront.postOnAnimationDelayed(this::scheduleUpdate, 16);
}
}
public void abortKeyguardFadingOut() {
@@ -211,6 +225,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
return mDozeInFrontAlpha;
}
private float getScrimInFrontAlpha() {
return mKeyguardUpdateMonitor.isUserUnlocked()
? SCRIM_IN_FRONT_ALPHA
: SCRIM_IN_FRONT_ALPHA_LOCKED;
}
private void scheduleUpdate() {
if (mUpdatePending) return;
@@ -250,10 +269,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
float fraction = 1 - behindFraction;
fraction = (float) Math.pow(fraction, 0.8f);
behindFraction = (float) Math.pow(behindFraction, 0.8f);
setScrimInFrontColor(fraction * SCRIM_IN_FRONT_ALPHA);
setScrimInFrontColor(fraction * getScrimInFrontAlpha());
setScrimBehindColor(behindFraction * mScrimBehindAlphaKeyguard);
} else if (mBouncerShowing) {
setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA);
setScrimInFrontColor(getScrimInFrontAlpha());
setScrimBehindColor(0f);
} else {
float fraction = Math.max(0, Math.min(mFraction, 1));
@@ -371,7 +390,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
private Interpolator getInterpolator() {
return mAnimateKeyguardFadingOut ? KEYGUARD_FADE_OUT_INTERPOLATOR : mInterpolator;
if (mAnimateKeyguardFadingOut && !mKeyguardUpdateMonitor.isUserUnlocked()) {
return KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED;
} else if (mAnimateKeyguardFadingOut) {
return KEYGUARD_FADE_OUT_INTERPOLATOR;
} else {
return mInterpolator;
}
}
@Override

View File

@@ -53,6 +53,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private static final long WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS = 200;
// Duration of the Keyguard dismissal animation in case the user is currently locked. This is to
// make everything a bit slower to bridge a gap until the user is unlocked and home screen has
// dranw its first frame.
private static final long KEYGUARD_DISMISS_DURATION_LOCKED = 2000;
private static String TAG = "StatusBarKeyguardViewManager";
protected final Context mContext;
@@ -274,9 +279,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
/**
* Hides the keyguard view
*/
public void hide(long startTime, final long fadeoutDuration) {
public void hide(long startTime, long fadeoutDuration) {
mShowing = false;
if (!KeyguardUpdateMonitor.getInstance(mContext).isUserUnlocked()) {
fadeoutDuration = KEYGUARD_DISMISS_DURATION_LOCKED;
}
long uptimeMillis = SystemClock.uptimeMillis();
long delay = Math.max(0, startTime + HIDE_TIMING_CORRECTION_MS - uptimeMillis);

View File

@@ -69,6 +69,7 @@ import android.util.Log;
import android.util.Slog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.ICheckCredentialProgressCallback;
import com.android.internal.widget.ILockSettings;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.VerifyCredentialResponse;
@@ -760,7 +761,7 @@ public class LockSettingsService extends ILockSettings.Stub {
private void unlockChildProfile(int profileHandle) throws RemoteException {
try {
doVerifyPassword(getDecryptedPasswordForTiedProfile(profileHandle), false,
0 /* no challenge */, profileHandle);
0 /* no challenge */, profileHandle, null /* progressCallback */);
} catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
| NoSuchAlgorithmException | NoSuchPaddingException
| InvalidAlgorithmParameterException | IllegalBlockSizeException
@@ -947,7 +948,7 @@ public class LockSettingsService extends ILockSettings.Stub {
CredentialHash willStore
= new CredentialHash(enrolledHandle, CredentialHash.VERSION_GATEKEEPER);
setUserKeyProtection(userId, pattern,
doVerifyPattern(pattern, willStore, true, 0, userId));
doVerifyPattern(pattern, willStore, true, 0, userId, null /* progressCallback */));
mStorage.writePatternHash(enrolledHandle, userId);
fixateNewestUserKeyAuth(userId);
onUserLockChanged(userId);
@@ -1007,7 +1008,8 @@ public class LockSettingsService extends ILockSettings.Stub {
CredentialHash willStore
= new CredentialHash(enrolledHandle, CredentialHash.VERSION_GATEKEEPER);
setUserKeyProtection(userId, password,
doVerifyPassword(password, willStore, true, 0, userId));
doVerifyPassword(password, willStore, true, 0, userId,
null /* progressCallback */));
mStorage.writePasswordHash(enrolledHandle, userId);
fixateNewestUserKeyAuth(userId);
onUserLockChanged(userId);
@@ -1205,25 +1207,29 @@ public class LockSettingsService extends ILockSettings.Stub {
}
@Override
public VerifyCredentialResponse checkPattern(String pattern, int userId) throws RemoteException {
return doVerifyPattern(pattern, false, 0, userId);
public VerifyCredentialResponse checkPattern(String pattern, int userId,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
return doVerifyPattern(pattern, false, 0, userId, progressCallback);
}
@Override
public VerifyCredentialResponse verifyPattern(String pattern, long challenge, int userId)
throws RemoteException {
return doVerifyPattern(pattern, true, challenge, userId);
return doVerifyPattern(pattern, true, challenge, userId, null /* progressCallback */);
}
private VerifyCredentialResponse doVerifyPattern(String pattern, boolean hasChallenge,
long challenge, int userId) throws RemoteException {
long challenge, int userId, ICheckCredentialProgressCallback progressCallback)
throws RemoteException {
checkPasswordReadPermission(userId);
CredentialHash storedHash = mStorage.readPatternHash(userId);
return doVerifyPattern(pattern, storedHash, hasChallenge, challenge, userId);
return doVerifyPattern(pattern, storedHash, hasChallenge, challenge, userId,
progressCallback);
}
private VerifyCredentialResponse doVerifyPattern(String pattern, CredentialHash storedHash,
boolean hasChallenge, long challenge, int userId) throws RemoteException {
boolean hasChallenge, long challenge, int userId,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
boolean shouldReEnrollBaseZero = storedHash != null && storedHash.isBaseZeroPattern;
String patternToVerify;
@@ -1252,7 +1258,8 @@ public class LockSettingsService extends ILockSettings.Stub {
public String adjustForKeystore(String pattern) {
return LockPatternUtils.patternStringToBaseZero(pattern);
}
}
},
progressCallback
);
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK
@@ -1264,15 +1271,15 @@ public class LockSettingsService extends ILockSettings.Stub {
}
@Override
public VerifyCredentialResponse checkPassword(String password, int userId)
throws RemoteException {
return doVerifyPassword(password, false, 0, userId);
public VerifyCredentialResponse checkPassword(String password, int userId,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
return doVerifyPassword(password, false, 0, userId, progressCallback);
}
@Override
public VerifyCredentialResponse verifyPassword(String password, long challenge, int userId)
throws RemoteException {
return doVerifyPassword(password, true, challenge, userId);
return doVerifyPassword(password, true, challenge, userId, null /* progressCallback */);
}
@Override
@@ -1285,8 +1292,10 @@ public class LockSettingsService extends ILockSettings.Stub {
final int parentProfileId = mUserManager.getProfileParent(userId).id;
// Unlock parent by using parent's challenge
final VerifyCredentialResponse parentResponse = isPattern
? doVerifyPattern(password, true, challenge, parentProfileId)
: doVerifyPassword(password, true, challenge, parentProfileId);
? doVerifyPattern(password, true, challenge, parentProfileId,
null /* progressCallback */)
: doVerifyPassword(password, true, challenge, parentProfileId,
null /* progressCallback */);
if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
// Failed, just return parent's response
return parentResponse;
@@ -1296,7 +1305,7 @@ public class LockSettingsService extends ILockSettings.Stub {
// Unlock work profile, and work profile with unified lock must use password only
return doVerifyPassword(getDecryptedPasswordForTiedProfile(userId), true,
challenge,
userId);
userId, null /* progressCallback */);
} catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
| NoSuchAlgorithmException | NoSuchPaddingException
| InvalidAlgorithmParameterException | IllegalBlockSizeException
@@ -1307,14 +1316,17 @@ public class LockSettingsService extends ILockSettings.Stub {
}
private VerifyCredentialResponse doVerifyPassword(String password, boolean hasChallenge,
long challenge, int userId) throws RemoteException {
long challenge, int userId, ICheckCredentialProgressCallback progressCallback)
throws RemoteException {
checkPasswordReadPermission(userId);
CredentialHash storedHash = mStorage.readPasswordHash(userId);
return doVerifyPassword(password, storedHash, hasChallenge, challenge, userId);
return doVerifyPassword(password, storedHash, hasChallenge, challenge, userId,
progressCallback);
}
private VerifyCredentialResponse doVerifyPassword(String password, CredentialHash storedHash,
boolean hasChallenge, long challenge, int userId) throws RemoteException {
boolean hasChallenge, long challenge, int userId,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
return verifyCredential(userId, storedHash, password, hasChallenge, challenge,
new CredentialUtil() {
@Override
@@ -1332,12 +1344,12 @@ public class LockSettingsService extends ILockSettings.Stub {
public String adjustForKeystore(String password) {
return password;
}
}
);
}, progressCallback);
}
private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash,
String credential, boolean hasChallenge, long challenge, CredentialUtil credentialUtil)
String credential, boolean hasChallenge, long challenge, CredentialUtil credentialUtil,
ICheckCredentialProgressCallback progressCallback)
throws RemoteException {
if ((storedHash == null || storedHash.hash.length == 0) && TextUtils.isEmpty(credential)) {
// don't need to pass empty credentials to GateKeeper
@@ -1395,6 +1407,10 @@ public class LockSettingsService extends ILockSettings.Stub {
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
// credential has matched
if (progressCallback != null) {
progressCallback.onCredentialVerified();
}
unlockKeystore(credential, userId);
Slog.i(TAG, "Unlocking user " + userId +
@@ -1450,7 +1466,7 @@ public class LockSettingsService extends ILockSettings.Stub {
try {
if (mLockPatternUtils.isLockPatternEnabled(userId)) {
if (checkPattern(password, userId).getResponseCode()
if (checkPattern(password, userId, null /* progressCallback */).getResponseCode()
== GateKeeperResponse.RESPONSE_OK) {
return true;
}
@@ -1460,7 +1476,7 @@ public class LockSettingsService extends ILockSettings.Stub {
try {
if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
if (checkPassword(password, userId).getResponseCode()
if (checkPassword(password, userId, null /* progressCallback */).getResponseCode()
== GateKeeperResponse.RESPONSE_OK) {
return true;
}