Merge changes from topic "b150393918-lock-icon" into rvc-dev am: 2728fa3c52 am: c1c9801bd5 am: a57752f754
Change-Id: Ib532c73528be6d39e1785082ac8a89eb515411b3
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
@@ -30,241 +28,98 @@ import android.os.Trace;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.util.SparseArray;
|
||||
import android.view.ViewTreeObserver.OnPreDrawListener;
|
||||
|
||||
import com.android.internal.graphics.ColorUtils;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.KeyguardAffordanceView;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
||||
import com.android.systemui.statusbar.phone.ScrimController.ScrimVisibility;
|
||||
import com.android.systemui.statusbar.policy.AccessibilityController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* Manages the different states and animations of the unlock icon.
|
||||
*/
|
||||
public class LockIcon extends KeyguardAffordanceView implements
|
||||
ViewTreeObserver.OnPreDrawListener {
|
||||
public class LockIcon extends KeyguardAffordanceView {
|
||||
|
||||
private static final int STATE_LOCKED = 0;
|
||||
private static final int STATE_LOCK_OPEN = 1;
|
||||
private static final int STATE_SCANNING_FACE = 2;
|
||||
private static final int STATE_BIOMETRICS_ERROR = 3;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private final AccessibilityController mAccessibilityController;
|
||||
private final KeyguardStateController mKeyguardStateController;
|
||||
private final KeyguardBypassController mBypassController;
|
||||
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
|
||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||
|
||||
private int mLastState = 0;
|
||||
private boolean mForceUpdate;
|
||||
private boolean mTransientBiometricsError;
|
||||
private boolean mIsFaceUnlockState;
|
||||
private boolean mSimLocked;
|
||||
private int mDensity;
|
||||
static final int STATE_LOCKED = 0;
|
||||
static final int STATE_LOCK_OPEN = 1;
|
||||
static final int STATE_SCANNING_FACE = 2;
|
||||
static final int STATE_BIOMETRICS_ERROR = 3;
|
||||
private float mDozeAmount;
|
||||
private int mIconColor;
|
||||
private StateProvider mStateProvider;
|
||||
private int mOldState;
|
||||
private boolean mPulsing;
|
||||
private boolean mDozing;
|
||||
private boolean mDocked;
|
||||
private boolean mBlockUpdates;
|
||||
private int mIconColor;
|
||||
private float mDozeAmount;
|
||||
private boolean mBouncerShowingScrimmed;
|
||||
private boolean mWakeAndUnlockRunning;
|
||||
private boolean mKeyguardShowing;
|
||||
private boolean mShowingLaunchAffordance;
|
||||
private boolean mKeyguardJustShown;
|
||||
private boolean mUpdatePending;
|
||||
private boolean mBouncerPreHideAnimation;
|
||||
private int mStatusBarState = StatusBarState.SHADE;
|
||||
private final SparseArray<Drawable> mDrawableCache = new SparseArray<>();
|
||||
|
||||
private final KeyguardStateController.Callback mKeyguardMonitorCallback =
|
||||
new KeyguardStateController.Callback() {
|
||||
@Override
|
||||
public void onKeyguardShowingChanged() {
|
||||
boolean force = false;
|
||||
boolean wasShowing = mKeyguardShowing;
|
||||
mKeyguardShowing = mKeyguardStateController.isShowing();
|
||||
if (!wasShowing && mKeyguardShowing && mBlockUpdates) {
|
||||
mBlockUpdates = false;
|
||||
force = true;
|
||||
}
|
||||
if (!wasShowing && mKeyguardShowing) {
|
||||
mKeyguardJustShown = true;
|
||||
}
|
||||
update(force);
|
||||
}
|
||||
private final OnPreDrawListener mOnPreDrawListener = new OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
|
||||
@Override
|
||||
public void onKeyguardFadingAwayChanged() {
|
||||
if (!mKeyguardStateController.isKeyguardFadingAway()) {
|
||||
mBouncerPreHideAnimation = false;
|
||||
if (mBlockUpdates) {
|
||||
mBlockUpdates = false;
|
||||
update(true /* force */);
|
||||
}
|
||||
}
|
||||
}
|
||||
int newState = mStateProvider.getState();
|
||||
Drawable icon = getIcon(newState);
|
||||
setImageDrawable(icon, false);
|
||||
|
||||
@Override
|
||||
public void onUnlockedChanged() {
|
||||
update();
|
||||
}
|
||||
};
|
||||
if (newState == STATE_SCANNING_FACE) {
|
||||
announceForAccessibility(getResources().getString(
|
||||
R.string.accessibility_scanning_face));
|
||||
}
|
||||
|
||||
@Inject
|
||||
public LockIcon(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
|
||||
AccessibilityController accessibilityController,
|
||||
KeyguardBypassController bypassController,
|
||||
NotificationWakeUpCoordinator wakeUpCoordinator,
|
||||
KeyguardStateController keyguardStateController,
|
||||
HeadsUpManagerPhone headsUpManager) {
|
||||
if (icon instanceof AnimatedVectorDrawable) {
|
||||
final AnimatedVectorDrawable animation = (AnimatedVectorDrawable) icon;
|
||||
animation.forceAnimationOnUI();
|
||||
animation.clearAnimationCallbacks();
|
||||
animation.registerAnimationCallback(
|
||||
new Animatable2.AnimationCallback() {
|
||||
@Override
|
||||
public void onAnimationEnd(Drawable drawable) {
|
||||
if (getDrawable() == animation
|
||||
&& newState == mStateProvider.getState()
|
||||
&& newState == STATE_SCANNING_FACE) {
|
||||
animation.start();
|
||||
} else {
|
||||
Trace.endAsyncSection("LockIcon#Animation", newState);
|
||||
}
|
||||
}
|
||||
});
|
||||
Trace.beginAsyncSection("LockIcon#Animation", newState);
|
||||
animation.start();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public LockIcon(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
|
||||
mAccessibilityController = accessibilityController;
|
||||
mBypassController = bypassController;
|
||||
mWakeUpCoordinator = wakeUpCoordinator;
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mHeadsUpManager = headsUpManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mKeyguardStateController.addCallback(mKeyguardMonitorCallback);
|
||||
mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mKeyguardStateController.removeCallback(mKeyguardMonitorCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* If we're currently presenting an authentication error message.
|
||||
*/
|
||||
public void setTransientBiometricsError(boolean transientBiometricsError) {
|
||||
mTransientBiometricsError = transientBiometricsError;
|
||||
update();
|
||||
void setStateProvider(StateProvider stateProvider) {
|
||||
mStateProvider = stateProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
final int density = newConfig.densityDpi;
|
||||
if (density != mDensity) {
|
||||
mDensity = density;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
update(false /* force */);
|
||||
}
|
||||
|
||||
public void update(boolean force) {
|
||||
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;
|
||||
boolean keyguardJustShown = mKeyguardJustShown;
|
||||
mIsFaceUnlockState = state == STATE_SCANNING_FACE;
|
||||
mLastState = state;
|
||||
mKeyguardJustShown = false;
|
||||
|
||||
boolean shouldUpdate = lastState != state || mForceUpdate;
|
||||
if (mBlockUpdates && canBlockUpdates()) {
|
||||
shouldUpdate = false;
|
||||
}
|
||||
if (shouldUpdate) {
|
||||
mForceUpdate = false;
|
||||
@LockAnimIndex final int lockAnimIndex = getAnimationIndexForTransition(lastState,
|
||||
state, mPulsing, mDozing, keyguardJustShown);
|
||||
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();
|
||||
|
||||
updateIconVisibility();
|
||||
updateClickability();
|
||||
|
||||
return true;
|
||||
mDrawableCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the icon visibility
|
||||
* @return true if the visibility changed
|
||||
*/
|
||||
boolean updateIconVisibility() {
|
||||
boolean onAodNotPulsingOrDocked = mDozing && (!mPulsing || mDocked);
|
||||
boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning
|
||||
|| mShowingLaunchAffordance;
|
||||
if (mBypassController.getBypassEnabled() && !mBouncerShowingScrimmed) {
|
||||
if ((mHeadsUpManager.isHeadsUpGoingAway() || mHeadsUpManager.hasPinnedHeadsUp()
|
||||
|| mStatusBarState == StatusBarState.KEYGUARD)
|
||||
&& !mWakeUpCoordinator.getNotificationsFullyHidden()) {
|
||||
invisible = true;
|
||||
}
|
||||
}
|
||||
boolean wasInvisible = getVisibility() == INVISIBLE;
|
||||
if (invisible != wasInvisible) {
|
||||
setVisibility(invisible ? INVISIBLE : VISIBLE);
|
||||
boolean updateIconVisibility(boolean visible) {
|
||||
boolean wasVisible = getVisibility() == VISIBLE;
|
||||
if (visible != wasVisible) {
|
||||
setVisibility(visible ? VISIBLE : INVISIBLE);
|
||||
animate().cancel();
|
||||
if (!invisible) {
|
||||
if (visible) {
|
||||
setScaleX(0);
|
||||
setScaleY(0);
|
||||
animate()
|
||||
@@ -280,49 +135,47 @@ public class LockIcon extends KeyguardAffordanceView implements
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean canBlockUpdates() {
|
||||
return mKeyguardShowing || mKeyguardStateController.isKeyguardFadingAway();
|
||||
void update(int oldState, boolean pulsing, boolean dozing, boolean keyguardJustShown) {
|
||||
mOldState = oldState;
|
||||
mPulsing = pulsing;
|
||||
mDozing = dozing;
|
||||
mKeyguardJustShown = keyguardJustShown;
|
||||
|
||||
getViewTreeObserver().addOnPreDrawListener(mOnPreDrawListener);
|
||||
}
|
||||
|
||||
private void updateClickability() {
|
||||
if (mAccessibilityController == null) {
|
||||
return;
|
||||
void setDozeAmount(float dozeAmount) {
|
||||
mDozeAmount = dozeAmount;
|
||||
updateDarkTint();
|
||||
}
|
||||
|
||||
void onThemeChange(int iconColor) {
|
||||
mDrawableCache.clear();
|
||||
mIconColor = iconColor;
|
||||
updateDarkTint();
|
||||
}
|
||||
|
||||
private void updateDarkTint() {
|
||||
int color = ColorUtils.blendARGB(mIconColor, Color.WHITE, mDozeAmount);
|
||||
setImageTintList(ColorStateList.valueOf(color));
|
||||
}
|
||||
|
||||
private Drawable getIcon(int newState) {
|
||||
@LockAnimIndex final int lockAnimIndex =
|
||||
getAnimationIndexForTransition(mOldState, newState, mPulsing, mDozing,
|
||||
mKeyguardJustShown);
|
||||
|
||||
boolean isAnim = lockAnimIndex != -1;
|
||||
int iconRes = isAnim ? getThemedAnimationResId(lockAnimIndex) : getIconForState(newState);
|
||||
|
||||
if (!mDrawableCache.contains(iconRes)) {
|
||||
mDrawableCache.put(iconRes, getResources().getDrawable(iconRes));
|
||||
}
|
||||
boolean canLock = mKeyguardStateController.isMethodSecure()
|
||||
&& mKeyguardStateController.canDismissLockScreen();
|
||||
boolean clickToUnlock = mAccessibilityController.isAccessibilityEnabled();
|
||||
setClickable(clickToUnlock);
|
||||
setLongClickable(canLock && !clickToUnlock);
|
||||
setFocusable(mAccessibilityController.isAccessibilityEnabled());
|
||||
|
||||
return mDrawableCache.get(iconRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
boolean fingerprintRunning = mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
|
||||
// Only checking if unlocking with Biometric is allowed (no matter strong or non-strong
|
||||
// as long as primary auth, i.e. PIN/pattern/password, is not required), so it's ok to
|
||||
// pass true for isStrongBiometric to isUnlockingWithBiometricAllowed() to bypass the
|
||||
// check of whether non-strong biometric is allowed
|
||||
boolean unlockingAllowed = mKeyguardUpdateMonitor
|
||||
.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */);
|
||||
if (fingerprintRunning && unlockingAllowed) {
|
||||
AccessibilityNodeInfo.AccessibilityAction unlock
|
||||
= new AccessibilityNodeInfo.AccessibilityAction(
|
||||
AccessibilityNodeInfo.ACTION_CLICK,
|
||||
getContext().getString(R.string.accessibility_unlock_without_fingerprint));
|
||||
info.addAction(unlock);
|
||||
info.setHintText(getContext().getString(
|
||||
R.string.accessibility_waiting_for_fingerprint));
|
||||
} else if (mIsFaceUnlockState) {
|
||||
//Avoid 'button' to be spoken for scanning face
|
||||
info.setClassName(LockIcon.class.getName());
|
||||
info.setContentDescription(getContext().getString(
|
||||
R.string.accessibility_scanning_face));
|
||||
}
|
||||
}
|
||||
|
||||
private int getIconForState(int state) {
|
||||
static int getIconForState(int state) {
|
||||
int iconRes;
|
||||
switch (state) {
|
||||
case STATE_LOCKED:
|
||||
@@ -343,11 +196,7 @@ public class LockIcon extends KeyguardAffordanceView implements
|
||||
return iconRes;
|
||||
}
|
||||
|
||||
private boolean doesAnimationLoop(@LockAnimIndex int lockAnimIndex) {
|
||||
return lockAnimIndex == SCANNING;
|
||||
}
|
||||
|
||||
private static int getAnimationIndexForTransition(int oldState, int newState, boolean pulsing,
|
||||
static int getAnimationIndexForTransition(int oldState, int newState, boolean pulsing,
|
||||
boolean dozing, boolean keyguardJustShown) {
|
||||
|
||||
// Never animate when screen is off
|
||||
@@ -367,42 +216,10 @@ public class LockIcon extends KeyguardAffordanceView implements
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void setBouncerShowingScrimmed(boolean bouncerShowing) {
|
||||
mBouncerShowingScrimmed = bouncerShowing;
|
||||
if (mBypassController.getBypassEnabled()) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate padlock opening when bouncer challenge is solved.
|
||||
*/
|
||||
public void onBouncerPreHideAnimation() {
|
||||
mBouncerPreHideAnimation = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void setIconColor(int iconColor) {
|
||||
mIconColor = iconColor;
|
||||
updateDarkTint();
|
||||
}
|
||||
|
||||
void setSimLocked(boolean simLocked) {
|
||||
mSimLocked = simLocked;
|
||||
}
|
||||
|
||||
/** Set if the device is docked. */
|
||||
public void setDocked(boolean docked) {
|
||||
if (mDocked != docked) {
|
||||
mDocked = docked;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({ERROR, UNLOCK, LOCK, SCANNING})
|
||||
@interface LockAnimIndex {}
|
||||
private static final int ERROR = 0, UNLOCK = 1, LOCK = 2, SCANNING = 3;
|
||||
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,
|
||||
@@ -433,7 +250,7 @@ public class LockIcon extends KeyguardAffordanceView implements
|
||||
private int getThemedAnimationResId(@LockAnimIndex int lockAnimIndex) {
|
||||
final String setting = TextUtils.emptyIfNull(
|
||||
Settings.Secure.getString(getContext().getContentResolver(),
|
||||
Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES));
|
||||
Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES));
|
||||
if (setting.contains("com.android.theme.icon_pack.circular.android")) {
|
||||
return LOCK_ANIM_RES_IDS[1][lockAnimIndex];
|
||||
} else if (setting.contains("com.android.theme.icon_pack.filled.android")) {
|
||||
@@ -444,83 +261,8 @@ public class LockIcon extends KeyguardAffordanceView implements
|
||||
return LOCK_ANIM_RES_IDS[0][lockAnimIndex];
|
||||
}
|
||||
|
||||
private int getState() {
|
||||
KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
|
||||
if ((mKeyguardStateController.canDismissLockScreen() || !mKeyguardShowing
|
||||
|| mKeyguardStateController.isKeyguardGoingAway()) && !mSimLocked) {
|
||||
return STATE_LOCK_OPEN;
|
||||
} else if (mTransientBiometricsError) {
|
||||
return STATE_BIOMETRICS_ERROR;
|
||||
} else if (updateMonitor.isFaceDetectionRunning() && !mPulsing) {
|
||||
return STATE_SCANNING_FACE;
|
||||
} else {
|
||||
return STATE_LOCKED;
|
||||
}
|
||||
interface StateProvider {
|
||||
int getState();
|
||||
}
|
||||
|
||||
/**
|
||||
* When keyguard is in pulsing (AOD2) state.
|
||||
* @param pulsing {@code true} when pulsing.
|
||||
*/
|
||||
public void setPulsing(boolean pulsing) {
|
||||
mPulsing = pulsing;
|
||||
update();
|
||||
}
|
||||
|
||||
private void updateDarkTint() {
|
||||
int color = ColorUtils.blendARGB(mIconColor, Color.WHITE, mDozeAmount);
|
||||
setImageTintList(ColorStateList.valueOf(color));
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to hide the lock whenever there's a fingerprint unlock, otherwise you'll see the
|
||||
* icon on top of the black front scrim.
|
||||
* @param wakeAndUnlock are we wake and unlocking
|
||||
* @param isUnlock are we currently unlocking
|
||||
*/
|
||||
public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
|
||||
if (wakeAndUnlock) {
|
||||
mWakeAndUnlockRunning = true;
|
||||
}
|
||||
if (isUnlock && mBypassController.getBypassEnabled() && canBlockUpdates()) {
|
||||
// We don't want the icon to change while we are unlocking
|
||||
mBlockUpdates = true;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* When we're launching an affordance, like double pressing power to open camera.
|
||||
*/
|
||||
public void onShowingLaunchAffordanceChanged(boolean showing) {
|
||||
mShowingLaunchAffordance = showing;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever the scrims become opaque, transparent or semi-transparent.
|
||||
*/
|
||||
public void onScrimVisibilityChanged(@ScrimVisibility int scrimsVisible) {
|
||||
if (mWakeAndUnlockRunning
|
||||
&& scrimsVisible == ScrimController.TRANSPARENT) {
|
||||
mWakeAndUnlockRunning = false;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void setDozing(boolean dozing) {
|
||||
mDozing = dozing;
|
||||
update();
|
||||
}
|
||||
|
||||
void setDozeAmount(float dozeAmount) {
|
||||
mDozeAmount = dozeAmount;
|
||||
updateDarkTint();
|
||||
}
|
||||
|
||||
/** Set the StatusBarState. */
|
||||
public void setStatusBarState(int statusBarState) {
|
||||
mStatusBarState = statusBarState;
|
||||
updateIconVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,19 @@
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import static com.android.systemui.statusbar.phone.LockIcon.STATE_BIOMETRICS_ERROR;
|
||||
import static com.android.systemui.statusbar.phone.LockIcon.STATE_LOCKED;
|
||||
import static com.android.systemui.statusbar.phone.LockIcon.STATE_LOCK_OPEN;
|
||||
import static com.android.systemui.statusbar.phone.LockIcon.STATE_SCANNING_FACE;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.biometrics.BiometricSourceType;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -29,15 +37,18 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.KeyguardIndicationController;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator.WakeUpListener;
|
||||
import com.android.systemui.statusbar.policy.AccessibilityController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -59,6 +70,21 @@ public class LockscreenLockIconController {
|
||||
private final NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
|
||||
private final KeyguardBypassController mKeyguardBypassController;
|
||||
private final Optional<DockManager> mDockManager;
|
||||
private final KeyguardStateController mKeyguardStateController;
|
||||
private final Resources mResources;
|
||||
private final HeadsUpManagerPhone mHeadsUpManagerPhone;
|
||||
private boolean mKeyguardShowing;
|
||||
private boolean mKeyguardJustShown;
|
||||
private boolean mBlockUpdates;
|
||||
private boolean mPulsing;
|
||||
private boolean mDozing;
|
||||
private boolean mSimLocked;
|
||||
private boolean mTransientBiometricsError;
|
||||
private boolean mDocked;
|
||||
private boolean mWakeAndUnlockRunning;
|
||||
private boolean mShowingLaunchAffordance;
|
||||
private boolean mBouncerShowingScrimmed;
|
||||
private int mStatusBarState = StatusBarState.SHADE;
|
||||
private LockIcon mLockIcon;
|
||||
|
||||
private View.OnAttachStateChangeListener mOnAttachStateChangeListener =
|
||||
@@ -69,10 +95,13 @@ public class LockscreenLockIconController {
|
||||
mConfigurationController.addCallback(mConfigurationListener);
|
||||
mNotificationWakeUpCoordinator.addListener(mWakeUpListener);
|
||||
mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
|
||||
mKeyguardStateController.addCallback(mKeyguardMonitorCallback);
|
||||
|
||||
mDockManager.ifPresent(dockManager -> dockManager.addListener(mDockEventListener));
|
||||
|
||||
mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
|
||||
mConfigurationListener.onThemeChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,7 +110,7 @@ public class LockscreenLockIconController {
|
||||
mConfigurationController.removeCallback(mConfigurationListener);
|
||||
mNotificationWakeUpCoordinator.removeListener(mWakeUpListener);
|
||||
mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
|
||||
|
||||
mKeyguardStateController.removeCallback(mKeyguardMonitorCallback);
|
||||
|
||||
mDockManager.ifPresent(dockManager -> dockManager.removeListener(mDockEventListener));
|
||||
}
|
||||
@@ -91,32 +120,44 @@ public class LockscreenLockIconController {
|
||||
new StatusBarStateController.StateListener() {
|
||||
@Override
|
||||
public void onDozingChanged(boolean isDozing) {
|
||||
mLockIcon.setDozing(isDozing);
|
||||
setDozing(isDozing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDozeAmountChanged(float linear, float eased) {
|
||||
mLockIcon.setDozeAmount(eased);
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.setDozeAmount(eased);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int newState) {
|
||||
mLockIcon.setStatusBarState(newState);
|
||||
setStatusBarState(newState);
|
||||
}
|
||||
};
|
||||
|
||||
private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
|
||||
private int mDensity;
|
||||
|
||||
@Override
|
||||
public void onThemeChanged() {
|
||||
if (mLockIcon == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TypedArray typedArray = mLockIcon.getContext().getTheme().obtainStyledAttributes(
|
||||
null, new int[]{ R.attr.wallpaperTextColor }, 0, 0);
|
||||
int iconColor = typedArray.getColor(0, Color.WHITE);
|
||||
typedArray.recycle();
|
||||
mLockIcon.setIconColor(iconColor);
|
||||
mLockIcon.onThemeChange(iconColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
if (mLockIcon == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ViewGroup.LayoutParams lp = mLockIcon.getLayoutParams();
|
||||
if (lp == null) {
|
||||
return;
|
||||
@@ -125,24 +166,41 @@ public class LockscreenLockIconController {
|
||||
lp.height = mLockIcon.getResources().getDimensionPixelSize(
|
||||
R.dimen.keyguard_lock_height);
|
||||
mLockIcon.setLayoutParams(lp);
|
||||
mLockIcon.update(true /* force */);
|
||||
update(true /* force */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocaleListChanged() {
|
||||
if (mLockIcon == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mLockIcon.setContentDescription(
|
||||
mLockIcon.getResources().getText(R.string.accessibility_unlock_button));
|
||||
mLockIcon.update(true /* force */);
|
||||
update(true /* force */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigChanged(Configuration newConfig) {
|
||||
final int density = newConfig.densityDpi;
|
||||
if (density != mDensity) {
|
||||
mDensity = density;
|
||||
update();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final WakeUpListener mWakeUpListener = new WakeUpListener() {
|
||||
@Override
|
||||
public void onPulseExpansionChanged(boolean expandingChanged) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFullyHiddenChanged(boolean isFullyHidden) {
|
||||
if (mKeyguardBypassController.getBypassEnabled()) {
|
||||
boolean changed = mLockIcon.updateIconVisibility();
|
||||
boolean changed = updateIconVisibility();
|
||||
if (changed) {
|
||||
mLockIcon.update();
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,30 +210,103 @@ public class LockscreenLockIconController {
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onSimStateChanged(int subId, int slotId, int simState) {
|
||||
mLockIcon.setSimLocked(mKeyguardUpdateMonitor.isSimPinSecure());
|
||||
mLockIcon.update();
|
||||
mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyguardVisibilityChanged(boolean showing) {
|
||||
mLockIcon.update();
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBiometricRunningStateChanged(boolean running,
|
||||
BiometricSourceType biometricSourceType) {
|
||||
mLockIcon.update();
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStrongAuthStateChanged(int userId) {
|
||||
mLockIcon.update();
|
||||
update();
|
||||
}
|
||||
};
|
||||
|
||||
private final DockManager.DockEventListener mDockEventListener =
|
||||
event -> mLockIcon.setDocked(event == DockManager.STATE_DOCKED
|
||||
|| event == DockManager.STATE_DOCKED_HIDE);
|
||||
event -> {
|
||||
boolean docked =
|
||||
event == DockManager.STATE_DOCKED || event == DockManager.STATE_DOCKED_HIDE;
|
||||
if (docked != mDocked) {
|
||||
mDocked = docked;
|
||||
update();
|
||||
}
|
||||
};
|
||||
|
||||
private final KeyguardStateController.Callback mKeyguardMonitorCallback =
|
||||
new KeyguardStateController.Callback() {
|
||||
@Override
|
||||
public void onKeyguardShowingChanged() {
|
||||
boolean force = false;
|
||||
boolean wasShowing = mKeyguardShowing;
|
||||
mKeyguardShowing = mKeyguardStateController.isShowing();
|
||||
if (!wasShowing && mKeyguardShowing && mBlockUpdates) {
|
||||
mBlockUpdates = false;
|
||||
force = true;
|
||||
}
|
||||
if (!wasShowing && mKeyguardShowing) {
|
||||
mKeyguardJustShown = true;
|
||||
}
|
||||
update(force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyguardFadingAwayChanged() {
|
||||
if (!mKeyguardStateController.isKeyguardFadingAway()) {
|
||||
if (mBlockUpdates) {
|
||||
mBlockUpdates = false;
|
||||
update(true /* force */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnlockedChanged() {
|
||||
update();
|
||||
}
|
||||
};
|
||||
|
||||
private final View.AccessibilityDelegate mAccessibilityDelegate =
|
||||
new View.AccessibilityDelegate() {
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(View host,
|
||||
AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(host, info);
|
||||
boolean fingerprintRunning =
|
||||
mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
|
||||
// Only checking if unlocking with Biometric is allowed (no matter strong or
|
||||
// non-strong as long as primary auth, i.e. PIN/pattern/password, is not
|
||||
// required), so it's ok to pass true for isStrongBiometric to
|
||||
// isUnlockingWithBiometricAllowed() to bypass the check of whether non-strong
|
||||
// biometric is allowed
|
||||
boolean unlockingAllowed = mKeyguardUpdateMonitor
|
||||
.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */);
|
||||
if (fingerprintRunning && unlockingAllowed) {
|
||||
AccessibilityNodeInfo.AccessibilityAction unlock =
|
||||
new AccessibilityNodeInfo.AccessibilityAction(
|
||||
AccessibilityNodeInfo.ACTION_CLICK,
|
||||
mResources.getString(
|
||||
R.string.accessibility_unlock_without_fingerprint));
|
||||
info.addAction(unlock);
|
||||
info.setHintText(mResources.getString(
|
||||
R.string.accessibility_waiting_for_fingerprint));
|
||||
} else if (getState() == STATE_SCANNING_FACE) {
|
||||
//Avoid 'button' to be spoken for scanning face
|
||||
info.setClassName(LockIcon.class.getName());
|
||||
info.setContentDescription(mResources.getString(
|
||||
R.string.accessibility_scanning_face));
|
||||
}
|
||||
}
|
||||
};
|
||||
private int mLastState;
|
||||
|
||||
@Inject
|
||||
public LockscreenLockIconController(LockscreenGestureLogger lockscreenGestureLogger,
|
||||
@@ -188,7 +319,10 @@ public class LockscreenLockIconController {
|
||||
ConfigurationController configurationController,
|
||||
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
|
||||
KeyguardBypassController keyguardBypassController,
|
||||
@Nullable DockManager dockManager) {
|
||||
@Nullable DockManager dockManager,
|
||||
KeyguardStateController keyguardStateController,
|
||||
@Main Resources resources,
|
||||
HeadsUpManagerPhone headsUpManagerPhone) {
|
||||
mLockscreenGestureLogger = lockscreenGestureLogger;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
@@ -200,24 +334,31 @@ public class LockscreenLockIconController {
|
||||
mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
|
||||
mKeyguardBypassController = keyguardBypassController;
|
||||
mDockManager = dockManager == null ? Optional.empty() : Optional.of(dockManager);
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mResources = resources;
|
||||
mHeadsUpManagerPhone = headsUpManagerPhone;
|
||||
|
||||
mKeyguardIndicationController.setLockIconController(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate the controller with a {@link LockIcon}
|
||||
*
|
||||
* TODO: change to an init method and inject the view.
|
||||
*/
|
||||
public void attach(LockIcon lockIcon) {
|
||||
mLockIcon = lockIcon;
|
||||
|
||||
mLockIcon.setOnClickListener(this::handleClick);
|
||||
mLockIcon.setOnLongClickListener(this::handleLongClick);
|
||||
mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate);
|
||||
mLockIcon.setStateProvider(this::getState);
|
||||
|
||||
if (mLockIcon.isAttachedToWindow()) {
|
||||
mOnAttachStateChangeListener.onViewAttachedToWindow(mLockIcon);
|
||||
}
|
||||
mLockIcon.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
|
||||
mLockIcon.setStatusBarState(mStatusBarStateController.getState());
|
||||
setStatusBarState(mStatusBarStateController.getState());
|
||||
}
|
||||
|
||||
public LockIcon getView() {
|
||||
@@ -228,8 +369,10 @@ public class LockscreenLockIconController {
|
||||
* Called whenever the scrims become opaque, transparent or semi-transparent.
|
||||
*/
|
||||
public void onScrimVisibilityChanged(Integer scrimsVisible) {
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.onScrimVisibilityChanged(scrimsVisible);
|
||||
if (mWakeAndUnlockRunning
|
||||
&& scrimsVisible == ScrimController.TRANSPARENT) {
|
||||
mWakeAndUnlockRunning = false;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,55 +380,56 @@ public class LockscreenLockIconController {
|
||||
* Propagate {@link StatusBar} pulsing state.
|
||||
*/
|
||||
public void setPulsing(boolean pulsing) {
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.setPulsing(pulsing);
|
||||
}
|
||||
mPulsing = pulsing;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the biometric authentication mode changes.
|
||||
*
|
||||
* @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()}
|
||||
* @param isUnlock If the type is {@link BiometricUnlockController#isBiometricUnlock()} ()
|
||||
* We need to hide the lock whenever there's a fingerprint unlock, otherwise you'll see the
|
||||
* icon on top of the black front scrim.
|
||||
* @param wakeAndUnlock are we wake and unlocking
|
||||
* @param isUnlock are we currently unlocking
|
||||
*/
|
||||
public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock);
|
||||
if (wakeAndUnlock) {
|
||||
mWakeAndUnlockRunning = true;
|
||||
}
|
||||
if (isUnlock && mKeyguardBypassController.getBypassEnabled() && canBlockUpdates()) {
|
||||
// We don't want the icon to change while we are unlocking
|
||||
mBlockUpdates = true;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* When we're launching an affordance, like double pressing power to open camera.
|
||||
*/
|
||||
public void onShowingLaunchAffordanceChanged(Boolean showing) {
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.onShowingLaunchAffordanceChanged(showing);
|
||||
}
|
||||
mShowingLaunchAffordance = showing;
|
||||
update();
|
||||
}
|
||||
|
||||
/** Sets whether the bouncer is showing. */
|
||||
public void setBouncerShowingScrimmed(boolean bouncerShowing) {
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
|
||||
mBouncerShowingScrimmed = bouncerShowing;
|
||||
if (mKeyguardBypassController.getBypassEnabled()) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When {@link KeyguardBouncer} starts to be dismissed and starts to play its animation.
|
||||
* Animate padlock opening when bouncer challenge is solved.
|
||||
*/
|
||||
public void onBouncerPreHideAnimation() {
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.onBouncerPreHideAnimation();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* If we're currently presenting an authentication error message.
|
||||
*/
|
||||
public void setTransientBiometricsError(boolean transientBiometricsError) {
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.setTransientBiometricsError(transientBiometricsError);
|
||||
}
|
||||
mTransientBiometricsError = transientBiometricsError;
|
||||
update();
|
||||
}
|
||||
|
||||
private boolean handleLongClick(View view) {
|
||||
@@ -306,4 +450,90 @@ public class LockscreenLockIconController {
|
||||
}
|
||||
mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
|
||||
}
|
||||
|
||||
private void update() {
|
||||
update(false /* force */);
|
||||
}
|
||||
|
||||
private void update(boolean force) {
|
||||
int state = getState();
|
||||
boolean shouldUpdate = mLastState != state || force;
|
||||
if (mBlockUpdates && canBlockUpdates()) {
|
||||
shouldUpdate = false;
|
||||
}
|
||||
if (shouldUpdate && mLockIcon != null) {
|
||||
mLockIcon.update(mLastState, mPulsing, mDozing, mKeyguardJustShown);
|
||||
}
|
||||
mLastState = state;
|
||||
mKeyguardJustShown = false;
|
||||
updateIconVisibility();
|
||||
updateClickability();
|
||||
}
|
||||
|
||||
private int getState() {
|
||||
if ((mKeyguardStateController.canDismissLockScreen() || !mKeyguardShowing
|
||||
|| mKeyguardStateController.isKeyguardGoingAway()) && !mSimLocked) {
|
||||
return STATE_LOCK_OPEN;
|
||||
} else if (mTransientBiometricsError) {
|
||||
return STATE_BIOMETRICS_ERROR;
|
||||
} else if (mKeyguardUpdateMonitor.isFaceDetectionRunning() && !mPulsing) {
|
||||
return STATE_SCANNING_FACE;
|
||||
} else {
|
||||
return STATE_LOCKED;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canBlockUpdates() {
|
||||
return mKeyguardShowing || mKeyguardStateController.isKeyguardFadingAway();
|
||||
}
|
||||
|
||||
private void setDozing(boolean isDozing) {
|
||||
mDozing = isDozing;
|
||||
update();
|
||||
}
|
||||
|
||||
/** Set the StatusBarState. */
|
||||
private void setStatusBarState(int statusBarState) {
|
||||
mStatusBarState = statusBarState;
|
||||
updateIconVisibility();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the icon visibility
|
||||
* @return true if the visibility changed
|
||||
*/
|
||||
private boolean updateIconVisibility() {
|
||||
boolean onAodNotPulsingOrDocked = mDozing && (!mPulsing || mDocked);
|
||||
boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning
|
||||
|| mShowingLaunchAffordance;
|
||||
if (mKeyguardBypassController.getBypassEnabled() && !mBouncerShowingScrimmed) {
|
||||
if ((mHeadsUpManagerPhone.isHeadsUpGoingAway()
|
||||
|| mHeadsUpManagerPhone.hasPinnedHeadsUp()
|
||||
|| mStatusBarState == StatusBarState.KEYGUARD)
|
||||
&& !mNotificationWakeUpCoordinator.getNotificationsFullyHidden()) {
|
||||
invisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mLockIcon == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mLockIcon.updateIconVisibility(!invisible);
|
||||
}
|
||||
|
||||
private void updateClickability() {
|
||||
if (mAccessibilityController == null) {
|
||||
return;
|
||||
}
|
||||
boolean canLock = mKeyguardStateController.isMethodSecure()
|
||||
&& mKeyguardStateController.canDismissLockScreen();
|
||||
boolean clickToUnlock = mAccessibilityController.isAccessibilityEnabled();
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.setClickable(clickToUnlock);
|
||||
mLockIcon.setLongClickable(canLock && !clickToUnlock);
|
||||
mLockIcon.setFocusable(mAccessibilityController.isAccessibilityEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.android.systemui.qs.QuickStatusBarHeader;
|
||||
import com.android.systemui.qs.customize.QSCustomizer;
|
||||
import com.android.systemui.statusbar.NotificationShelf;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
||||
import com.android.systemui.statusbar.phone.LockIcon;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -147,11 +146,6 @@ public class InjectionInflationController {
|
||||
*/
|
||||
KeyguardMessageArea createKeyguardMessageArea();
|
||||
|
||||
/**
|
||||
* Creates the keyguard LockIcon.
|
||||
*/
|
||||
LockIcon createLockIcon();
|
||||
|
||||
/**
|
||||
* Creates the QSPanel.
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -35,6 +36,7 @@ import com.android.systemui.statusbar.KeyguardIndicationController;
|
||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
||||
import com.android.systemui.statusbar.policy.AccessibilityController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -71,6 +73,12 @@ public class LockscreenIconControllerTest extends SysuiTestCase {
|
||||
private KeyguardBypassController mKeyguardBypassController;
|
||||
@Mock
|
||||
private DockManager mDockManager;
|
||||
@Mock
|
||||
private KeyguardStateController mKeyguardStateController;
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
@Mock
|
||||
private HeadsUpManagerPhone mHeadsUpManagerPhone;
|
||||
|
||||
|
||||
@Before
|
||||
@@ -81,7 +89,8 @@ public class LockscreenIconControllerTest extends SysuiTestCase {
|
||||
mLockscreenGestureLogger, mKeyguardUpdateMonitor, mLockPatternUtils,
|
||||
mShadeController, mAccessibilityController, mKeyguardIndicationController,
|
||||
mStatusBarStateController, mConfigurationController, mNotificationWakeUpCoordinator,
|
||||
mKeyguardBypassController, mDockManager);
|
||||
mKeyguardBypassController, mDockManager, mKeyguardStateController, mResources,
|
||||
mHeadsUpManagerPhone);
|
||||
|
||||
mLockIconController.attach(mLockIcon);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user