From 83eb6bb5d83d3994a3750b566a2109a049ab1388 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Mon, 17 Aug 2015 17:38:58 -0700 Subject: Improve motion for wake-and-unlocking while pulsing - Move all fingerprint related to logic in on central class in SystemUI that knows all the state of the UI so there is exactly ONE place in which we decide what to do when we acquire a fingerprint. - When pulsing and we get a valid finger, we fade the contents of the Keyguard out and fade the scrim out almost the same way as we would do in a normal wake-and-unlock sequence. - Hide shadows while dozing, so we don't see the artifacts when we fade the dozed Keyguard out. Bug: 23225107 Change-Id: I82f78e61f2530cf7d507ade80f6f0a340c082567 --- .../systemui/keyguard/KeyguardViewMediator.java | 41 +--- .../statusbar/ActivatableNotificationView.java | 1 + .../systemui/statusbar/ExpandableOutlineView.java | 7 + .../statusbar/phone/DozeScrimController.java | 10 +- .../phone/FingerprintUnlockController.java | 269 +++++++++++++++++++++ .../systemui/statusbar/phone/PhoneStatusBar.java | 61 +++-- .../systemui/statusbar/phone/ScrimController.java | 45 ++-- .../phone/StatusBarKeyguardViewManager.java | 72 +++--- .../statusbar/phone/StatusBarWindowManager.java | 24 +- .../statusbar/phone/UnlockMethodCache.java | 2 +- 10 files changed, 433 insertions(+), 99 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java (limited to 'packages/SystemUI/src') diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index e833962..ce91d5b 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 403af70..7f17885 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 d77e050..a6fc4bb 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 c0077b8..4d3e57e 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 0000000..28d4a42 --- /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 1062db9..b277cc1 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 1a35500..5b009ee 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 2070c96..448f16d 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 038fefb..ccfa0dd 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 d646d0d..091db76 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; } -- cgit v1.1