From e5be111dc4740db3fa624c2620fee09a40193974 Mon Sep 17 00:00:00 2001 From: Beverly Date: Mon, 13 Sep 2021 17:25:00 -0400 Subject: [PATCH] [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 --- .../res/layout/status_bar_expanded.xml | 13 +++ .../com/android/keyguard/LockIconView.java | 17 ++- .../keyguard/LockIconViewController.java | 106 ++++++++++++++++-- .../systemui/biometrics/UdfpsController.java | 4 + .../UdfpsKeyguardViewController.java | 1 - .../NotificationPanelViewController.java | 5 +- ...NotificationShadeWindowViewController.java | 16 ++- .../biometrics/UdfpsControllerTest.java | 22 +++- .../keyguard/LockIconViewControllerTest.java | 13 ++- .../NotificationShadeWindowViewTest.java | 5 +- 10 files changed, 174 insertions(+), 28 deletions(-) diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index d8346aba4a8f3..8b787323ccb68 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -70,6 +70,19 @@ android:padding="@dimen/lock_icon_padding" android:layout_gravity="center" android:scaleType="centerCrop"/> + + + + 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 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 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 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 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 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 impleme mCancelDelayedUpdateVisibilityRunnable = null; } - if (!mIsKeyguardShowing) { + if (!mIsKeyguardShowing && !mIsDozing) { mView.setVisibility(View.INVISIBLE); return; } @@ -242,6 +265,7 @@ public class LockIconViewController extends ViewController 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 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 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 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 impleme mKeyguardUpdateMonitor.getUserUnlockedWithBiometric( KeyguardUpdateMonitor.getCurrentUser()); } - mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled(); + updateIsUdfpsEnrolled(); updateVisibility(); } @@ -485,8 +563,7 @@ public class LockIconViewController extends ViewController 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 impleme "lockIcon-onDown", VIBRATION_SONIFICATION_ATTRIBUTES); } + + mDownDetected = true; return true; } @@ -551,6 +630,9 @@ public class LockIconViewController extends ViewController 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 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 impleme private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() { @Override public void onAllAuthenticatorsRegistered() { - mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null; + updateIsUdfpsEnrolled(); updateConfiguration(); } }; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index dac6f9cc16ac5..52c26e1c20e6b 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java index 8aa545a2013e6..f1cb3a78e2fe5 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java @@ -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. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index e6bb30624f777..baef809e043e4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -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; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java index e57e2005e3b5c..3807b4647fe1c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java @@ -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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index cff2aed3f8fca..4dbfe0881b31b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java index d279bbb02cee5..a2af9b2dc35d9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java @@ -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; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java index bcc257dfa3d97..aafaebd959f03 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java @@ -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 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);