[DO NOT MERGE] Show UDFPS icon on AOD even if fp auth isn't running

* shows udfps if it's enrolled on AOD even if:
   * device requires strong auth (ie: after reboot, lockdown)
   * device is unlocked via smart lock

On click of the udfps icon in the above cases:
  * If the device is locked, the bouncer will show.
  * If the device is unlocked, the user will enter the device.

Fixes: 198315404
Test: manual
Change-Id: Id766df8f77427ae1db672507716bd38dc3462452
This commit is contained in:
Beverly
2021-09-13 17:25:00 -04:00
committed by Matt Pietal
parent 906b2ed5a1
commit e5be111dc4
10 changed files with 174 additions and 28 deletions

View File

@@ -70,6 +70,19 @@
android:padding="@dimen/lock_icon_padding"
android:layout_gravity="center"
android:scaleType="centerCrop"/>
<!-- Fingerprint -->
<!-- AOD dashed fingerprint icon with moving dashes -->
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lock_udfps_aod_fp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/lock_icon_padding"
android:layout_gravity="center"
android:scaleType="centerCrop"
systemui:lottie_autoPlay="false"
systemui:lottie_loop="true"
systemui:lottie_rawRes="@raw/udfps_aod_fp"/>
</com.android.keyguard.LockIconView>
<com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer

View File

@@ -45,7 +45,7 @@ public class LockIconView extends FrameLayout implements Dumpable {
private int mRadius;
private ImageView mLockIcon;
private ImageView mUnlockBgView;
private ImageView mBgView;
private int mLockIconColor;
@@ -58,19 +58,19 @@ public class LockIconView extends FrameLayout implements Dumpable {
public void onFinishInflate() {
super.onFinishInflate();
mLockIcon = findViewById(R.id.lock_icon);
mUnlockBgView = findViewById(R.id.lock_icon_bg);
mBgView = findViewById(R.id.lock_icon_bg);
}
void updateColorAndBackgroundVisibility(boolean useBackground) {
if (useBackground) {
if (useBackground && mLockIcon.getDrawable() != null) {
mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
android.R.attr.textColorPrimary);
mUnlockBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
mUnlockBgView.setVisibility(View.VISIBLE);
mBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
mBgView.setVisibility(View.VISIBLE);
} else {
mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
R.attr.wallpaperTextColorAccent);
mUnlockBgView.setVisibility(View.GONE);
mBgView.setVisibility(View.GONE);
}
mLockIcon.setImageTintList(ColorStateList.valueOf(mLockIconColor));
@@ -78,6 +78,11 @@ public class LockIconView extends FrameLayout implements Dumpable {
void setImageDrawable(Drawable drawable) {
mLockIcon.setImageDrawable(drawable);
if (drawable == null) {
mBgView.setVisibility(View.INVISIBLE);
} else {
mBgView.setVisibility(View.VISIBLE);
}
}
/**

View File

@@ -19,6 +19,8 @@ package com.android.keyguard;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
import static com.android.systemui.classifier.Classifier.LOCK_ICON;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOffset;
import android.content.Context;
import android.content.res.Configuration;
@@ -32,6 +34,7 @@ import android.media.AudioAttributes;
import android.os.Process;
import android.os.Vibrator;
import android.util.DisplayMetrics;
import android.util.MathUtils;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
@@ -59,6 +62,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.airbnb.lottie.LottieAnimationView;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Objects;
@@ -94,6 +99,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
@NonNull private final DelayableExecutor mExecutor;
private boolean mUdfpsEnrolled;
@NonNull private LottieAnimationView mAodFp;
@NonNull private final AnimatedVectorDrawable mFpToUnlockIcon;
@NonNull private final AnimatedVectorDrawable mLockToUnlockIcon;
@NonNull private final Drawable mLockIcon;
@@ -112,6 +119,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
private boolean mIsKeyguardShowing;
private boolean mUserUnlockedWithBiometric;
private Runnable mCancelDelayedUpdateVisibilityRunnable;
private Runnable mOnGestureDetectedRunnable;
private boolean mUdfpsSupported;
private float mHeightPixels;
@@ -121,6 +129,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
private boolean mShowUnlockIcon;
private boolean mShowLockIcon;
// for udfps when strong auth is required or unlocked on AOD
private boolean mShowAODFpIcon;
private final int mMaxBurnInOffsetX;
private final int mMaxBurnInOffsetY;
private float mInterpolatedDarkAmount;
private boolean mDownDetected;
private boolean mDetectedLongPress;
private final Rect mSensorTouchLocation = new Rect();
@@ -155,6 +169,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mAuthRippleController = authRippleController;
final Context context = view.getContext();
mAodFp = mView.findViewById(R.id.lock_udfps_aod_fp);
mMaxBurnInOffsetX = context.getResources()
.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x);
mMaxBurnInOffsetY = context.getResources()
.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);
mUnlockIcon = mView.getContext().getResources().getDrawable(
R.drawable.ic_unlock,
mView.getContext().getTheme());
@@ -173,19 +193,19 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
@Override
protected void onInit() {
mAuthController.addCallback(mAuthControllerCallback);
mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null;
mView.setAccessibilityDelegate(mAccessibilityDelegate);
}
@Override
protected void onViewAttached() {
updateIsUdfpsEnrolled();
updateConfiguration();
updateKeyguardShowing();
mUserUnlockedWithBiometric = false;
mIsBouncerShowing = mKeyguardViewController.isBouncerShowing();
mIsDozing = mStatusBarStateController.isDozing();
mInterpolatedDarkAmount = mStatusBarStateController.getDozeAmount();
mRunningFPS = mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen();
mStatusBarState = mStatusBarStateController.getState();
@@ -193,15 +213,18 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
updateColors();
mConfigurationController.addCallback(mConfigurationListener);
mAuthController.addCallback(mAuthControllerCallback);
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
mStatusBarStateController.addCallback(mStatusBarStateListener);
mKeyguardStateController.addCallback(mKeyguardStateCallback);
mDownDetected = false;
updateBurnInOffsets();
updateVisibility();
}
@Override
protected void onViewDetached() {
mAuthController.removeCallback(mAuthControllerCallback);
mConfigurationController.removeCallback(mConfigurationListener);
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
@@ -231,7 +254,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mCancelDelayedUpdateVisibilityRunnable = null;
}
if (!mIsKeyguardShowing) {
if (!mIsKeyguardShowing && !mIsDozing) {
mView.setVisibility(View.INVISIBLE);
return;
}
@@ -242,6 +265,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mShowLockIcon = !mCanDismissLockScreen && !mUserUnlockedWithBiometric && isLockScreen()
&& (!mUdfpsEnrolled || !mRunningFPS);
mShowUnlockIcon = mCanDismissLockScreen && isLockScreen();
mShowAODFpIcon = mIsDozing && mUdfpsEnrolled && !mRunningFPS;
final CharSequence prevContentDescription = mView.getContentDescription();
if (mShowLockIcon) {
@@ -264,10 +288,22 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
}
mView.setVisibility(View.VISIBLE);
mView.setContentDescription(mUnlockedLabel);
} else if (mShowAODFpIcon) {
mView.setImageDrawable(null);
mView.setContentDescription(null);
mAodFp.setVisibility(View.VISIBLE);
mAodFp.setContentDescription(mCanDismissLockScreen ? mUnlockedLabel : mLockedLabel);
mView.setVisibility(View.VISIBLE);
} else {
mView.setVisibility(View.INVISIBLE);
mView.setContentDescription(null);
}
if (!mShowAODFpIcon) {
mAodFp.setVisibility(View.INVISIBLE);
mAodFp.setContentDescription(null);
}
if (!Objects.equals(prevContentDescription, mView.getContentDescription())
&& mView.getContentDescription() != null) {
mView.announceForAccessibility(mView.getContentDescription());
@@ -344,10 +380,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
@Override
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("mUdfpsSupported: " + mUdfpsSupported);
pw.println("mUdfpsEnrolled: " + mUdfpsEnrolled);
pw.println("mIsKeyguardShowing: " + mIsKeyguardShowing);
pw.println(" mShowUnlockIcon: " + mShowUnlockIcon);
pw.println(" mShowLockIcon: " + mShowLockIcon);
pw.println(" mShowAODFpIcon: " + mShowAODFpIcon);
pw.println(" mIsDozing: " + mIsDozing);
pw.println(" mIsBouncerShowing: " + mIsBouncerShowing);
pw.println(" mUserUnlockedWithBiometric: " + mUserUnlockedWithBiometric);
@@ -355,17 +393,57 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
pw.println(" mCanDismissLockScreen: " + mCanDismissLockScreen);
pw.println(" mStatusBarState: " + StatusBarState.toShortString(mStatusBarState));
pw.println(" mQsExpanded: " + mQsExpanded);
pw.println(" mInterpolatedDarkAmount: " + mInterpolatedDarkAmount);
if (mView != null) {
mView.dump(fd, pw, args);
}
}
/** Every minute, update the aod icon's burn in offset */
public void dozeTimeTick() {
updateBurnInOffsets();
}
private void updateBurnInOffsets() {
float offsetX = MathUtils.lerp(0f,
getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
- mMaxBurnInOffsetX, mInterpolatedDarkAmount);
float offsetY = MathUtils.lerp(0f,
getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
- mMaxBurnInOffsetY, mInterpolatedDarkAmount);
float progress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount);
mAodFp.setTranslationX(offsetX);
mAodFp.setTranslationY(offsetY);
mAodFp.setProgress(progress);
mAodFp.setAlpha(255 * mInterpolatedDarkAmount);
}
private void updateIsUdfpsEnrolled() {
boolean wasUdfpsSupported = mUdfpsSupported;
boolean wasUdfpsEnrolled = mUdfpsEnrolled;
mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null;
mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled();
if (wasUdfpsSupported != mUdfpsSupported || wasUdfpsEnrolled != mUdfpsEnrolled) {
updateVisibility();
}
}
private StatusBarStateController.StateListener mStatusBarStateListener =
new StatusBarStateController.StateListener() {
@Override
public void onDozeAmountChanged(float linear, float eased) {
mInterpolatedDarkAmount = eased;
updateBurnInOffsets();
}
@Override
public void onDozingChanged(boolean isDozing) {
mIsDozing = isDozing;
updateBurnInOffsets();
updateIsUdfpsEnrolled();
updateVisibility();
}
@@ -439,7 +517,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
KeyguardUpdateMonitor.getCurrentUser());
}
mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled();
updateIsUdfpsEnrolled();
updateVisibility();
}
@@ -485,8 +563,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
// intercept all following touches until we see MotionEvent.ACTION_CANCEL UP or
// MotionEvent.ACTION_UP (see #onTouchEvent)
mDownDetected = true;
if (mVibrator != null) {
if (mVibrator != null && !mDownDetected) {
mVibrator.vibrate(
Process.myUid(),
getContext().getOpPackageName(),
@@ -494,6 +571,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
"lockIcon-onDown",
VIBRATION_SONIFICATION_ATTRIBUTES);
}
mDownDetected = true;
return true;
}
@@ -551,6 +630,9 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mAuthRippleController.showRipple(FINGERPRINT);
}
updateVisibility();
if (mOnGestureDetectedRunnable != null) {
mOnGestureDetectedRunnable.run();
}
mKeyguardViewController.showBouncer(/* scrim */ true);
return true;
}
@@ -561,16 +643,18 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
* in a 'clickable' state
* @return whether to intercept the touch event
*/
public boolean onTouchEvent(MotionEvent event) {
public boolean onTouchEvent(MotionEvent event, Runnable onGestureDetectedRunnable) {
if (mSensorTouchLocation.contains((int) event.getX(), (int) event.getY())
&& mView.getVisibility() == View.VISIBLE) {
&& (mView.getVisibility() == View.VISIBLE
|| mAodFp.getVisibility() == View.VISIBLE)) {
mOnGestureDetectedRunnable = onGestureDetectedRunnable;
mGestureDetector.onTouchEvent(event);
}
// we continue to intercept all following touches until we see MotionEvent.ACTION_CANCEL UP
// or MotionEvent.ACTION_UP. this is to avoid passing the touch to NPV
// after the lock icon disappears on device entry
if (mDownDetected && mDetectedLongPress) {
if (mDownDetected) {
if (event.getAction() == MotionEvent.ACTION_CANCEL
|| event.getAction() == MotionEvent.ACTION_UP) {
mDownDetected = false;
@@ -594,7 +678,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
@Override
public void onAllAuthenticatorsRegistered() {
mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null;
updateIsUdfpsEnrolled();
updateConfiguration();
}
};

View File

@@ -861,6 +861,10 @@ public class UdfpsController implements DozeReceiver {
return;
}
if (!mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
return;
}
mAodInterruptRunnable = () -> {
mIsAodInterruptActive = true;
// Since the sensor that triggers the AOD interrupt doesn't provide

View File

@@ -41,7 +41,6 @@ import com.android.systemui.util.time.SystemClock;
import java.io.FileDescriptor;
import java.io.PrintWriter;
/**
* Class that coordinates non-HBM animations during keyguard authentication.
*/

View File

@@ -3671,6 +3671,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
public void dozeTimeTick() {
mLockIconViewController.dozeTimeTick();
mKeyguardBottomArea.dozeTimeTick();
mKeyguardStatusViewController.dozeTimeTick();
if (mInterpolatedDarkAmount > 0) {
@@ -3974,10 +3975,6 @@ public class NotificationPanelViewController extends PanelViewController {
mStatusBarKeyguardViewManager.updateKeyguardPosition(event.getX());
}
if (mLockIconViewController.onTouchEvent(event)) {
return true;
}
handled |= super.onTouch(v, event);
return !mDozing || mPulsing || handled;
}

View File

@@ -35,6 +35,7 @@ import android.view.View;
import android.view.ViewGroup;
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.LockIconViewController;
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dock.DockManager;
@@ -88,6 +89,7 @@ public class NotificationShadeWindowViewController {
private final NotificationShadeDepthController mDepthController;
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
private final LockIconViewController mLockIconViewController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private GestureDetector mGestureDetector;
@@ -138,7 +140,8 @@ public class NotificationShadeWindowViewController {
NotificationPanelViewController notificationPanelViewController,
SuperStatusBarViewFactory statusBarViewFactory,
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
LockIconViewController lockIconViewController) {
mInjectionInflationController = injectionInflationController;
mCoordinator = coordinator;
mPulseExpansionHandler = pulseExpansionHandler;
@@ -163,6 +166,7 @@ public class NotificationShadeWindowViewController {
mStatusBarViewFactory = statusBarViewFactory;
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mLockIconViewController = lockIconViewController;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -235,6 +239,7 @@ public class NotificationShadeWindowViewController {
if (!isCancel && mService.shouldIgnoreTouch()) {
return false;
}
if (isDown) {
setTouchActive(true);
mTouchCancelled = false;
@@ -245,6 +250,7 @@ public class NotificationShadeWindowViewController {
if (mTouchCancelled || mExpandAnimationRunning) {
return false;
}
mFalsingCollector.onTouchEvent(ev);
mGestureDetector.onTouchEvent(ev);
mStatusBarKeyguardViewManager.onTouch(ev);
@@ -260,9 +266,17 @@ public class NotificationShadeWindowViewController {
if (isDown) {
mNotificationStackScrollLayoutController.closeControlsIfOutsideTouch(ev);
}
if (mStatusBarStateController.isDozing()) {
mService.mDozeScrimController.extendPulse();
}
mLockIconViewController.onTouchEvent(
ev,
() -> mService.wakeUpIfDozing(
SystemClock.uptimeMillis(),
mView,
"LOCK_ICON_TOUCH"));
// In case we start outside of the view bounds (below the status bar), we need to
// dispatch
// the touch manually as the view system can't accommodate for touches outside of

View File

@@ -477,11 +477,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void aodInterrupt() throws RemoteException {
// GIVEN that the overlay is showing and screen is on
// GIVEN that the overlay is showing and screen is on and fp is running
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
// WHEN fingerprint is requested because of AOD interrupt
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
// THEN illumination begins
@@ -499,6 +500,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
// WHEN it is cancelled
@@ -514,6 +516,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
// WHEN it times out
@@ -532,6 +535,23 @@ public class UdfpsControllerTest extends SysuiTestCase {
mFgExecutor.runAllReady();
// WHEN aod interrupt is received
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
// THEN no illumination because screen is off
verify(mUdfpsView, never()).startIllumination(any());
}
@Test
public void aodInterrupt_fingerprintNotRunning() throws RemoteException {
// GIVEN showing overlay
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
// WHEN aod interrupt is received when the fingerprint service isn't running
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false);
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
// THEN no illumination because screen is off

View File

@@ -18,6 +18,7 @@ package com.android.systemui.keyguard;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -49,6 +50,8 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.airbnb.lottie.LottieAnimationView;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -80,6 +83,7 @@ public class LockIconViewControllerTest extends SysuiTestCase {
private @Mock DelayableExecutor mDelayableExecutor;
private @Mock Vibrator mVibrator;
private @Mock AuthRippleController mAuthRippleController;
private @Mock LottieAnimationView mAodFp;
private LockIconViewController mLockIconViewController;
@@ -101,6 +105,7 @@ public class LockIconViewControllerTest extends SysuiTestCase {
when(mLockIconView.getContext()).thenReturn(mContext);
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
when(mLockIconView.findViewById(anyInt())).thenReturn(mAodFp);
mLockIconViewController = new LockIconViewController(
mLockIconView,
@@ -121,7 +126,7 @@ public class LockIconViewControllerTest extends SysuiTestCase {
@Test
public void testUpdateFingerprintLocationOnInit() {
// GIVEN fp sensor location is available pre-init
// GIVEN fp sensor location is available pre-attached
final PointF udfpsLocation = new PointF(50, 75);
final int radius = 33;
final FingerprintSensorPropertiesInternal fpProps =
@@ -139,7 +144,7 @@ public class LockIconViewControllerTest extends SysuiTestCase {
// WHEN lock icon view controller is initialized and attached
mLockIconViewController.init();
captureAttachListener();
mAttachListener.onViewAttachedToWindow(null);
mAttachListener.onViewAttachedToWindow(mLockIconView);
// THEN lock icon view location is updated with the same coordinates as fpProps
verify(mLockIconView).setCenterLocation(mPointCaptor.capture(), eq(radius));
@@ -152,8 +157,10 @@ public class LockIconViewControllerTest extends SysuiTestCase {
when(mAuthController.getFingerprintSensorLocation()).thenReturn(null);
when(mAuthController.getUdfpsProps()).thenReturn(null);
mLockIconViewController.init();
captureAttachListener();
mAttachListener.onViewAttachedToWindow(mLockIconView);
// GIVEN fp sensor location is available post-init
// GIVEN fp sensor location is available post-atttached
captureAuthControllerCallback();
final PointF udfpsLocation = new PointF(50, 75);
final int radius = 33;

View File

@@ -32,6 +32,7 @@ import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
import com.android.keyguard.LockIconViewController;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
@@ -97,6 +98,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
@Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Mock private LockIconViewController mLockIconViewController;
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
mInteractionEventHandlerCaptor;
@@ -142,7 +144,8 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
mNotificationPanelViewController,
mStatusBarViewFactory,
mNotificationStackScrollLayoutController,
mStatusBarKeyguardViewManager);
mStatusBarKeyguardViewManager,
mLockIconViewController);
mController.setupExpandedStatusBar();
mController.setService(mStatusBar, mNotificationShadeWindowController);
mController.setDragDownHelper(mDragDownHelper);