Merge "Show ripple effect on rear fp auth" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-05-25 14:00:13 +00:00
committed by Android (Google) Code Review
6 changed files with 87 additions and 29 deletions

View File

@@ -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) {
@@ -334,6 +355,17 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
mUdfpsController.getSensorLocation().centerY());
}
/**
* @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();
}
}

View File

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

View File

@@ -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,

View File

@@ -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");

View File

@@ -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);
}

View File

@@ -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)