summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Joe Bolinger <jbolinger@google.com> 2021-07-02 16:26:31 -0700
committer Joe Bolinger <jbolinger@google.com> 2021-07-02 17:09:41 -0700
commitc3e039f9cae09d9a3174fb4646057948e26d357c (patch)
treed2dbf08c655db20c34c88668a594a0feadb0283b
parent571124edc93a50c88f1cd778b26b2c75d7daf27e (diff)
Add a device orientation listener for updaing UDFPS layouts.
Configuration change events are only generated when switching to/from portrait/landscape modes and can't be used for udfps overlays. Fix: 190832486 Test: manual (put device in landscape, start auth, flip 180 degrees) Change-Id: If03d8ee3ec479b91eab93622a6e93f00b3f14765
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java84
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java11
6 files changed, 85 insertions, 35 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index a533d2cd97d2..3f61d3c6af9a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -36,6 +36,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.UserManager;
import android.util.Log;
+import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -476,6 +477,11 @@ public class AuthContainerView extends LinearLayout
}
@Override
+ public void onOrientationChanged() {
+ maybeUpdatePositionForUdfps(true /* invalidate */);
+ }
+
+ @Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
onAttachedToWindowInternal();
@@ -555,11 +561,15 @@ public class AuthContainerView extends LinearLayout
}
private boolean maybeUpdatePositionForUdfps(boolean invalidate) {
+ final Display display = getDisplay();
+ if (display == null) {
+ return false;
+ }
if (!shouldUpdatePositionForUdfps(mBiometricView)) {
return false;
}
- final int displayRotation = getDisplay().getRotation();
+ final int displayRotation = display.getRotation();
switch (displayRotation) {
case Surface.ROTATION_0:
mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 7947241ff794..2a18055da232 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -30,7 +30,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.graphics.PointF;
-import android.graphics.RectF;
import android.hardware.biometrics.BiometricAuthenticator.Modality;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager.Authenticators;
@@ -49,7 +48,10 @@ import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
+import android.view.Display;
import android.view.MotionEvent;
+import android.view.OrientationEventListener;
+import android.view.Surface;
import android.view.WindowManager;
import com.android.internal.R;
@@ -97,17 +99,15 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
@VisibleForTesting
AuthDialog mCurrentDialog;
- private WindowManager mWindowManager;
- @Nullable
- private UdfpsController mUdfpsController;
- @Nullable
- private IUdfpsHbmListener mUdfpsHbmListener;
- @Nullable
- private SidefpsController mSidefpsController;
+ @NonNull private final WindowManager mWindowManager;
+ @Nullable private UdfpsController mUdfpsController;
+ @Nullable private IUdfpsHbmListener mUdfpsHbmListener;
+ @Nullable private SidefpsController mSidefpsController;
@VisibleForTesting
TaskStackListener mTaskStackListener;
@VisibleForTesting
IBiometricSysuiReceiver mReceiver;
+ @NonNull private final BiometricOrientationEventListener mOrientationListener;
@Nullable private final List<FaceSensorPropertiesInternal> mFaceProps;
@Nullable private List<FingerprintSensorPropertiesInternal> mFpProps;
@Nullable private List<FingerprintSensorPropertiesInternal> mUdfpsProps;
@@ -120,6 +120,42 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
}
}
+ private class BiometricOrientationEventListener extends OrientationEventListener {
+ @Surface.Rotation private int mLastRotation;
+
+ BiometricOrientationEventListener(Context context) {
+ super(context);
+ mLastRotation = context.getDisplay().getRotation();
+ }
+
+ @Override
+ public void onOrientationChanged(int orientation) {
+ if (orientation == ORIENTATION_UNKNOWN) {
+ return;
+ }
+
+ final Display display = mContext.getDisplay();
+ if (display == null) {
+ return;
+ }
+
+ final int rotation = display.getRotation();
+ if (mLastRotation != rotation) {
+ mLastRotation = rotation;
+
+ if (mCurrentDialog != null) {
+ mCurrentDialog.onOrientationChanged();
+ }
+ if (mUdfpsController != null) {
+ mUdfpsController.onOrientationChanged();
+ }
+ if (mSidefpsController != null) {
+ mSidefpsController.onOrientationChanged();
+ }
+ }
+ }
+ }
+
@NonNull
private final IFingerprintAuthenticatorsRegisteredCallback
mFingerprintAuthenticatorsRegisteredCallback =
@@ -164,6 +200,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
Log.w(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received");
mCurrentDialog.dismissWithoutCallback(true /* animate */);
mCurrentDialog = null;
+ mOrientationListener.disable();
try {
if (mReceiver != null) {
@@ -192,6 +229,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
Log.w(TAG, "Evicting client due to: " + topPackage);
mCurrentDialog.dismissWithoutCallback(true /* animate */);
mCurrentDialog = null;
+ mOrientationListener.disable();
+
if (mReceiver != null) {
mReceiver.onDialogDismissed(
BiometricPrompt.DISMISSED_REASON_USER_CANCEL,
@@ -342,15 +381,6 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
/**
* @return where the UDFPS exists on the screen in pixels in portrait mode.
*/
- @Nullable public RectF getUdfpsRegion() {
- return mUdfpsController == null
- ? null
- : mUdfpsController.getSensorLocation();
- }
-
- /**
- * @return where the UDFPS exists on the screen in pixels in portrait mode.
- */
@Nullable public PointF getUdfpsSensorLocation() {
if (mUdfpsController == null) {
return null;
@@ -422,8 +452,10 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
}
@Inject
- public AuthController(Context context, CommandQueue commandQueue,
+ public AuthController(Context context,
+ CommandQueue commandQueue,
ActivityTaskManager activityTaskManager,
+ @NonNull WindowManager windowManager,
@Nullable FingerprintManager fingerprintManager,
@Nullable FaceManager faceManager,
Provider<UdfpsController> udfpsControllerFactory,
@@ -435,6 +467,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
mFaceManager = faceManager;
mUdfpsControllerFactory = udfpsControllerFactory;
mSidefpsControllerFactory = sidefpsControllerFactory;
+ mWindowManager = windowManager;
+ mOrientationListener = new BiometricOrientationEventListener(context);
mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null;
@@ -462,7 +496,6 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
@Override
public void start() {
mCommandQueue.addCallback(this);
- mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
if (mFingerprintManager != null) {
mFingerprintManager.addAuthenticatorsRegisteredCallback(
@@ -630,6 +663,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
// BiometricService will have already sent the callback to the client in this case.
// This avoids a round trip to SystemUI. So, just dismiss the dialog and we're done.
mCurrentDialog = null;
+ mOrientationListener.disable();
}
/**
@@ -701,6 +735,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
mReceiver = (IBiometricSysuiReceiver) args.arg2;
mCurrentDialog = newDialog;
mCurrentDialog.show(mWindowManager, savedState);
+ mOrientationListener.enable();
}
private void onDialogDismissed(@DismissedReason int reason) {
@@ -710,20 +745,12 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
}
mReceiver = null;
mCurrentDialog = null;
+ mOrientationListener.disable();
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- // UdfpsController is not BiometricPrompt-specific. It can be active for keyguard or
- // enrollment.
- if (mUdfpsController != null) {
- mUdfpsController.onConfigurationChanged();
- }
-
- if (mSidefpsController != null) {
- mSidefpsController.onConfigurationChanged();
- }
// Save the state of the current dialog (buttons showing, etc)
if (mCurrentDialog != null) {
@@ -731,6 +758,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
mCurrentDialog.onSaveState(savedState);
mCurrentDialog.dismissWithoutCallback(false /* animate */);
mCurrentDialog = null;
+ mOrientationListener.disable();
// Only show the dialog if necessary. If it was animating out, the dialog is supposed
// to send its pending callback immediately.
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index ff31e499f6e8..fa5213e94081 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -156,4 +156,12 @@ public interface AuthDialog {
* @return true if device credential is allowed.
*/
boolean isAllowDeviceCredentials();
+
+ /**
+ * Called when the device's orientation changed and the dialog may need to do another
+ * layout. This is most relevant to UDFPS since configuration changes are not sent by
+ * the framework in equivalent cases (landscape to reverse landscape) but the dialog
+ * must remain fixed on the physical sensor location.
+ */
+ void onOrientationChanged();
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.java
index a52296a71960..436e1e4e3116 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.java
@@ -137,8 +137,7 @@ public class SidefpsController {
}
}
-
- void onConfigurationChanged() {
+ void onOrientationChanged() {
// If mView is null or if view is hidden, then return.
if (mView == null || !mIsVisible) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 38f85cdb4a9b..81e60f316bbd 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -650,7 +650,7 @@ public class UdfpsController implements DozeReceiver {
return mCoreLayoutParams;
}
- void onConfigurationChanged() {
+ void onOrientationChanged() {
// When the configuration changes it's almost always necessary to destroy and re-create
// the overlay's window to pass it the new LayoutParams.
// Hiding the overlay will destroy its window. It's safe to hide the overlay regardless
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 9774ea98ff0d..bfcd1310acc2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -59,6 +59,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableContext;
import android.testing.TestableLooper.RunWithLooper;
+import android.view.WindowManager;
import com.android.internal.R;
import com.android.systemui.SysuiTestCase;
@@ -97,6 +98,8 @@ public class AuthControllerTest extends SysuiTestCase {
@Mock
private ActivityTaskManager mActivityTaskManager;
@Mock
+ private WindowManager mWindowManager;
+ @Mock
private FingerprintManager mFingerprintManager;
@Mock
private FaceManager mFaceManager;
@@ -149,7 +152,7 @@ public class AuthControllerTest extends SysuiTestCase {
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
mAuthController = new TestableAuthController(context, mCommandQueue,
- mActivityTaskManager, mFingerprintManager, mFaceManager,
+ mActivityTaskManager, mWindowManager, mFingerprintManager, mFaceManager,
() -> mUdfpsController, () -> mSidefpsController);
mAuthController.start();
@@ -576,13 +579,15 @@ public class AuthControllerTest extends SysuiTestCase {
private int mBuildCount = 0;
private PromptInfo mLastBiometricPromptInfo;
- TestableAuthController(Context context, CommandQueue commandQueue,
+ TestableAuthController(Context context,
+ CommandQueue commandQueue,
ActivityTaskManager activityTaskManager,
+ WindowManager windowManager,
FingerprintManager fingerprintManager,
FaceManager faceManager,
Provider<UdfpsController> udfpsControllerFactory,
Provider<SidefpsController> sidefpsControllerFactory) {
- super(context, commandQueue, activityTaskManager,
+ super(context, commandQueue, activityTaskManager, windowManager,
fingerprintManager, faceManager, udfpsControllerFactory,
sidefpsControllerFactory);
}