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() {