diff --git a/packages/SystemUI/res/anim/lock_in.xml b/packages/SystemUI/res/anim/lock_in.xml deleted file mode 100644 index c7014e80d33ec..0000000000000 --- a/packages/SystemUI/res/anim/lock_in.xml +++ /dev/null @@ -1,227 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/SystemUI/res/anim/lock_in_circular.xml b/packages/SystemUI/res/anim/lock_in_circular.xml deleted file mode 100644 index d1e98db6e0e36..0000000000000 --- a/packages/SystemUI/res/anim/lock_in_circular.xml +++ /dev/null @@ -1,327 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/SystemUI/res/anim/lock_in_filled.xml b/packages/SystemUI/res/anim/lock_in_filled.xml deleted file mode 100644 index 4cde38d4f0dc1..0000000000000 --- a/packages/SystemUI/res/anim/lock_in_filled.xml +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/SystemUI/res/anim/lock_in_rounded.xml b/packages/SystemUI/res/anim/lock_in_rounded.xml deleted file mode 100644 index 7c8cf9d7b5259..0000000000000 --- a/packages/SystemUI/res/anim/lock_in_rounded.xml +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file 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 ca001c6f31108..1e7c44cdba2f1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java @@ -16,7 +16,6 @@ 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.annotation.IntDef; @@ -29,12 +28,12 @@ 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.os.Trace; import android.provider.Settings; import android.text.TextUtils; import android.util.AttributeSet; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityNodeInfo; import androidx.annotation.Nullable; @@ -43,6 +42,7 @@ import com.android.internal.graphics.ColorUtils; import com.android.internal.telephony.IccCardConstants; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.dock.DockManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -67,7 +67,7 @@ import javax.inject.Named; public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChangedListener, StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener, UnlockMethodCache.OnUnlockMethodChangedListener, - NotificationWakeUpCoordinator.WakeUpListener { + NotificationWakeUpCoordinator.WakeUpListener, ViewTreeObserver.OnPreDrawListener { private static final int STATE_LOCKED = 0; private static final int STATE_LOCK_OPEN = 1; @@ -79,12 +79,12 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final AccessibilityController mAccessibilityController; private final DockManager mDockManager; - private final Handler mMainHandler; private final KeyguardMonitor mKeyguardMonitor; private final KeyguardBypassController mBypassController; private final NotificationWakeUpCoordinator mWakeUpCoordinator; private int mLastState = 0; + private boolean mForceUpdate; private boolean mTransientBiometricsError; private boolean mIsFaceUnlockState; private boolean mSimLocked; @@ -92,23 +92,20 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange private boolean mPulsing; private boolean mDozing; private boolean mDocked; - private boolean mLastDozing; - private boolean mLastPulsing; private int mIconColor; private float mDozeAmount; - private int mIconRes; private boolean mBouncerShowing; - private boolean mWasPulsingOnThisFrame; private boolean mWakeAndUnlockRunning; private boolean mKeyguardShowing; private boolean mShowingLaunchAffordance; + private boolean mUpdatePending; private final KeyguardMonitor.Callback mKeyguardMonitorCallback = new KeyguardMonitor.Callback() { @Override public void onKeyguardShowingChanged() { mKeyguardShowing = mKeyguardMonitor.isShowing(); - update(false /* force */); + update(); } }; private final DockManager.DockEventListener mDockEventListener = @@ -119,7 +116,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange || event == DockManager.STATE_DOCKED_HIDE; if (docked != mDocked) { mDocked = docked; - update(true /* force */); + update(); } } }; @@ -129,9 +126,8 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange @Override public void onSimStateChanged(int subId, int slotId, IccCardConstants.State simState) { - boolean oldSimLocked = mSimLocked; mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure(); - update(oldSimLocked != mSimLocked); + update(); } @Override @@ -149,11 +145,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange public void onStrongAuthStateChanged(int userId) { update(); } - - @Override - public void onBiometricsCleared() { - update(); - } }; @Inject @@ -164,8 +155,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange KeyguardBypassController bypassController, NotificationWakeUpCoordinator wakeUpCoordinator, KeyguardMonitor keyguardMonitor, - @Nullable DockManager dockManager, - @Named(MAIN_HANDLER_NAME) Handler mainHandler) { + @Nullable DockManager dockManager) { super(context, attrs); mContext = context; mUnlockMethodCache = UnlockMethodCache.getInstance(context); @@ -177,7 +167,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange mWakeUpCoordinator = wakeUpCoordinator; mKeyguardMonitor = keyguardMonitor; mDockManager = dockManager; - mMainHandler = mainHandler; } @Override @@ -194,6 +183,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange mDockManager.addListener(mDockEventListener); } onThemeChanged(); + update(); } @Override @@ -247,51 +237,61 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange } public void update(boolean force) { - int state = getState(); - mIsFaceUnlockState = state == STATE_SCANNING_FACE; - if (state != mLastState || mLastDozing != mDozing || mLastPulsing != mPulsing || force) { - @LockAnimIndex final int lockAnimIndex = getAnimationIndexForTransition(mLastState, - state, mLastPulsing, mPulsing, mLastDozing, mDozing); - boolean isAnim = lockAnimIndex != -1; - - int iconRes = isAnim ? getThemedAnimationResId(lockAnimIndex) : getIconForState(state); - if (iconRes != mIconRes) { - mIconRes = iconRes; - - 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(lockAnimIndex)) { - animation.start(); - } else { - Trace.endAsyncSection("LockIcon#Animation", state); - } - } - }); - Trace.beginAsyncSection("LockIcon#Animation", state); - animation.start(); - } - } - updateDarkTint(); - - mLastState = state; - mLastDozing = mDozing; - mLastPulsing = mPulsing; + if (force) { + mForceUpdate = true; } + if (!mUpdatePending) { + mUpdatePending = true; + getViewTreeObserver().addOnPreDrawListener(this); + } + } + + @Override + public boolean onPreDraw() { + mUpdatePending = false; + getViewTreeObserver().removeOnPreDrawListener(this); + + int state = getState(); + int lastState = mLastState; + mIsFaceUnlockState = state == STATE_SCANNING_FACE; + mLastState = state; + + if (lastState != state || mForceUpdate) { + mForceUpdate = false; + @LockAnimIndex final int lockAnimIndex = getAnimationIndexForTransition(lastState, + state, mPulsing, mDozing); + boolean isAnim = lockAnimIndex != -1; + int iconRes = isAnim ? getThemedAnimationResId(lockAnimIndex) : getIconForState(state); + + 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(lockAnimIndex)) { + animation.start(); + } else { + Trace.endAsyncSection("LockIcon#Animation", state); + } + } + }); + Trace.beginAsyncSection("LockIcon#Animation", state); + animation.start(); + } + } + updateDarkTint(); boolean onAodNotPulsingOrDocked = mDozing && (!mPulsing || mDocked); boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning @@ -302,8 +302,25 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange && !mBouncerShowing) { invisible = true; } - setVisibility(invisible ? INVISIBLE : VISIBLE); + boolean wasInvisible = getVisibility() == INVISIBLE; + if (invisible != wasInvisible) { + setVisibility(invisible ? INVISIBLE : VISIBLE); + animate().cancel(); + if (!invisible) { + setScaleX(0); + setScaleY(0); + animate() + .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN) + .scaleX(1) + .scaleY(1) + .withLayer() + .setDuration(233) + .start(); + } + } updateClickability(); + + return true; } private void updateClickability() { @@ -364,30 +381,22 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange return lockAnimIndex == SCANNING; } - private int getAnimationIndexForTransition(int oldState, int newState, - boolean wasPulsing, boolean pulsing, boolean wasDozing, boolean dozing) { + private static int getAnimationIndexForTransition(int oldState, int newState, boolean pulsing, + boolean dozing) { // Never animate when screen is off - if (dozing && !pulsing && !mWasPulsingOnThisFrame) { + if (dozing && !pulsing) { 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) { + if (newState == STATE_BIOMETRICS_ERROR) { return ERROR; - } else if (justUnlocked) { + } else if (oldState != STATE_LOCK_OPEN && newState == STATE_LOCK_OPEN) { return UNLOCK; - } else if (justLocked) { + } else if (oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED) { return LOCK; } else if (newState == STATE_SCANNING_FACE) { return SCANNING; - } else if ((nowPulsing || turningOn) && newState != STATE_LOCK_OPEN) { - return LOCK_IN; } return -1; } @@ -407,37 +416,33 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange } @Retention(RetentionPolicy.SOURCE) - @IntDef({ERROR, UNLOCK, LOCK, SCANNING, LOCK_IN}) + @IntDef({ERROR, UNLOCK, LOCK, SCANNING}) @interface LockAnimIndex {} - private static final int ERROR = 0, UNLOCK = 1, LOCK = 2, SCANNING = 3, LOCK_IN = 4; + private static final int ERROR = 0, UNLOCK = 1, LOCK = 2, SCANNING = 3; private static final int[][] LOCK_ANIM_RES_IDS = new int[][] { { R.anim.lock_to_error, R.anim.lock_unlock, R.anim.lock_lock, - R.anim.lock_scanning, - R.anim.lock_in, + R.anim.lock_scanning }, { R.anim.lock_to_error_circular, R.anim.lock_unlock_circular, R.anim.lock_lock_circular, - R.anim.lock_scanning_circular, - R.anim.lock_in_circular, + R.anim.lock_scanning_circular }, { R.anim.lock_to_error_filled, R.anim.lock_unlock_filled, R.anim.lock_lock_filled, - R.anim.lock_scanning_filled, - R.anim.lock_in_filled, + R.anim.lock_scanning_filled }, { R.anim.lock_to_error_rounded, R.anim.lock_unlock_rounded, R.anim.lock_lock_rounded, - R.anim.lock_scanning_rounded, - R.anim.lock_in_rounded, + R.anim.lock_scanning_rounded }, }; @@ -462,7 +467,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange return STATE_LOCK_OPEN; } else if (mTransientBiometricsError) { return STATE_BIOMETRICS_ERROR; - } else if (updateMonitor.isFaceDetectionRunning()) { + } else if (updateMonitor.isFaceDetectionRunning() && !mPulsing) { return STATE_SCANNING_FACE; } else { return STATE_LOCKED; @@ -481,12 +486,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange */ public void setPulsing(boolean pulsing) { mPulsing = pulsing; - if (!mPulsing) { - mWasPulsingOnThisFrame = true; - mMainHandler.post(() -> { - mWasPulsingOnThisFrame = false; - }); - } update(); } 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 78eb394e33365..f36c56f60965b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java @@ -190,6 +190,11 @@ public class UnlockMethodCache { public void onKeyguardVisibilityChanged(boolean showing) { update(false /* updateAlways */); } + + @Override + public void onBiometricsCleared() { + update(false /* alwaysUpdate */); + } }; public boolean isTrustManaged() {