Merge "Show ripple effect on rear fp auth" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
6a01a5507c
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user