resolve merge conflicts of 0483184 to master
Change-Id: I8466c8d56b5685705591dad7cfb7d439b6dee3d7
diff --git a/Android.mk b/Android.mk
index 9513c3e..584e4d1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -343,6 +343,7 @@
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 \
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index a0762b9..9cd70e6 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -72,7 +72,7 @@
* information about that wallpaper. Otherwise, if it is a static image,
* simply return null.
*/
- WallpaperInfo getWallpaperInfo();
+ WallpaperInfo getWallpaperInfo(int userId);
/**
* Clear the system wallpaper.
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 7f467f0..79f2a1e 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -51,6 +51,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.view.WindowManagerGlobal;
@@ -783,7 +784,7 @@
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
} else {
- return sGlobals.mService.getWallpaperInfo();
+ return sGlobals.mService.getWallpaperInfo(UserHandle.myUserId());
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/com/android/internal/widget/ICheckCredentialProgressCallback.aidl b/core/java/com/android/internal/widget/ICheckCredentialProgressCallback.aidl
new file mode 100644
index 0000000..79717cf
--- /dev/null
+++ b/core/java/com/android/internal/widget/ICheckCredentialProgressCallback.aidl
@@ -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();
+}
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 05b839d..9fa558e 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -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 @@
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);
diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java
index 713f56f..df9b0dd 100644
--- a/core/java/com/android/internal/widget/LockPatternChecker.java
+++ b/core/java/com/android/internal/widget/LockPatternChecker.java
@@ -14,6 +14,13 @@
* 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 @@
@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 @@
@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;
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index b7ce7d7..04654f3 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -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.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 @@
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 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 @@
* @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) {
@@ -1481,6 +1507,33 @@
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.
*/
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index cca9163..766eab7 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -137,12 +137,21 @@
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 */);
+ }
}
});
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
index 7ea767c..4f5152a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -36,6 +36,7 @@
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 @@
private View mDivider;
private int mDisappearYTranslation;
private View[][] mViews;
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
public KeyguardPINView(Context context) {
this(context, null);
@@ -56,8 +58,14 @@
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 @@
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() {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 23015b5..69eb538 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -55,9 +55,13 @@
// 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 @@
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 @@
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 @@
@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(),
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 94d9550..dec1fd2 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -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.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.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.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 @@
private boolean mGoingToSleep;
private boolean mBouncer;
private boolean mBootCompleted;
+ private boolean mUserUnlocked;
// Device provisioning state
private boolean mDeviceProvisioned;
@@ -202,6 +203,7 @@
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 @@
&& !hasFingerprintUnlockTimedOut(sCurrentUser);
}
+ public boolean isUserUnlocked() {
+ return mUserUnlocked;
+ }
+
public StrongAuthTracker getStrongAuthTracker() {
return mStrongAuthTracker;
}
@@ -1058,6 +1064,8 @@
if (mFpm != null) {
mFpm.addLockoutResetCallback(mLockoutResetCallback);
}
+
+ mUserManager = context.getSystemService(UserManager.class);
}
private void updateFingerprintListeningState() {
@@ -1390,6 +1398,7 @@
private void handleKeyguardReset() {
if (DEBUG) Log.d(TAG, "handleKeyguardReset");
updateFingerprintListeningState();
+ mUserUnlocked = mUserManager.isUserUnlocked(getCurrentUser());
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index b5561bd..21f68f5 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -29,6 +29,7 @@
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.phone.QSTileHost;
@@ -94,7 +95,7 @@
}
public ScrimController createScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
- View headsUpScrim) {
+ View headsUpScrim, LockscreenWallpaper lockscreenWallpaper) {
return new ScrimController(scrimBehind, scrimInFront, headsUpScrim);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index e109812..bc05ff1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -234,7 +234,6 @@
mKeyguardView.setViewMediatorCallback(mCallback);
mContainer.addView(mRoot, mContainer.getChildCount());
mRoot.setVisibility(View.INVISIBLE);
- mRoot.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
}
protected void removeView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index f233e50..d969451 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -789,11 +789,15 @@
mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
+ if (ENABLE_LOCKSCREEN_WALLPAPER) {
+ mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
+ }
+
ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
mScrimController = SystemUIFactory.getInstance().createScrimController(
- scrimBehind, scrimInFront, headsUpScrim);
+ scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper);
if (mScrimSrcModeEnabled) {
Runnable runnable = new Runnable() {
@Override
@@ -823,10 +827,6 @@
mKeyguardBottomArea.getLockIcon());
mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
- if (ENABLE_LOCKSCREEN_WALLPAPER) {
- mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
- }
-
// set the initial view visibility
setAreThereNotifications();
@@ -3522,6 +3522,7 @@
setControllerUsers();
clearCurrentMediaNotification();
mLockscreenWallpaper.setCurrentUser(newUserId);
+ mScrimController.setCurrentUser(newUserId);
updateMediaMetaData(true, false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 94ede0c..40abaa4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -31,6 +31,7 @@
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;
@@ -47,10 +48,13 @@
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;
+ protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
+ protected 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;
@@ -60,6 +64,7 @@
private final ScrimView mScrimInFront;
private final UnlockMethodCache mUnlockMethodCache;
private final View mHeadsUpScrim;
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
protected float mScrimBehindAlpha = SCRIM_BEHIND_ALPHA;
protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
@@ -101,6 +106,7 @@
mHeadsUpScrim = headsUpScrim;
final Context context = scrimBehind.getContext();
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
+ mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
updateHeadsUpScrim(false);
}
@@ -109,6 +115,13 @@
scheduleUpdate();
}
+ protected void setScrimBehindValues(float scrimBehindAlphaKeyguard,
+ float scrimBehindAlphaUnlocking) {
+ mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
+ mScrimBehindAlphaUnlocking = scrimBehindAlphaUnlocking;
+ scheduleUpdate();
+ }
+
public void onTrackingStarted() {
mExpanding = true;
mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer();
@@ -151,11 +164,19 @@
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() {
@@ -200,6 +221,12 @@
return mDozeInFrontAlpha;
}
+ private float getScrimInFrontAlpha() {
+ return mKeyguardUpdateMonitor.isUserUnlocked()
+ ? SCRIM_IN_FRONT_ALPHA
+ : SCRIM_IN_FRONT_ALPHA_LOCKED;
+ }
+
protected void scheduleUpdate() {
if (mUpdatePending) return;
@@ -239,10 +266,10 @@
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 && !mBouncerIsKeyguard) {
- setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA);
+ setScrimInFrontColor(getScrimInFrontAlpha());
setScrimBehindColor(0f);
} else if (mBouncerShowing) {
setScrimInFrontColor(0f);
@@ -365,7 +392,13 @@
}
protected 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
@@ -536,4 +569,8 @@
R.dimen.heads_up_scrim_height);
mHeadsUpScrim.setLayoutParams(layoutParams);
}
+
+ public void setCurrentUser(int currentUser) {
+ // Don't care in the base class.
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index f1d2fe9..79d274e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -53,6 +53,11 @@
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;
@@ -277,9 +282,12 @@
/**
* 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);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 8e0114a..e28fa73 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -69,6 +69,7 @@
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 @@
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 @@
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 @@
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 @@
}
@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 String adjustForKeystore(String pattern) {
return LockPatternUtils.patternStringToBaseZero(pattern);
}
- }
+ },
+ progressCallback
);
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK
@@ -1264,15 +1271,15 @@
}
@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 @@
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 @@
// 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 @@
}
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 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
@@ -1394,7 +1406,13 @@
}
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 +1468,7 @@
try {
if (mLockPatternUtils.isLockPatternEnabled(userId)) {
- if (checkPattern(password, userId).getResponseCode()
+ if (checkPattern(password, userId, null /* progressCallback */).getResponseCode()
== GateKeeperResponse.RESPONSE_OK) {
return true;
}
@@ -1460,7 +1478,7 @@
try {
if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
- if (checkPassword(password, userId).getResponseCode()
+ if (checkPassword(password, userId, null /* progressCallback */).getResponseCode()
== GateKeeperResponse.RESPONSE_OK) {
return true;
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 7907ea5..2800227 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1282,8 +1282,9 @@
}
@Override
- public WallpaperInfo getWallpaperInfo() {
- int userId = UserHandle.getCallingUserId();
+ public WallpaperInfo getWallpaperInfo(int userId) {
+ userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, true, "getWallpaperIdForUser", null);
synchronized (mLock) {
WallpaperData wallpaper = mWallpaperMap.get(userId);
if (wallpaper != null && wallpaper.connection != null) {