diff options
| author | 2015-08-19 01:33:52 +0000 | |
|---|---|---|
| committer | 2015-08-19 01:33:52 +0000 | |
| commit | f10e475d85a584e07bf74cc4d47ee4176ed543f8 (patch) | |
| tree | d33189f0144e9dd71e37ae6e7050ed6c0ad1cf3b | |
| parent | 1dc1c93b9347380064c183398bb0441d99a33bf3 (diff) | |
| parent | ebcd9d558f1d9e17b5b04d96b816dffb2d8c8d13 (diff) | |
am ebcd9d55: am 0835f33a: Merge "Improve motion for wake-and-unlocking while pulsing" into mnc-dr-dev
* commit 'ebcd9d558f1d9e17b5b04d96b816dffb2d8c8d13':
Improve motion for wake-and-unlocking while pulsing
13 files changed, 453 insertions, 210 deletions
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java index 806f2806e441..4eb6f881afb8 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -94,15 +94,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private static final String TAG = "KeyguardUpdateMonitor"; private static final boolean DEBUG = KeyguardConstants.DEBUG; private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES; - private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK; private static final int LOW_BATTERY_THRESHOLD = 20; - private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000; private static final String ACTION_FACE_UNLOCK_STARTED = "com.android.facelock.FACE_UNLOCK_STARTED"; private static final String ACTION_FACE_UNLOCK_STOPPED = "com.android.facelock.FACE_UNLOCK_STOPPED"; - private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock"; private static final String ACTION_STRONG_AUTH_TIMEOUT = "com.android.systemui.ACTION_STRONG_AUTH_TIMEOUT"; @@ -111,29 +108,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; /** - * Mode in which we don't need to wake up the device when we get a fingerprint. - */ - private static final int FP_WAKE_NONE = 0; - - /** - * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire - * a fingerprint while the screen is off and the device was sleeping. - */ - private static final int FP_WAKE_DIRECT_UNLOCK = 1; - - /** - * Mode in which we wake up the device, but play the normal dismiss animation. Active when we - * acquire a fingerprint pulsing in doze mode. - * */ - private static final int FP_WAKE_TO_BOUNCER = 2; - - /** - * Mode in which we only wake up the device, and keyguard was not showing when we acquired a - * fingerprint. - * */ - private static final int FP_ONLY_WAKE = 3; - - /** * Milliseconds after unlocking with fingerprint times out, i.e. the user has to use a * strong auth method like password, PIN or pattern. */ @@ -202,7 +176,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private List<SubscriptionInfo> mSubscriptionInfo; private boolean mFingerprintDetectionRunning; private TrustManager mTrustManager; - private PowerManager mPowerManager; private final Handler mHandler = new Handler() { @Override @@ -398,22 +371,23 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } } - private void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { + private void onFingerprintAuthenticated(int userId) { mUserFingerprintAuthenticated.put(userId, true); for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { - cb.onFingerprintAuthenticated(userId, wakeAndUnlocking); + cb.onFingerprintAuthenticated(userId); } } } private void handleFingerprintAuthFailed() { - if (mFpWakeMode == FP_WAKE_DIRECT_UNLOCK) { - notifyOnFingerprintWakeAndUnlockingFinished(); + for (int i = 0; i < mCallbacks.size(); i++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); + if (cb != null) { + cb.onFingerprintAuthFailed(); + } } - mFpWakeMode = FP_WAKE_NONE; - releaseFingerprintWakeLock(); handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized)); } @@ -421,75 +395,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) { return; } - if (!mDeviceInteractive && !mScreenOn) { - releaseFingerprintWakeLock(); - mWakeLock = mPowerManager.newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME); - mWakeLock.acquire(); - mFpWakeMode = mKeyguardIsVisible ? FP_WAKE_DIRECT_UNLOCK : FP_ONLY_WAKE; - if (DEBUG_FP_WAKELOCK) { - Log.i(TAG, "fingerprint acquired, grabbing fp wakelock"); - } - mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable, - FINGERPRINT_WAKELOCK_TIMEOUT_MS); - if (mFpWakeMode == FP_WAKE_DIRECT_UNLOCK) { - notifyOnFingerprintWakeAndUnlockingStarted(); - } - } else if (!mDeviceInteractive) { - mFpWakeMode = FP_WAKE_TO_BOUNCER; - } else { - mFpWakeMode = FP_WAKE_NONE; - } - } - - private void notifyOnFingerprintWakeAndUnlockingStarted() { for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { - cb.onFingerprintWakeAndUnlockingStarted(); + cb.onFingerprintAcquired(); } } } - private void notifyOnFingerprintWakeAndUnlockingFinished() { - for (int i = 0; i < mCallbacks.size(); i++) { - KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); - if (cb != null) { - cb.onFingerprintWakeAndUnlockingFinished(); - } - } - } - - private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() { - @Override - public void run() { - if (DEBUG_FP_WAKELOCK) { - Log.i(TAG, "fp wakelock: TIMEOUT!!"); - } - releaseFingerprintWakeLock(); - } - }; - - private void releaseFingerprintWakeLock() { - if (mWakeLock != null) { - mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable); - if (DEBUG_FP_WAKELOCK) { - Log.i(TAG, "releasing fp wakelock"); - } - mWakeLock.release(); - mWakeLock = null; - } - } - private void handleFingerprintAuthenticated() { - if (mFpWakeMode == FP_WAKE_TO_BOUNCER || mFpWakeMode == FP_WAKE_DIRECT_UNLOCK - || mFpWakeMode == FP_ONLY_WAKE) { - if (DEBUG_FP_WAKELOCK) { - Log.i(TAG, "fp wakelock: Authenticated, waking up..."); - } - mPowerManager.wakeUp(SystemClock.uptimeMillis()); - } - releaseFingerprintWakeLock(); try { final int userId; try { @@ -502,7 +416,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId); return; } - onFingerprintAuthenticated(userId, mFpWakeMode == FP_WAKE_DIRECT_UNLOCK); + onFingerprintAuthenticated(userId); } finally { setFingerprintRunningDetectionRunning(false); } @@ -754,7 +668,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { }; private CancellationSignal mFingerprintCancelSignal; private FingerprintManager mFpm; - private PowerManager.WakeLock mWakeLock; /** * When we receive a @@ -916,10 +829,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { cb.onScreenTurnedOn(); } } - if (mFpWakeMode == FP_WAKE_DIRECT_UNLOCK) { - notifyOnFingerprintWakeAndUnlockingFinished(); - } - mFpWakeMode = FP_WAKE_NONE; } private void handleScreenTurnedOff() { @@ -958,7 +867,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private KeyguardUpdateMonitor(Context context) { mContext = context; mSubscriptionManager = SubscriptionManager.from(context); - mPowerManager = context.getSystemService(PowerManager.class); mAlarmManager = context.getSystemService(AlarmManager.class); mDeviceProvisioned = isDeviceProvisionedInSettingsDb(); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index bf9435e18b0e..7ca67b085e9a 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -186,23 +186,23 @@ public class KeyguardUpdateMonitorCallback { public void onTrustGrantedWithFlags(int flags, int userId) { } /** - * Called when a fingerprint is recognized. - * @param userId the user id for which the fingerprint was authenticated - * @param wakeAndUnlocking whether the authentication woke the device up and thus we'd like to - * dismiss the lockscreen before turning on the screen + * Called when a finger has been acquired. + * <p> + * It is guaranteed that either {@link #onFingerprintAuthenticated} or + * {@link #onFingerprintAuthFailed()} is called after this method eventually. */ - public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { } + public void onFingerprintAcquired() { } /** - * Called when we might be starting a wake-and-unlock sequence. + * Called when a fingerprint couldn't be authenticated. */ - public void onFingerprintWakeAndUnlockingStarted() { } + public void onFingerprintAuthFailed() { } /** - * Called when we're done with the wake-and-unlock sequence. This can either happen when we - * figure out that the fingerprint didn't match, or when the phone is fully unlocked. + * Called when a fingerprint is recognized. + * @param userId the user id for which the fingerprint was authenticated */ - public void onFingerprintWakeAndUnlockingFinished() { } + public void onFingerprintAuthenticated(int userId) { } /** * Called when fingerprint provides help string (e.g. "Try again") diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index 8eef23e3db52..13128b7cf9eb 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -37,6 +37,7 @@ <item type="id" name="doze_saved_filter_tag"/> <item type="id" name="qs_icon_tag"/> <item type="id" name="scrim"/> + <item type="id" name="scrim_target"/> <item type="id" name="hun_scrim_alpha_start"/> <item type="id" name="hun_scrim_alpha_end"/> <item type="id" name="notification_power"/> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index e83396212818..ce91d5b13779 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -68,6 +68,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.SystemUI; +import com.android.systemui.statusbar.phone.FingerprintUnlockController; import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; @@ -176,11 +177,6 @@ public class KeyguardViewMediator extends SystemUI { */ private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics"; - /** - * How much faster we collapse the lockscreen when authenticating with fingerprint. - */ - private static final float FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR = 1.3f; - /** The stream type that the lock sounds are tied to. */ private int mUiSoundsStreamType; @@ -458,31 +454,6 @@ public class KeyguardViewMediator extends SystemUI { break; } } - - @Override - public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { - boolean unlockingWithFingerprintAllowed = - mUpdateMonitor.isUnlockingWithFingerprintAllowed(); - if (mStatusBarKeyguardViewManager.isBouncerShowing()) { - if (unlockingWithFingerprintAllowed) { - mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated( - false /* strongAuth */); - } - } else { - if (wakeAndUnlocking && mShowing && unlockingWithFingerprintAllowed) { - mWakeAndUnlocking = true; - mStatusBarKeyguardViewManager.setWakeAndUnlocking(); - keyguardDone(true); - } else if (mShowing) { - if (wakeAndUnlocking) { - mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested(); - } - mStatusBarKeyguardViewManager.animateCollapsePanels( - FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR); - } - } - }; - }; ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { @@ -1620,11 +1591,17 @@ public class KeyguardViewMediator extends SystemUI { } } + public void onWakeAndUnlocking() { + mWakeAndUnlocking = true; + keyguardDone(true /* authenticated */); + } + public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar, ViewGroup container, StatusBarWindowManager statusBarWindowManager, - ScrimController scrimController) { + ScrimController scrimController, + FingerprintUnlockController fingerprintUnlockController) { mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container, - statusBarWindowManager, scrimController); + statusBarWindowManager, scrimController, fingerprintUnlockController); return mStatusBarKeyguardViewManager; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index 403af7099c6c..7f17885ab687 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -350,6 +350,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } else { updateBackground(); } + setOutlineAlpha(dark ? 0f : 1f); } public void setShowingLegacyBackground(boolean showing) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java index d77e050dbee7..a6fc4bbcb11d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java @@ -34,6 +34,7 @@ public abstract class ExpandableOutlineView extends ExpandableView { private final Rect mOutlineRect = new Rect(); protected final int mRoundedRectCornerRadius; private boolean mCustomOutline; + private float mOutlineAlpha = 1f; public ExpandableOutlineView(Context context, AttributeSet attrs) { super(context, attrs); @@ -50,6 +51,7 @@ public abstract class ExpandableOutlineView extends ExpandableView { } else { outline.setRoundRect(mOutlineRect, mRoundedRectCornerRadius); } + outline.setAlpha(mOutlineAlpha); } }); } @@ -66,6 +68,11 @@ public abstract class ExpandableOutlineView extends ExpandableView { invalidateOutline(); } + protected void setOutlineAlpha(float alpha) { + mOutlineAlpha = alpha; + invalidateOutline(); + } + protected void setOutlineRect(RectF rect) { if (rect != null) { setOutlineRect(rect.left, rect.top, rect.right, rect.bottom); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java index c0077b80c492..4d3e57ed8b9d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java @@ -106,8 +106,10 @@ public class DozeScrimController { public void abortPulsing() { mHandler.removeCallbacks(mPulseIn); abortAnimations(); - mScrimController.setDozeBehindAlpha(1f); - mScrimController.setDozeInFrontAlpha(1f); + if (mDozing) { + mScrimController.setDozeBehindAlpha(1f); + mScrimController.setDozeInFrontAlpha(1f); + } mPulseCallback = null; } @@ -125,6 +127,10 @@ public class DozeScrimController { return mPulseCallback != null; } + public boolean isDozing() { + return mDozing; + } + private void cancelPulsing() { if (DEBUG) Log.d(TAG, "Cancel pulsing"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java new file mode 100644 index 000000000000..28d4a42efd72 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java @@ -0,0 +1,269 @@ +/* + * 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.systemui.statusbar.phone; + +import android.content.Context; +import android.os.Handler; +import android.os.PowerManager; +import android.os.SystemClock; +import android.util.Log; + +import com.android.keyguard.KeyguardConstants; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.systemui.keyguard.KeyguardViewMediator; + +/** + * Controller which coordinates all the fingerprint unlocking actions with the UI. + */ +public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { + + private static final String TAG = "FingerprintController"; + private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK; + private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000; + private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock"; + + /** + * Mode in which we don't need to wake up the device when we get a fingerprint. + */ + public static final int MODE_NONE = 0; + + /** + * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire + * a fingerprint while the screen is off and the device was sleeping. + */ + public static final int MODE_WAKE_AND_UNLOCK = 1; + + /** + * Mode in which we wake the device up, and fade out the Keyguard contents because they were + * already visible while pulsing in doze mode. + */ + public static final int MODE_WAKE_AND_UNLOCK_PULSING = 2; + + /** + * Mode in which we wake up the device, but play the normal dismiss animation. Active when we + * acquire a fingerprint pulsing in doze mode. + */ + public static final int MODE_SHOW_BOUNCER = 3; + + /** + * Mode in which we only wake up the device, and keyguard was not showing when we acquired a + * fingerprint. + * */ + public static final int MODE_ONLY_WAKE = 4; + + /** + * Mode in which fingerprint unlocks the device. + */ + public static final int MODE_UNLOCK = 5; + + /** + * Mode in which fingerprint brings up the bouncer because fingerprint unlocking is currently + * not allowed. + */ + public static final int MODE_DISMISS_BOUNCER = 6; + + /** + * How much faster we collapse the lockscreen when authenticating with fingerprint. + */ + private static final float FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR = 1.3f; + + private PowerManager mPowerManager; + private Handler mHandler = new Handler(); + private PowerManager.WakeLock mWakeLock; + private KeyguardUpdateMonitor mUpdateMonitor; + private int mMode; + private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + private StatusBarWindowManager mStatusBarWindowManager; + private DozeScrimController mDozeScrimController; + private KeyguardViewMediator mKeyguardViewMediator; + private ScrimController mScrimController; + private PhoneStatusBar mPhoneStatusBar; + + public FingerprintUnlockController(Context context, + StatusBarWindowManager statusBarWindowManager, + DozeScrimController dozeScrimController, + KeyguardViewMediator keyguardViewMediator, + ScrimController scrimController, + PhoneStatusBar phoneStatusBar) { + mPowerManager = context.getSystemService(PowerManager.class); + mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context); + mUpdateMonitor.registerCallback(this); + mStatusBarWindowManager = statusBarWindowManager; + mDozeScrimController = dozeScrimController; + mKeyguardViewMediator = keyguardViewMediator; + mScrimController = scrimController; + mPhoneStatusBar = phoneStatusBar; + } + + public void setStatusBarKeyguardViewManager( + StatusBarKeyguardViewManager statusBarKeyguardViewManager) { + mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; + } + + private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() { + @Override + public void run() { + if (DEBUG_FP_WAKELOCK) { + Log.i(TAG, "fp wakelock: TIMEOUT!!"); + } + releaseFingerprintWakeLock(); + } + }; + + private void releaseFingerprintWakeLock() { + if (mWakeLock != null) { + mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable); + if (DEBUG_FP_WAKELOCK) { + Log.i(TAG, "releasing fp wakelock"); + } + mWakeLock.release(); + mWakeLock = null; + } + } + + @Override + public void onFingerprintAcquired() { + releaseFingerprintWakeLock(); + if (!mUpdateMonitor.isDeviceInteractive()) { + mWakeLock = mPowerManager.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME); + mWakeLock.acquire(); + if (DEBUG_FP_WAKELOCK) { + Log.i(TAG, "fingerprint acquired, grabbing fp wakelock"); + } + mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable, + FINGERPRINT_WAKELOCK_TIMEOUT_MS); + if (mDozeScrimController.isPulsing()) { + + // If we are waking the device up while we are pulsing the clock and the + // notifications would light up first, creating an unpleasant animation. + // Defer changing the screen brightness by forcing doze brightness on our window + // until the clock and the notifications are faded out. + mStatusBarWindowManager.setForceDozeBrightness(true); + } + } + } + + @Override + public void onFingerprintAuthenticated(int userId) { + boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive(); + mMode = calculateMode(); + if (!wasDeviceInteractive) { + if (DEBUG_FP_WAKELOCK) { + Log.i(TAG, "fp wakelock: Authenticated, waking up..."); + } + mPowerManager.wakeUp(SystemClock.uptimeMillis()); + } + releaseFingerprintWakeLock(); + switch (mMode) { + case MODE_DISMISS_BOUNCER: + mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated( + false /* strongAuth */); + break; + case MODE_UNLOCK: + case MODE_SHOW_BOUNCER: + if (!wasDeviceInteractive) { + mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested(); + } + mStatusBarKeyguardViewManager.animateCollapsePanels( + FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR); + break; + case MODE_WAKE_AND_UNLOCK: + case MODE_WAKE_AND_UNLOCK_PULSING: + mDozeScrimController.abortPulsing(); + mKeyguardViewMediator.onWakeAndUnlocking(); + mScrimController.setWakeAndUnlocking(); + if (mPhoneStatusBar.getNavigationBarView() != null) { + mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true); + } + break; + case MODE_ONLY_WAKE: + case MODE_NONE: + break; + } + if (mMode != MODE_WAKE_AND_UNLOCK_PULSING) { + mStatusBarWindowManager.setForceDozeBrightness(false); + } + mPhoneStatusBar.notifyFpAuthModeChanged(); + } + + public int getMode() { + return mMode; + } + + private int calculateMode() { + boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithFingerprintAllowed(); + if (!mUpdateMonitor.isDeviceInteractive()) { + if (!mStatusBarKeyguardViewManager.isShowing()) { + return MODE_ONLY_WAKE; + } else if (mDozeScrimController.isPulsing() && unlockingAllowed) { + return MODE_WAKE_AND_UNLOCK_PULSING; + } else if (unlockingAllowed) { + return MODE_WAKE_AND_UNLOCK; + } else { + return MODE_SHOW_BOUNCER; + } + } + if (mStatusBarKeyguardViewManager.isShowing()) { + if (mStatusBarKeyguardViewManager.isBouncerShowing() && unlockingAllowed) { + return MODE_DISMISS_BOUNCER; + } else if (unlockingAllowed) { + return MODE_UNLOCK; + } else { + return MODE_SHOW_BOUNCER; + } + } + return MODE_NONE; + } + + @Override + public void onFingerprintAuthFailed() { + cleanup(); + } + + @Override + public void onFingerprintError(int msgId, String errString) { + cleanup(); + } + + private void cleanup() { + mMode = MODE_NONE; + releaseFingerprintWakeLock(); + mStatusBarWindowManager.setForceDozeBrightness(false); + mPhoneStatusBar.notifyFpAuthModeChanged(); + } + + public void startKeyguardFadingAway() { + + // Disable brightness override when the ambient contents are fully invisible. + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + mStatusBarWindowManager.setForceDozeBrightness(false); + } + }, PhoneStatusBar.FADE_KEYGUARD_DURATION_PULSING); + } + + public void finishKeyguardFadingAway() { + mMode = MODE_NONE; + if (mPhoneStatusBar.getNavigationBarView() != null) { + mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(false); + } + mPhoneStatusBar.notifyFpAuthModeChanged(); + } +} 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 1062db9b5748..b277cc165701 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -231,6 +231,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public static final int FADE_KEYGUARD_START_DELAY = 100; public static final int FADE_KEYGUARD_DURATION = 300; + public static final int FADE_KEYGUARD_DURATION_PULSING = 120; /** Allow some time inbetween the long press for back and recents. */ private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; @@ -271,6 +272,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, KeyguardMonitor mKeyguardMonitor; BrightnessMirrorController mBrightnessMirrorController; AccessibilityController mAccessibilityController; + FingerprintUnlockController mFingerprintUnlockController; int mNaturalBarHeight = -1; @@ -1012,10 +1014,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void startKeyguard() { KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class); + mFingerprintUnlockController = new FingerprintUnlockController(mContext, + mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator, + mScrimController, this); mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this, - mStatusBarWindow, mStatusBarWindowManager, mScrimController); + mStatusBarWindow, mStatusBarWindowManager, mScrimController, + mFingerprintUnlockController); mKeyguardIndicationController.setStatusBarKeyguardViewManager( mStatusBarKeyguardViewManager); + mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager); mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback(); } @@ -3425,6 +3432,27 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } /** + * Fades the content of the Keyguard while we are dozing and makes it invisible when finished + * fading. + */ + public void fadeKeyguardWhilePulsing() { + mNotificationPanel.animate() + .alpha(0f) + .setStartDelay(0) + .setDuration(FADE_KEYGUARD_DURATION_PULSING) + .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR) + .withLayer() + .withEndAction(new Runnable() { + @Override + public void run() { + mNotificationPanel.setAlpha(1f); + hideKeyguard(); + } + }) + .start(); + } + + /** * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen * because the launched app crashed or something else went wrong. @@ -3565,7 +3593,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mNotificationPanel.setDozing(mDozing, animate); mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation); mScrimController.setDozing(mDozing); - mDozeScrimController.setDozing(mDozing, animate); + + // Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock + // for pulsing so the Keyguard fade-out animation scrim can take over. + mDozeScrimController.setDozing(mDozing && + mFingerprintUnlockController.getMode() + != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate); } public void updateStackScrollerState(boolean goingToFullShade) { @@ -3998,8 +4031,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } + public void notifyFpAuthModeChanged() { + updateDozing(); + } + private void updateDozing() { - mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD; + // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked. + mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD + || mFingerprintUnlockController.getMode() + == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING; updateDozingState(); } @@ -4041,7 +4081,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Keeps the last reported state by fireNotificationLight. private boolean mNotificationLightOn; - private boolean mWakeAndUnlocking; @Override public String toString() { @@ -4105,18 +4144,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, @Override public boolean isPulsingBlocked() { - return mWakeAndUnlocking; - } - - @Override - public void onFingerprintWakeAndUnlockingStarted() { - mWakeAndUnlocking = true; - mDozeScrimController.abortPulsing(); - } - - @Override - public void onFingerprintWakeAndUnlockingFinished() { - mWakeAndUnlocking = false; + return mFingerprintUnlockController.getMode() + == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK; } @Override 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 1a35500abac2..5b009ee28c31 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -44,12 +44,15 @@ import com.android.systemui.statusbar.stack.StackStateAnimator; public class ScrimController implements ViewTreeObserver.OnPreDrawListener, HeadsUpManager.OnHeadsUpChangedListener { public static final long ANIMATION_DURATION = 220; + public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR + = new PathInterpolator(0f, 0, 0.7f, 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 int TAG_KEY_ANIM = R.id.scrim; + private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target; private static final int TAG_HUN_START_ALPHA = R.id.hun_scrim_alpha_start; private static final int TAG_HUN_END_ALPHA = R.id.hun_scrim_alpha_end; @@ -71,9 +74,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, private long mDurationOverride = -1; private long mAnimationDelay; private Runnable mOnAnimationFinished; - private boolean mAnimationStarted; private final Interpolator mInterpolator = new DecelerateInterpolator(); - private final Interpolator mKeyguardFadeOutInterpolator = new PathInterpolator(0f, 0, 0.7f, 1f); private BackDropView mBackDropView; private boolean mScrimSrcEnabled; private boolean mDozing; @@ -145,7 +146,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, public void abortKeyguardFadingOut() { if (mAnimateKeyguardFadingOut) { - endAnimateKeyguardFadingOut(); + endAnimateKeyguardFadingOut(true /* force */); } } @@ -198,8 +199,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, // During wake and unlock, we first hide everything behind a black scrim, which then // gets faded out from animateKeyguardFadingOut. - setScrimInFrontColor(1f); - setScrimBehindColor(0f); + if (mDozing) { + setScrimInFrontColor(0f); + setScrimBehindColor(1f); + } else { + setScrimInFrontColor(1f); + setScrimBehindColor(0f); + } } else if (!mKeyguardShowing && !mBouncerShowing) { updateScrimNormal(); setScrimInFrontColor(0); @@ -258,10 +264,14 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, } private void setScrimColor(View scrim, float alpha) { - Object runningAnim = scrim.getTag(TAG_KEY_ANIM); - if (runningAnim instanceof ValueAnimator) { - ((ValueAnimator) runningAnim).cancel(); - scrim.setTag(TAG_KEY_ANIM, null); + ValueAnimator runningAnim = (ValueAnimator) scrim.getTag(TAG_KEY_ANIM); + Float target = (Float) scrim.getTag(TAG_KEY_ANIM_TARGET); + if (runningAnim != null && target != null) { + if (alpha != target) { + runningAnim.cancel(); + } else { + return; + } } if (mAnimateChange) { startScrimAnimation(scrim, alpha); @@ -325,15 +335,16 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, mOnAnimationFinished = null; } scrim.setTag(TAG_KEY_ANIM, null); + scrim.setTag(TAG_KEY_ANIM_TARGET, null); } }); anim.start(); scrim.setTag(TAG_KEY_ANIM, anim); - mAnimationStarted = true; + scrim.setTag(TAG_KEY_ANIM_TARGET, target); } private Interpolator getInterpolator() { - return mAnimateKeyguardFadingOut ? mKeyguardFadeOutInterpolator : mInterpolator; + return mAnimateKeyguardFadingOut ? KEYGUARD_FADE_OUT_INTERPOLATOR : mInterpolator; } @Override @@ -345,19 +356,23 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, mAnimationDelay = 0; // Make sure that we always call the listener even if we didn't start an animation. - endAnimateKeyguardFadingOut(); - mAnimationStarted = false; + endAnimateKeyguardFadingOut(false /* force */); return true; } - private void endAnimateKeyguardFadingOut() { + private void endAnimateKeyguardFadingOut(boolean force) { mAnimateKeyguardFadingOut = false; - if (!mAnimationStarted && mOnAnimationFinished != null) { + if ((force || (!isAnimating(mScrimInFront) && !isAnimating(mScrimBehind))) + && mOnAnimationFinished != null) { mOnAnimationFinished.run(); mOnAnimationFinished = null; } } + private boolean isAnimating(View scrim) { + return scrim.getTag(TAG_KEY_ANIM) != null; + } + public void setBackDropView(BackDropView backDropView) { mBackDropView = backDropView; mBackDropView.setOnVisibilityChangedRunnable(new Runnable() { 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 2070c965754c..448f16dac5ac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -58,6 +58,7 @@ public class StatusBarKeyguardViewManager { private ViewMediatorCallback mViewMediatorCallback; private PhoneStatusBar mPhoneStatusBar; private ScrimController mScrimController; + private FingerprintUnlockController mFingerprintUnlockController; private ViewGroup mContainer; private StatusBarWindowManager mStatusBarWindowManager; @@ -76,7 +77,6 @@ public class StatusBarKeyguardViewManager { private boolean mLastDeferScrimFadeOut; private OnDismissAction mAfterKeyguardGoneAction; private boolean mDeviceWillWakeUp; - private boolean mWakeAndUnlocking; private boolean mDeferScrimFadeOut; public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback, @@ -88,11 +88,13 @@ public class StatusBarKeyguardViewManager { public void registerStatusBar(PhoneStatusBar phoneStatusBar, ViewGroup container, StatusBarWindowManager statusBarWindowManager, - ScrimController scrimController) { + ScrimController scrimController, + FingerprintUnlockController fingerprintUnlockController) { mPhoneStatusBar = phoneStatusBar; mContainer = container; mStatusBarWindowManager = statusBarWindowManager; mScrimController = scrimController; + mFingerprintUnlockController = fingerprintUnlockController; mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils, mStatusBarWindowManager, container); } @@ -189,7 +191,6 @@ public class StatusBarKeyguardViewManager { } public void onScreenTurnedOff() { - mWakeAndUnlocking = false; mScreenTurnedOn = false; } @@ -275,23 +276,36 @@ public class StatusBarKeyguardViewManager { } }); } else { - mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration); - boolean staying = mPhoneStatusBar.hideKeyguard(); - if (!staying) { + if (mFingerprintUnlockController.getMode() + == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) { + mFingerprintUnlockController.startKeyguardFadingAway(); + mPhoneStatusBar.setKeyguardFadingAway(startTime, 0, 250); mStatusBarWindowManager.setKeyguardFadingAway(true); - if (mWakeAndUnlocking && !mScreenTurnedOn) { - mDeferScrimFadeOut = true; - } else if (mWakeAndUnlocking){ - - // Screen is already on, don't defer with fading out. - animateScrimControllerKeyguardFadingOut(0, - WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS); - } else { - animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration); - } + mPhoneStatusBar.fadeKeyguardWhilePulsing(); + animateScrimControllerKeyguardFadingOut(0, 250); } else { - mScrimController.animateGoingToFullShade(delay, fadeoutDuration); - mPhoneStatusBar.finishKeyguardFadingAway(); + mFingerprintUnlockController.startKeyguardFadingAway(); + mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration); + boolean staying = mPhoneStatusBar.hideKeyguard(); + if (!staying) { + mStatusBarWindowManager.setKeyguardFadingAway(true); + if (mFingerprintUnlockController.getMode() + == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK) { + if (!mScreenTurnedOn) { + mDeferScrimFadeOut = true; + } else { + + // Screen is already on, don't defer with fading out. + animateScrimControllerKeyguardFadingOut(0, + WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS); + } + } else { + animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration); + } + } else { + mScrimController.animateGoingToFullShade(delay, fadeoutDuration); + mPhoneStatusBar.finishKeyguardFadingAway(); + } } mStatusBarWindowManager.setKeyguardShowing(false); mBouncer.hide(true /* destroyView */); @@ -299,7 +313,6 @@ public class StatusBarKeyguardViewManager { executeAfterKeyguardGoneAction(); updateStates(); } - mWakeAndUnlocking = false; } private void animateScrimControllerKeyguardFadingOut(long delay, long duration) { @@ -309,9 +322,7 @@ public class StatusBarKeyguardViewManager { public void run() { mStatusBarWindowManager.setKeyguardFadingAway(false); mPhoneStatusBar.finishKeyguardFadingAway(); - if (mPhoneStatusBar.getNavigationBarView() != null) { - mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(false); - } + mFingerprintUnlockController.finishKeyguardFadingAway(); WindowManagerGlobal.getInstance().trimMemory( ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "Fading out", 0); @@ -409,8 +420,13 @@ public class StatusBarKeyguardViewManager { if (navBarVisible != lastNavBarVisible || mFirstUpdate) { if (mPhoneStatusBar.getNavigationBarView() != null) { if (navBarVisible) { - mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable, - getNavBarShowDelay()); + long delay = getNavBarShowDelay(); + if (delay == 0) { + mMakeNavigationBarVisibleRunnable.run(); + } else { + mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable, + delay); + } } else { mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable); mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE); @@ -496,14 +512,6 @@ public class StatusBarKeyguardViewManager { mBouncer.notifyKeyguardAuthenticated(strongAuth); } - public void setWakeAndUnlocking() { - mWakeAndUnlocking = true; - mScrimController.setWakeAndUnlocking(); - if (mPhoneStatusBar.getNavigationBarView() != null) { - mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true); - } - } - public void showBouncerMessage(String message, int color) { mBouncer.showMessage(message, color); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index 038fefb7cd3a..ccfa0dd058de 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -24,6 +24,7 @@ import android.os.SystemProperties; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; +import android.view.Window; import android.view.WindowManager; import com.android.keyguard.R; @@ -47,13 +48,15 @@ public class StatusBarWindowManager { private WindowManager.LayoutParams mLpChanged; private int mBarHeight; private final boolean mKeyguardScreenRotation; - + private final float mScreenBrightnessDoze; private final State mCurrentState = new State(); public StatusBarWindowManager(Context context) { mContext = context; mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation(); + mScreenBrightnessDoze = mContext.getResources().getInteger( + com.android.internal.R.integer.config_screenBrightnessDoze) / 255f; } private boolean shouldEnableKeyguardScreenRotation() { @@ -182,6 +185,7 @@ public class StatusBarWindowManager { applyInputFeatures(state); applyFitsSystemWindows(state); applyModalFlag(state); + applyBrightness(state); if (mLp.copyFrom(mLpChanged) != 0) { mWindowManager.updateViewLayout(mStatusBarView, mLp); } @@ -205,6 +209,14 @@ public class StatusBarWindowManager { } } + private void applyBrightness(State state) { + if (state.forceDozeBrightness) { + mLpChanged.screenBrightness = mScreenBrightnessDoze; + } else { + mLpChanged.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE; + } + } + public void setKeyguardShowing(boolean showing) { mCurrentState.keyguardShowing = showing; apply(mCurrentState); @@ -279,6 +291,15 @@ public class StatusBarWindowManager { apply(mCurrentState); } + /** + * Set whether the screen brightness is forced to the value we use for doze mode by the status + * bar window. + */ + public void setForceDozeBrightness(boolean forceDozeBrightness) { + mCurrentState.forceDozeBrightness = forceDozeBrightness; + apply(mCurrentState); + } + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("StatusBarWindowManager state:"); pw.println(mCurrentState); @@ -297,6 +318,7 @@ public class StatusBarWindowManager { boolean headsUpShowing; boolean forceStatusBarVisible; boolean forceCollapsed; + boolean forceDozeBrightness; /** * The {@link BaseStatusBar} state from the status bar. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java index d646d0d64388..091db76b7e41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java @@ -132,7 +132,7 @@ public class UnlockMethodCache { } @Override - public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { + public void onFingerprintAuthenticated(int userId) { if (!mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()) { return; } |