diff options
6 files changed, 87 insertions, 29 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index 792d2ec03388..146f430c88a1 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -54,14 +54,16 @@ import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.SomeArgs; import com.android.systemui.SystemUI; +import com.android.systemui.assist.ui.DisplayUtils; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.doze.DozeReceiver; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.inject.Inject; import javax.inject.Provider; @@ -79,13 +81,14 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, private final Handler mHandler = new Handler(Looper.getMainLooper()); private final CommandQueue mCommandQueue; - private final StatusBarStateController mStatusBarStateController; private final ActivityTaskManager mActivityTaskManager; @Nullable private final FingerprintManager mFingerprintManager; @Nullable private final FaceManager mFaceManager; private final Provider<UdfpsController> mUdfpsControllerFactory; private final Provider<SidefpsController> mSidefpsControllerFactory; @Nullable private final PointF mFaceAuthSensorLocation; + @Nullable private final PointF mFingerprintLocation; + private final Set<Callback> mCallbacks = new HashSet<>(); // TODO: These should just be saved from onSaveState private SomeArgs mCurrentDialogArgs; @@ -142,6 +145,10 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, if (mSidefpsProps != null) { mSidefpsController = mSidefpsControllerFactory.get(); } + + for (Callback cb : mCallbacks) { + cb.onAllAuthenticatorsRegistered(); + } } }; @@ -195,6 +202,20 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, } } + /** + * Adds a callback. See {@link Callback}. + */ + public void addCallback(@NonNull Callback callback) { + mCallbacks.add(callback); + } + + /** + * Removes a callback. See {@link Callback}. + */ + public void removeCallback(@NonNull Callback callback) { + mCallbacks.remove(callback); + } + @Override public void dozeTimeTick() { if (mUdfpsController != null) { @@ -335,6 +356,17 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, } /** + * @return where the fingerprint sensor exists in pixels in portrait mode. devices without an + * overridden value will use the default value even if they don't have a fingerprint sensor + */ + @Nullable public PointF getFingerprintSensorLocation() { + if (getUdfpsSensorLocation() != null) { + return getUdfpsSensorLocation(); + } + return mFingerprintLocation; + } + + /** * @return where the face authentication sensor exists relative to the screen in pixels in * portrait mode. */ @@ -387,7 +419,6 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, @Inject public AuthController(Context context, CommandQueue commandQueue, - StatusBarStateController statusBarStateController, ActivityTaskManager activityTaskManager, @Nullable FingerprintManager fingerprintManager, @Nullable FaceManager faceManager, @@ -395,7 +426,6 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, Provider<SidefpsController> sidefpsControllerFactory) { super(context); mCommandQueue = commandQueue; - mStatusBarStateController = statusBarStateController; mActivityTaskManager = activityTaskManager; mFingerprintManager = fingerprintManager; mFaceManager = faceManager; @@ -414,6 +444,10 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, (float) faceAuthLocation[1]); } + mFingerprintLocation = new PointF(DisplayUtils.getWidth(mContext) / 2, + mContext.getResources().getDimensionPixelSize( + com.android.systemui.R.dimen.physical_fingerprint_sensor_center_screen_location_y)); + IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); @@ -711,4 +745,12 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, .setMultiSensorConfig(multiSensorConfig) .build(sensorIds, credentialAllowed, mFpProps, mFaceProps); } + + interface Callback { + /** + * Called when authenticators are registered. If authenticators are already + * registered before this call, this callback will never be triggered. + */ + void onAllAuthenticatorsRegistered(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt index 257bd25f4afe..cf577a37d625 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt @@ -28,6 +28,7 @@ import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.phone.KeyguardBypassController +import com.android.systemui.statusbar.phone.StatusBar import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.ViewController @@ -40,6 +41,7 @@ import javax.inject.Inject */ @StatusBarScope class AuthRippleController @Inject constructor( + private val statusBar: StatusBar, private val sysuiContext: Context, private val authController: AuthController, private val configurationController: ConfigurationController, @@ -49,13 +51,14 @@ class AuthRippleController @Inject constructor( private val bypassController: KeyguardBypassController, rippleView: AuthRippleView? ) : ViewController<AuthRippleView>(rippleView) { - private var fingerprintSensorLocation: PointF? = null + var fingerprintSensorLocation: PointF? = null private var faceSensorLocation: PointF? = null @VisibleForTesting public override fun onViewAttached() { updateRippleColor() updateSensorLocation() + authController.addCallback(authControllerCallback) configurationController.addCallback(configurationChangedListener) keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() } @@ -63,6 +66,7 @@ class AuthRippleController @Inject constructor( @VisibleForTesting public override fun onViewDetached() { + authController.removeCallback(authControllerCallback) keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback) configurationController.removeCallback(configurationChangedListener) commandRegistry.unregisterCommand("auth-ripple") @@ -97,9 +101,10 @@ class AuthRippleController @Inject constructor( }) } - private fun updateSensorLocation() { - fingerprintSensorLocation = authController.udfpsSensorLocation + fun updateSensorLocation() { + fingerprintSensorLocation = authController.fingerprintSensorLocation faceSensorLocation = authController.faceAuthSensorLocation + statusBar.updateCircleReveal() } private fun updateRippleColor() { @@ -134,6 +139,8 @@ class AuthRippleController @Inject constructor( } } + private val authControllerCallback = AuthController.Callback { updateSensorLocation() } + inner class AuthRippleCommand : Command { override fun execute(pw: PrintWriter, args: List<String>) { if (args.isEmpty()) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 3075617cafdf..5c360a649af0 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -496,7 +496,6 @@ public class UdfpsController implements DozeReceiver { mSensorProps = findFirstUdfps(); // At least one UDFPS sensor exists checkArgument(mSensorProps != null); - mStatusBar.setSensorRect(getSensorLocation()); mCoreLayoutParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 3fb20c3cf6c0..1364d473c15d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -76,7 +76,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; -import android.graphics.RectF; import android.media.AudioAttributes; import android.metrics.LogMaker; import android.net.Uri; @@ -151,6 +150,7 @@ import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenu import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DelegateLaunchAnimatorController; import com.android.systemui.assist.AssistManager; +import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.camera.CameraIntents; import com.android.systemui.charging.WirelessChargingAnimation; @@ -387,6 +387,7 @@ public class StatusBar extends SystemUI implements DemoMode, protected NotificationShadeWindowView mNotificationShadeWindowView; protected StatusBarWindowView mPhoneStatusBarWindow; protected PhoneStatusBarView mStatusBarView; + private AuthRippleController mAuthRippleController; private int mStatusBarWindowState = WINDOW_STATE_SHOWING; protected NotificationShadeWindowController mNotificationShadeWindowController; protected StatusBarWindowController mStatusBarWindowController; @@ -1559,7 +1560,9 @@ public class StatusBar extends SystemUI implements DemoMode, mPhoneStatusBarWindow = mSuperStatusBarViewFactory.getStatusBarWindowView(); mNotificationPanelViewController = statusBarComponent.getNotificationPanelViewController(); statusBarComponent.getLockIconViewController().init(); - statusBarComponent.getAuthRippleController().init(); + + mAuthRippleController = statusBarComponent.getAuthRippleController(); + mAuthRippleController.init(); } protected void startKeyguard() { @@ -3794,7 +3797,8 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onDozeAmountChanged(float linear, float eased) { - if (mFeatureFlags.useNewLockscreenAnimations()) { + if (mFeatureFlags.useNewLockscreenAnimations() + && !mCircleRevealAnimator.isRunning()) { mLightRevealScrim.setRevealAmount(1f - linear); } } @@ -3831,6 +3835,23 @@ public class StatusBar extends SystemUI implements DemoMode, Trace.endSection(); } + /** + * Update the parameters for the dozing circle reveal that animates when the user authenticates + * from AOD using the fingerprint sensor. + */ + public void updateCircleReveal() { + final PointF fpLocation = mAuthRippleController.getFingerprintSensorLocation(); + if (fpLocation != null) { + mCircleReveal = + new CircleReveal( + fpLocation.x, + fpLocation.y, + 0, + Math.max(Math.max(fpLocation.x, getDisplayWidth() - fpLocation.x), + Math.max(fpLocation.y, getDisplayHeight() - fpLocation.y))); + } + } + private void startCircleReveal() { mLightRevealScrim.setRevealEffect(mCircleReveal); mCircleRevealAnimator.cancel(); @@ -3843,7 +3864,6 @@ public class StatusBar extends SystemUI implements DemoMode, private boolean shouldShowCircleReveal() { return mCircleReveal != null && !mCircleRevealAnimator.isRunning() - && mKeyguardUpdateMonitor.isUdfpsEnrolled() && mBiometricUnlockController.getBiometricType() == FINGERPRINT; } @@ -4306,15 +4326,6 @@ public class StatusBar extends SystemUI implements DemoMode, updateScrimController(); } - /** - * Set the location of the sensor on UDFPS if existent. - */ - public void setSensorRect(RectF rect) { - final float startRadius = (rect.right - rect.left) / 2f; - mCircleReveal = new CircleReveal(rect.centerX(), rect.centerY(), - startRadius, rect.centerY() - startRadius); - } - @VisibleForTesting public void updateScrimController() { Trace.beginSection("StatusBar#updateScrimController"); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java index bb2e55f877d4..db5648ab1ebc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -62,7 +62,6 @@ import android.testing.TestableLooper.RunWithLooper; import com.android.internal.R; import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import org.junit.Before; @@ -96,8 +95,6 @@ public class AuthControllerTest extends SysuiTestCase { @Mock private CommandQueue mCommandQueue; @Mock - private StatusBarStateController mStatusBarStateController; - @Mock private ActivityTaskManager mActivityTaskManager; @Mock private FingerprintManager mFingerprintManager; @@ -152,7 +149,7 @@ public class AuthControllerTest extends SysuiTestCase { when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props); mAuthController = new TestableAuthController(context, mCommandQueue, - mStatusBarStateController, mActivityTaskManager, mFingerprintManager, mFaceManager, + mActivityTaskManager, mFingerprintManager, mFaceManager, () -> mUdfpsController, () -> mSidefpsController); mAuthController.start(); @@ -561,13 +558,12 @@ public class AuthControllerTest extends SysuiTestCase { private PromptInfo mLastBiometricPromptInfo; TestableAuthController(Context context, CommandQueue commandQueue, - StatusBarStateController statusBarStateController, ActivityTaskManager activityTaskManager, FingerprintManager fingerprintManager, FaceManager faceManager, Provider<UdfpsController> udfpsControllerFactory, Provider<SidefpsController> sidefpsControllerFactory) { - super(context, commandQueue, statusBarStateController, activityTaskManager, + super(context, commandQueue, activityTaskManager, fingerprintManager, faceManager, udfpsControllerFactory, sidefpsControllerFactory); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt index 247748a98884..240fdf3a4e17 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt @@ -26,6 +26,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.phone.KeyguardBypassController +import com.android.systemui.statusbar.phone.StatusBar import com.android.systemui.statusbar.policy.ConfigurationController import org.junit.Before import org.junit.Test @@ -44,6 +45,7 @@ import org.mockito.MockitoAnnotations @RunWith(AndroidTestingRunner::class) class AuthRippleControllerTest : SysuiTestCase() { private lateinit var controller: AuthRippleController + @Mock private lateinit var statusBar: StatusBar @Mock private lateinit var rippleView: AuthRippleView @Mock private lateinit var commandRegistry: CommandRegistry @Mock private lateinit var configurationController: ConfigurationController @@ -56,6 +58,7 @@ class AuthRippleControllerTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) controller = AuthRippleController( + statusBar, context, authController, configurationController, @@ -72,7 +75,7 @@ class AuthRippleControllerTest : SysuiTestCase() { fun testFingerprintTrigger_Ripple() { // GIVEN fp exists, keyguard is visible, user doesn't need strong auth val fpsLocation = PointF(5f, 5f) - `when`(authController.udfpsSensorLocation).thenReturn(fpsLocation) + `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation) controller.onViewAttached() `when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true) `when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false) @@ -193,7 +196,7 @@ class AuthRippleControllerTest : SysuiTestCase() { @Test fun testNullFingerprintSensorLocationDoesNothing() { - `when`(authController.udfpsSensorLocation).thenReturn(null) + `when`(authController.fingerprintSensorLocation).thenReturn(null) controller.onViewAttached() val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) |
