From 1aec88fcc289faa3be2c1967d0e19b7f460c4a7d Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Wed, 1 May 2019 22:25:22 -0700 Subject: [PATCH] Animate padlock when waking up Padlock should animate when: - a pulse starts - user presses power - an interrupt wakes up the device Test: Pres power to wake up Test: Wake up from pulse Test: Wait for pulse timeout Test: Wake up from pulse, press power Test: Lift device Fixes: 131761884 Change-Id: Ib15d15f2138cd4f21f46b14221125353a005cde4 --- .../systemui/statusbar/phone/LockIcon.java | 82 +++++++++++-------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java index a831a5d29a797..3b3bd218a8e6b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT; import android.content.Context; @@ -27,6 +28,7 @@ import android.graphics.drawable.Animatable2; import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricSourceType; +import android.os.Handler; import android.util.AttributeSet; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; @@ -66,6 +68,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final AccessibilityController mAccessibilityController; private final DockManager mDockManager; + private final Handler mMainHandler; private int mLastState = 0; private boolean mTransientBiometricsError; @@ -82,6 +85,8 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange private boolean mLastBouncerVisible; private int mIconColor; private float mDozeAmount; + private int mIconRes; + private boolean mWasPulsingOnThisFrame; private final Runnable mDrawOffTimeout = () -> update(true /* forceUpdate */); private final DockManager.DockEventListener mDockEventListener = @@ -133,7 +138,8 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange StatusBarStateController statusBarStateController, ConfigurationController configurationController, AccessibilityController accessibilityController, - @Nullable DockManager dockManager) { + @Nullable DockManager dockManager, + @Named(MAIN_HANDLER_NAME) Handler mainHandler) { super(context, attrs); mContext = context; mUnlockMethodCache = UnlockMethodCache.getInstance(context); @@ -142,6 +148,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange mConfigurationController = configurationController; mStatusBarStateController = statusBarStateController; mDockManager = dockManager; + mMainHandler = mainHandler; } @Override @@ -214,39 +221,36 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange mPulsing, mLastDozing, mDozing, mBouncerVisible); boolean isAnim = iconAnimRes != -1; - Drawable icon; - if (isAnim) { - // Load the animation resource. - icon = mContext.getDrawable(iconAnimRes); - } else { - // Load the static icon resource based on the current state. - icon = getIconForState(state); - } + int iconRes = isAnim ? iconAnimRes : getIconForState(state); + if (iconRes != mIconRes) { + mIconRes = iconRes; - final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable - ? (AnimatedVectorDrawable) icon - : null; - setImageDrawable(icon, false); - updateDarkTint(); - if (mIsFaceUnlockState) { - announceForAccessibility(getContext().getString( - R.string.accessibility_scanning_face)); - } + Drawable icon = mContext.getDrawable(iconRes); + final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable + ? (AnimatedVectorDrawable) icon + : null; + setImageDrawable(icon, false); + if (mIsFaceUnlockState) { + announceForAccessibility(getContext().getString( + R.string.accessibility_scanning_face)); + } - if (animation != null && isAnim) { - animation.forceAnimationOnUI(); - animation.clearAnimationCallbacks(); - animation.registerAnimationCallback(new Animatable2.AnimationCallback() { - @Override - public void onAnimationEnd(Drawable drawable) { - if (getDrawable() == animation && state == getState() - && doesAnimationLoop(iconAnimRes)) { - animation.start(); + if (animation != null && isAnim) { + animation.forceAnimationOnUI(); + animation.clearAnimationCallbacks(); + animation.registerAnimationCallback(new Animatable2.AnimationCallback() { + @Override + public void onAnimationEnd(Drawable drawable) { + if (getDrawable() == animation && state == getState() + && doesAnimationLoop(iconAnimRes)) { + animation.start(); + } } - } - }); - animation.start(); + }); + animation.start(); + } } + updateDarkTint(); if (isAnim && !mLastScreenOn) { removeCallbacks(mDrawOffTimeout); @@ -300,7 +304,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange } } - private Drawable getIconForState(int state) { + private int getIconForState(int state) { int iconRes; switch (state) { case STATE_LOCKED: @@ -318,25 +322,27 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange throw new IllegalArgumentException(); } - return mContext.getDrawable(iconRes); + return iconRes; } private boolean doesAnimationLoop(int resourceId) { return resourceId == com.android.internal.R.anim.lock_scanning; } - private static int getAnimationResForTransition(int oldState, int newState, + private int getAnimationResForTransition(int oldState, int newState, boolean wasPulsing, boolean pulsing, boolean wasDozing, boolean dozing, boolean bouncerVisible) { // Never animate when screen is off - if (dozing && !pulsing) { + if (dozing && !pulsing && !mWasPulsingOnThisFrame) { return -1; } boolean isError = oldState != STATE_BIOMETRICS_ERROR && newState == STATE_BIOMETRICS_ERROR; boolean justUnlocked = oldState != STATE_LOCK_OPEN && newState == STATE_LOCK_OPEN; boolean justLocked = oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED; + boolean nowPulsing = !wasPulsing && pulsing; + boolean turningOn = wasDozing && !dozing && !mWasPulsingOnThisFrame; if (isError) { return com.android.internal.R.anim.lock_to_error; @@ -346,7 +352,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange return com.android.internal.R.anim.lock_lock; } else if (newState == STATE_SCANNING_FACE && bouncerVisible) { return com.android.internal.R.anim.lock_scanning; - } else if (!wasPulsing && pulsing && newState != STATE_LOCK_OPEN) { + } else if ((nowPulsing || turningOn) && newState != STATE_LOCK_OPEN) { return com.android.internal.R.anim.lock_in; } return -1; @@ -377,6 +383,12 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange */ public void setPulsing(boolean pulsing) { mPulsing = pulsing; + if (!mPulsing) { + mWasPulsingOnThisFrame = true; + mMainHandler.post(() -> { + mWasPulsingOnThisFrame = false; + }); + } update(); }