Loading packages/SystemUI/src/com/android/keyguard/LockIconView.java +3 −3 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.keyguard; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.PointF; import android.graphics.Point; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.AttributeSet; Loading Loading @@ -54,7 +54,7 @@ public class LockIconView extends FrameLayout implements Dumpable { private boolean mAod; @NonNull private final RectF mSensorRect; @NonNull private PointF mLockIconCenter = new PointF(0f, 0f); @NonNull private Point mLockIconCenter = new Point(0, 0); private float mRadius; private int mLockIconPadding; Loading Loading @@ -126,7 +126,7 @@ public class LockIconView extends FrameLayout implements Dumpable { * Set the location of the lock icon. */ @VisibleForTesting public void setCenterLocation(@NonNull PointF center, float radius, int drawablePadding) { public void setCenterLocation(@NonNull Point center, float radius, int drawablePadding) { mLockIconCenter = center; mRadius = radius; mLockIconPadding = drawablePadding; Loading packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +4 −3 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.PointF; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.AnimatedStateListDrawable; import android.hardware.biometrics.BiometricSourceType; Loading Loading @@ -357,8 +357,9 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mAuthController.getUdfpsRadius(), scaledPadding); } else { mView.setCenterLocation( new PointF(mWidthPixels / 2, mHeightPixels - ((mBottomPaddingPx + sLockIconRadiusPx) * scaleFactor)), new Point((int) mWidthPixels / 2, (int) (mHeightPixels - ((mBottomPaddingPx + sLockIconRadiusPx) * scaleFactor))), sLockIconRadiusPx * scaleFactor, scaledPadding); } } Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +135 −83 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.content.IntentFilter; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.hardware.SensorPrivacyManager; import android.hardware.biometrics.BiometricAuthenticator.Modality; Loading @@ -55,7 +54,9 @@ import android.os.Handler; import android.os.RemoteException; import android.os.UserManager; import android.util.Log; import android.util.RotationUtils; import android.util.SparseBooleanArray; import android.view.Display; import android.view.DisplayInfo; import android.view.MotionEvent; import android.view.WindowManager; Loading Loading @@ -116,8 +117,14 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba @NonNull private Point mStableDisplaySize = new Point(); @Nullable private final PointF mFaceAuthSensorLocation; @Nullable private PointF mFingerprintLocation; private final Display mDisplay; private float mScaleFactor = 1f; // sensor locations without any resolution scaling nor rotation adjustments: @Nullable private final Point mFaceSensorLocationDefault; @Nullable private final Point mFingerprintSensorLocationDefault; // cached sensor locations: @Nullable private Point mFaceSensorLocation; @Nullable private Point mFingerprintSensorLocation; @Nullable private Rect mUdfpsBounds; private final Set<Callback> mCallbacks = new HashSet<>(); Loading Loading @@ -147,6 +154,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba @NonNull private final LockPatternUtils mLockPatternUtils; @NonNull private final InteractionJankMonitor mInteractionJankMonitor; private final @Background DelayableExecutor mBackgroundExecutor; private final DisplayInfo mCachedDisplayInfo = new DisplayInfo(); @VisibleForTesting final TaskStackListener mTaskStackListener = new TaskStackListener() { Loading Loading @@ -184,7 +192,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba Log.w(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received"); mCurrentDialog.dismissWithoutCallback(true /* animate */); mCurrentDialog = null; mOrientationListener.disable(); for (Callback cb : mCallbacks) { cb.onBiometricPromptDismissed(); Loading Loading @@ -218,7 +225,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba Log.e(TAG, "Evicting client due to: " + topPackage); mCurrentDialog.dismissWithoutCallback(true /* animate */); mCurrentDialog = null; mOrientationListener.disable(); for (Callback cb : mCallbacks) { cb.onBiometricPromptDismissed(); Loading Loading @@ -284,7 +290,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba mUdfpsController.setAuthControllerUpdateUdfpsLocation(this::updateUdfpsLocation); mUdfpsController.setHalControlsIllumination(mUdfpsProps.get(0).halControlsIllumination); mUdfpsBounds = mUdfpsProps.get(0).getLocation().getRect(); updateUdfpsLocation(); } mSidefpsProps = !sidefpsProps.isEmpty() ? sidefpsProps : null; Loading @@ -292,8 +297,8 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba mSidefpsController = mSidefpsControllerFactory.get(); } updateSensorLocations(); mFingerprintManager.registerBiometricStateListener(mBiometricStateListener); updateFingerprintLocation(); for (Callback cb : mCallbacks) { cb.onAllAuthenticatorsRegistered(); Loading Loading @@ -470,11 +475,11 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba /** * @return where the UDFPS exists on the screen in pixels in portrait mode. */ @Nullable public PointF getUdfpsLocation() { @Nullable public Point getUdfpsLocation() { if (mUdfpsController == null || mUdfpsBounds == null) { return null; } return new PointF(mUdfpsBounds.centerX(), mUdfpsBounds.centerY()); return new Point(mUdfpsBounds.centerX(), mUdfpsBounds.centerY()); } /** Loading @@ -488,45 +493,105 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } /** * @return the scale factor representing the user's current resolution / the stable * (default) resolution * Gets the cached scale factor representing the user's current resolution / the stable * (default) resolution. */ public float getScaleFactor() { if (mUdfpsController == null || mUdfpsController.mOverlayParams == null) { return 1f; return mScaleFactor; } return mUdfpsController.mOverlayParams.getScaleFactor(); /** * Updates the current display info and cached scale factor & sensor locations. * Getting the display info is a relatively expensive call, so avoid superfluous calls. */ private void updateSensorLocations() { mDisplay.getDisplayInfo(mCachedDisplayInfo); final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio( mStableDisplaySize.x, mStableDisplaySize.y, mCachedDisplayInfo.getNaturalWidth(), mCachedDisplayInfo.getNaturalHeight()); if (scaleFactor == Float.POSITIVE_INFINITY) { mScaleFactor = 1f; } else { mScaleFactor = scaleFactor; } updateUdfpsLocation(); updateFingerprintLocation(); updateFaceLocation(); } /** * @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 * @return where the fingerprint sensor exists in pixels in its natural orientation. * Devices without location configs will use the default value even if they don't have a * fingerprint sensor. * * May return null if the fingerprint sensor isn't available yet. */ @Nullable public PointF getFingerprintSensorLocation() { @Nullable private Point getFingerprintSensorLocationInNaturalOrientation() { if (getUdfpsLocation() != null) { return getUdfpsLocation(); } return mFingerprintLocation; return new Point( (int) (mFingerprintSensorLocationDefault.x * mScaleFactor), (int) (mFingerprintSensorLocationDefault.y * mScaleFactor) ); } /** * @return where the face authentication sensor exists relative to the screen in pixels in * portrait mode. * @return where the fingerprint sensor exists in pixels exists the current device orientation. * Devices without location configs will use the default value even if they don't have a * fingerprint sensor. */ @Nullable public PointF getFaceAuthSensorLocation() { if (mFaceProps == null || mFaceAuthSensorLocation == null) { return null; @Nullable public Point getFingerprintSensorLocation() { return mFingerprintSensorLocation; } DisplayInfo displayInfo = new DisplayInfo(); mContext.getDisplay().getDisplayInfo(displayInfo); final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio( mStableDisplaySize.x, mStableDisplaySize.y, displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()); if (scaleFactor == Float.POSITIVE_INFINITY) { return new PointF(mFaceAuthSensorLocation.x, mFaceAuthSensorLocation.y); private void updateFingerprintLocation() { if (mFpProps == null) { mFingerprintSensorLocation = null; } else { mFingerprintSensorLocation = rotateToCurrentOrientation( getFingerprintSensorLocationInNaturalOrientation(), mCachedDisplayInfo); } return new PointF(mFaceAuthSensorLocation.x * scaleFactor, mFaceAuthSensorLocation.y * scaleFactor); } /** * @return where the face sensor exists in pixels in the current device orientation. Returns * null if no face sensor exists. */ @Nullable public Point getFaceSensorLocation() { return mFaceSensorLocation; } private void updateFaceLocation() { if (mFaceProps == null || mFaceSensorLocationDefault == null) { mFaceSensorLocation = null; } else { mFaceSensorLocation = rotateToCurrentOrientation( new Point( (int) (mFaceSensorLocationDefault.x * mScaleFactor), (int) (mFaceSensorLocationDefault.y * mScaleFactor)), mCachedDisplayInfo ); } } /** * @param inOutPoint point on the display in pixels. Going in, represents the point * in the device's natural orientation. Going out, represents * the point in the display's current orientation. * @param displayInfo currently display information to use to rotate the point */ @VisibleForTesting protected Point rotateToCurrentOrientation(Point inOutPoint, DisplayInfo displayInfo) { RotationUtils.rotatePoint( inOutPoint, displayInfo.rotation, displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight() ); return inOutPoint; } /** Loading Loading @@ -625,45 +690,36 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba }); mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null; int[] faceAuthLocation = context.getResources().getIntArray( com.android.systemui.R.array.config_face_auth_props); if (faceAuthLocation == null || faceAuthLocation.length < 2) { mFaceAuthSensorLocation = null; mFaceSensorLocationDefault = null; } else { mFaceAuthSensorLocation = new PointF( (float) faceAuthLocation[0], (float) faceAuthLocation[1]); mFaceSensorLocationDefault = new Point( faceAuthLocation[0], faceAuthLocation[1]); } updateFingerprintLocation(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED); mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class); } private int getDisplayWidth() { DisplayInfo displayInfo = new DisplayInfo(); mContext.getDisplay().getDisplayInfo(displayInfo); return displayInfo.getNaturalWidth(); } private void updateFingerprintLocation() { int xLocation = getDisplayWidth() / 2; mDisplay = mContext.getDisplay(); mDisplay.getDisplayInfo(mCachedDisplayInfo); int xFpLocation = mCachedDisplayInfo.getNaturalWidth() / 2; try { xLocation = mContext.getResources().getDimensionPixelSize( xFpLocation = mContext.getResources().getDimensionPixelSize( com.android.systemui.R.dimen .physical_fingerprint_sensor_center_screen_location_x); } catch (Resources.NotFoundException e) { } int yLocation = mContext.getResources().getDimensionPixelSize( com.android.systemui.R.dimen.physical_fingerprint_sensor_center_screen_location_y); mFingerprintLocation = new PointF( xLocation, yLocation); mFingerprintSensorLocationDefault = new Point( xFpLocation, mContext.getResources().getDimensionPixelSize(com.android.systemui.R.dimen .physical_fingerprint_sensor_center_screen_location_y) ); updateSensorLocations(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED); mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class); } // TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this. Loading @@ -672,19 +728,14 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba // updateFingerprintLocation in such a case are unclear. private void updateUdfpsLocation() { if (mUdfpsController != null) { final DisplayInfo displayInfo = new DisplayInfo(); mContext.getDisplay().getDisplayInfo(displayInfo); final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio( mStableDisplaySize.x, mStableDisplaySize.y, displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()); final FingerprintSensorPropertiesInternal udfpsProp = mUdfpsProps.get(0); final Rect previousUdfpsBounds = mUdfpsBounds; mUdfpsBounds = udfpsProp.getLocation().getRect(); mUdfpsBounds.scale(scaleFactor); mUdfpsBounds.scale(mScaleFactor); mUdfpsController.updateOverlayParams(udfpsProp.sensorId, new UdfpsOverlayParams(mUdfpsBounds, displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(), scaleFactor, displayInfo.rotation)); new UdfpsOverlayParams(mUdfpsBounds, mCachedDisplayInfo.getNaturalWidth(), mCachedDisplayInfo.getNaturalHeight(), mScaleFactor, mCachedDisplayInfo.rotation)); if (!Objects.equals(previousUdfpsBounds, mUdfpsBounds)) { for (Callback cb : mCallbacks) { cb.onUdfpsLocationChanged(); Loading @@ -705,6 +756,8 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba mStableDisplaySize = mDisplayManager.getStableDisplaySize(); mActivityTaskManager.registerTaskStackListener(mTaskStackListener); mOrientationListener.enable(); updateSensorLocations(); } @Override Loading Loading @@ -905,7 +958,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba // 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(); } /** Loading Loading @@ -996,7 +1048,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } mCurrentDialog = newDialog; mCurrentDialog.show(mWindowManager, savedState); mOrientationListener.enable(); if (!promptInfo.isAllowBackgroundAuthentication()) { mHandler.post(this::cancelIfOwnerIsNotInForeground); Loading @@ -1015,14 +1066,12 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba mReceiver = null; mCurrentDialog = null; mOrientationListener.disable(); } @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); updateFingerprintLocation(); updateUdfpsLocation(); updateSensorLocations(); // Save the state of the current dialog (buttons showing, etc) if (mCurrentDialog != null) { Loading @@ -1030,7 +1079,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba 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. Loading @@ -1051,8 +1099,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } private void onOrientationChanged() { updateFingerprintLocation(); updateUdfpsLocation(); updateSensorLocations(); if (mCurrentDialog != null) { mCurrentDialog.onOrientationChanged(); } Loading @@ -1062,6 +1109,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba PromptInfo promptInfo, boolean requireConfirmation, int userId, int[] sensorIds, String opPackageName, boolean skipIntro, long operationId, long requestId, @BiometricMultiSensorMode int multiSensorConfig, @NonNull WakefulnessLifecycle wakefulnessLifecycle, @NonNull UserManager userManager, @NonNull LockPatternUtils lockPatternUtils) { Loading @@ -1075,9 +1123,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba .setOperationId(operationId) .setRequestId(requestId) .setMultiSensorConfig(multiSensorConfig) .setScaleFactorProvider(() -> { return getScaleFactor(); }) .setScaleFactorProvider(() -> getScaleFactor()) .build(bgExecutor, sensorIds, mFpProps, mFaceProps, wakefulnessLifecycle, userManager, lockPatternUtils, mInteractionJankMonitor); } Loading @@ -1086,8 +1132,14 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { final AuthDialog dialog = mCurrentDialog; pw.println(" stableDisplaySize=" + mStableDisplaySize); pw.println(" faceAuthSensorLocation=" + mFaceAuthSensorLocation); pw.println(" fingerprintLocation=" + mFingerprintLocation); pw.println(" mCachedDisplayInfo=" + mCachedDisplayInfo); pw.println(" mScaleFactor=" + mScaleFactor); pw.println(" faceAuthSensorLocationDefault=" + mFaceSensorLocationDefault); pw.println(" faceAuthSensorLocation=" + getFaceSensorLocation()); pw.println(" fingerprintSensorLocationDefault=" + mFingerprintSensorLocationDefault); pw.println(" fingerprintSensorLocationInNaturalOrientation=" + getFingerprintSensorLocationInNaturalOrientation()); pw.println(" fingerprintSensorLocation=" + getFingerprintSensorLocation()); pw.println(" udfpsBounds=" + mUdfpsBounds); pw.println(" allFingerprintAuthenticatorsRegistered=" + mAllFingerprintAuthenticatorsRegistered); Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +12 −13 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.content.Context import android.graphics.PointF import android.graphics.Point import android.hardware.biometrics.BiometricFingerprintConstants import android.hardware.biometrics.BiometricSourceType import android.util.Log Loading Loading @@ -79,8 +79,8 @@ class AuthRippleController @Inject constructor( @VisibleForTesting internal var startLightRevealScrimOnKeyguardFadingAway = false var lightRevealScrimAnimator: ValueAnimator? = null var fingerprintSensorLocation: PointF? = null private var faceSensorLocation: PointF? = null var fingerprintSensorLocation: Point? = null private var faceSensorLocation: Point? = null private var circleReveal: LightRevealEffect? = null private var udfpsController: UdfpsController? = null Loading Loading @@ -131,10 +131,10 @@ class AuthRippleController @Inject constructor( circleReveal = CircleReveal( it.x, it.y, 0f, 0, Math.max( Math.max(it.x, centralSurfaces.displayWidth - it.x), Math.max(it.y, centralSurfaces.displayHeight - it.y) Math.max(it.x, centralSurfaces.displayWidth.toInt() - it.x), Math.max(it.y, centralSurfaces.displayHeight.toInt() - it.y) ) ) showUnlockedRipple() Loading @@ -148,10 +148,10 @@ class AuthRippleController @Inject constructor( circleReveal = CircleReveal( it.x, it.y, 0f, 0, Math.max( Math.max(it.x, centralSurfaces.displayWidth - it.x), Math.max(it.y, centralSurfaces.displayHeight - it.y) Math.max(it.x, centralSurfaces.displayWidth.toInt() - it.x), Math.max(it.y, centralSurfaces.displayHeight.toInt() - it.y) ) ) showUnlockedRipple() Loading Loading @@ -228,7 +228,7 @@ class AuthRippleController @Inject constructor( fun updateSensorLocation() { fingerprintSensorLocation = authController.fingerprintSensorLocation faceSensorLocation = authController.faceAuthSensorLocation faceSensorLocation = authController.faceSensorLocation } private fun updateRippleColor() { Loading Loading @@ -362,9 +362,8 @@ class AuthRippleController @Inject constructor( invalidCommand(pw) return } pw.println("custom ripple sensorLocation=" + args[1].toFloat() + ", " + args[2].toFloat()) mView.setSensorLocation(PointF(args[1].toFloat(), args[2].toFloat())) pw.println("custom ripple sensorLocation=" + args[1] + ", " + args[2]) mView.setSensorLocation(Point(args[1].toInt(), args[2].toInt())) showUnlockedRipple() } else -> invalidCommand(pw) Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +10 −8 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.PointF import android.graphics.Point import android.util.AttributeSet import android.view.View import android.view.animation.PathInterpolator Loading Loading @@ -68,7 +68,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at dwellShader.maxRadius = value field = value } private var dwellOrigin: PointF = PointF() private var dwellOrigin: Point = Point() set(value) { dwellShader.origin = value field = value Loading @@ -78,9 +78,9 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at rippleShader.setMaxSize(value * 2f, value * 2f) field = value } private var origin: PointF = PointF() private var origin: Point = Point() set(value) { rippleShader.setCenter(value.x, value.y) rippleShader.setCenter(value.x.toFloat(), value.y.toFloat()) field = value } Loading @@ -97,12 +97,12 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at visibility = GONE } fun setSensorLocation(location: PointF) { fun setSensorLocation(location: Point) { origin = location radius = maxOf(location.x, location.y, width - location.x, height - location.y).toFloat() } fun setFingerprintSensorLocation(location: PointF, sensorRadius: Float) { fun setFingerprintSensorLocation(location: Point, sensorRadius: Float) { origin = location radius = maxOf(location.x, location.y, width - location.x, height - location.y).toFloat() dwellOrigin = location Loading Loading @@ -349,13 +349,15 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at if (drawDwell) { val maskRadius = (1 - (1 - dwellShader.progress) * (1 - dwellShader.progress) * (1 - dwellShader.progress)) * dwellRadius * 2f canvas?.drawCircle(dwellOrigin.x, dwellOrigin.y, maskRadius, dwellPaint) canvas?.drawCircle(dwellOrigin.x.toFloat(), dwellOrigin.y.toFloat(), maskRadius, dwellPaint) } if (drawRipple) { val mask = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) * (1 - rippleShader.progress)) * radius * 2f canvas?.drawCircle(origin.x, origin.y, mask, ripplePaint) canvas?.drawCircle(origin.x.toFloat(), origin.y.toFloat(), mask, ripplePaint) } } } Loading
packages/SystemUI/src/com/android/keyguard/LockIconView.java +3 −3 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.keyguard; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.PointF; import android.graphics.Point; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.AttributeSet; Loading Loading @@ -54,7 +54,7 @@ public class LockIconView extends FrameLayout implements Dumpable { private boolean mAod; @NonNull private final RectF mSensorRect; @NonNull private PointF mLockIconCenter = new PointF(0f, 0f); @NonNull private Point mLockIconCenter = new Point(0, 0); private float mRadius; private int mLockIconPadding; Loading Loading @@ -126,7 +126,7 @@ public class LockIconView extends FrameLayout implements Dumpable { * Set the location of the lock icon. */ @VisibleForTesting public void setCenterLocation(@NonNull PointF center, float radius, int drawablePadding) { public void setCenterLocation(@NonNull Point center, float radius, int drawablePadding) { mLockIconCenter = center; mRadius = radius; mLockIconPadding = drawablePadding; Loading
packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +4 −3 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.PointF; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.AnimatedStateListDrawable; import android.hardware.biometrics.BiometricSourceType; Loading Loading @@ -357,8 +357,9 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mAuthController.getUdfpsRadius(), scaledPadding); } else { mView.setCenterLocation( new PointF(mWidthPixels / 2, mHeightPixels - ((mBottomPaddingPx + sLockIconRadiusPx) * scaleFactor)), new Point((int) mWidthPixels / 2, (int) (mHeightPixels - ((mBottomPaddingPx + sLockIconRadiusPx) * scaleFactor))), sLockIconRadiusPx * scaleFactor, scaledPadding); } } Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +135 −83 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.content.IntentFilter; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.hardware.SensorPrivacyManager; import android.hardware.biometrics.BiometricAuthenticator.Modality; Loading @@ -55,7 +54,9 @@ import android.os.Handler; import android.os.RemoteException; import android.os.UserManager; import android.util.Log; import android.util.RotationUtils; import android.util.SparseBooleanArray; import android.view.Display; import android.view.DisplayInfo; import android.view.MotionEvent; import android.view.WindowManager; Loading Loading @@ -116,8 +117,14 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba @NonNull private Point mStableDisplaySize = new Point(); @Nullable private final PointF mFaceAuthSensorLocation; @Nullable private PointF mFingerprintLocation; private final Display mDisplay; private float mScaleFactor = 1f; // sensor locations without any resolution scaling nor rotation adjustments: @Nullable private final Point mFaceSensorLocationDefault; @Nullable private final Point mFingerprintSensorLocationDefault; // cached sensor locations: @Nullable private Point mFaceSensorLocation; @Nullable private Point mFingerprintSensorLocation; @Nullable private Rect mUdfpsBounds; private final Set<Callback> mCallbacks = new HashSet<>(); Loading Loading @@ -147,6 +154,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba @NonNull private final LockPatternUtils mLockPatternUtils; @NonNull private final InteractionJankMonitor mInteractionJankMonitor; private final @Background DelayableExecutor mBackgroundExecutor; private final DisplayInfo mCachedDisplayInfo = new DisplayInfo(); @VisibleForTesting final TaskStackListener mTaskStackListener = new TaskStackListener() { Loading Loading @@ -184,7 +192,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba Log.w(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received"); mCurrentDialog.dismissWithoutCallback(true /* animate */); mCurrentDialog = null; mOrientationListener.disable(); for (Callback cb : mCallbacks) { cb.onBiometricPromptDismissed(); Loading Loading @@ -218,7 +225,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba Log.e(TAG, "Evicting client due to: " + topPackage); mCurrentDialog.dismissWithoutCallback(true /* animate */); mCurrentDialog = null; mOrientationListener.disable(); for (Callback cb : mCallbacks) { cb.onBiometricPromptDismissed(); Loading Loading @@ -284,7 +290,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba mUdfpsController.setAuthControllerUpdateUdfpsLocation(this::updateUdfpsLocation); mUdfpsController.setHalControlsIllumination(mUdfpsProps.get(0).halControlsIllumination); mUdfpsBounds = mUdfpsProps.get(0).getLocation().getRect(); updateUdfpsLocation(); } mSidefpsProps = !sidefpsProps.isEmpty() ? sidefpsProps : null; Loading @@ -292,8 +297,8 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba mSidefpsController = mSidefpsControllerFactory.get(); } updateSensorLocations(); mFingerprintManager.registerBiometricStateListener(mBiometricStateListener); updateFingerprintLocation(); for (Callback cb : mCallbacks) { cb.onAllAuthenticatorsRegistered(); Loading Loading @@ -470,11 +475,11 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba /** * @return where the UDFPS exists on the screen in pixels in portrait mode. */ @Nullable public PointF getUdfpsLocation() { @Nullable public Point getUdfpsLocation() { if (mUdfpsController == null || mUdfpsBounds == null) { return null; } return new PointF(mUdfpsBounds.centerX(), mUdfpsBounds.centerY()); return new Point(mUdfpsBounds.centerX(), mUdfpsBounds.centerY()); } /** Loading @@ -488,45 +493,105 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } /** * @return the scale factor representing the user's current resolution / the stable * (default) resolution * Gets the cached scale factor representing the user's current resolution / the stable * (default) resolution. */ public float getScaleFactor() { if (mUdfpsController == null || mUdfpsController.mOverlayParams == null) { return 1f; return mScaleFactor; } return mUdfpsController.mOverlayParams.getScaleFactor(); /** * Updates the current display info and cached scale factor & sensor locations. * Getting the display info is a relatively expensive call, so avoid superfluous calls. */ private void updateSensorLocations() { mDisplay.getDisplayInfo(mCachedDisplayInfo); final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio( mStableDisplaySize.x, mStableDisplaySize.y, mCachedDisplayInfo.getNaturalWidth(), mCachedDisplayInfo.getNaturalHeight()); if (scaleFactor == Float.POSITIVE_INFINITY) { mScaleFactor = 1f; } else { mScaleFactor = scaleFactor; } updateUdfpsLocation(); updateFingerprintLocation(); updateFaceLocation(); } /** * @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 * @return where the fingerprint sensor exists in pixels in its natural orientation. * Devices without location configs will use the default value even if they don't have a * fingerprint sensor. * * May return null if the fingerprint sensor isn't available yet. */ @Nullable public PointF getFingerprintSensorLocation() { @Nullable private Point getFingerprintSensorLocationInNaturalOrientation() { if (getUdfpsLocation() != null) { return getUdfpsLocation(); } return mFingerprintLocation; return new Point( (int) (mFingerprintSensorLocationDefault.x * mScaleFactor), (int) (mFingerprintSensorLocationDefault.y * mScaleFactor) ); } /** * @return where the face authentication sensor exists relative to the screen in pixels in * portrait mode. * @return where the fingerprint sensor exists in pixels exists the current device orientation. * Devices without location configs will use the default value even if they don't have a * fingerprint sensor. */ @Nullable public PointF getFaceAuthSensorLocation() { if (mFaceProps == null || mFaceAuthSensorLocation == null) { return null; @Nullable public Point getFingerprintSensorLocation() { return mFingerprintSensorLocation; } DisplayInfo displayInfo = new DisplayInfo(); mContext.getDisplay().getDisplayInfo(displayInfo); final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio( mStableDisplaySize.x, mStableDisplaySize.y, displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()); if (scaleFactor == Float.POSITIVE_INFINITY) { return new PointF(mFaceAuthSensorLocation.x, mFaceAuthSensorLocation.y); private void updateFingerprintLocation() { if (mFpProps == null) { mFingerprintSensorLocation = null; } else { mFingerprintSensorLocation = rotateToCurrentOrientation( getFingerprintSensorLocationInNaturalOrientation(), mCachedDisplayInfo); } return new PointF(mFaceAuthSensorLocation.x * scaleFactor, mFaceAuthSensorLocation.y * scaleFactor); } /** * @return where the face sensor exists in pixels in the current device orientation. Returns * null if no face sensor exists. */ @Nullable public Point getFaceSensorLocation() { return mFaceSensorLocation; } private void updateFaceLocation() { if (mFaceProps == null || mFaceSensorLocationDefault == null) { mFaceSensorLocation = null; } else { mFaceSensorLocation = rotateToCurrentOrientation( new Point( (int) (mFaceSensorLocationDefault.x * mScaleFactor), (int) (mFaceSensorLocationDefault.y * mScaleFactor)), mCachedDisplayInfo ); } } /** * @param inOutPoint point on the display in pixels. Going in, represents the point * in the device's natural orientation. Going out, represents * the point in the display's current orientation. * @param displayInfo currently display information to use to rotate the point */ @VisibleForTesting protected Point rotateToCurrentOrientation(Point inOutPoint, DisplayInfo displayInfo) { RotationUtils.rotatePoint( inOutPoint, displayInfo.rotation, displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight() ); return inOutPoint; } /** Loading Loading @@ -625,45 +690,36 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba }); mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null; int[] faceAuthLocation = context.getResources().getIntArray( com.android.systemui.R.array.config_face_auth_props); if (faceAuthLocation == null || faceAuthLocation.length < 2) { mFaceAuthSensorLocation = null; mFaceSensorLocationDefault = null; } else { mFaceAuthSensorLocation = new PointF( (float) faceAuthLocation[0], (float) faceAuthLocation[1]); mFaceSensorLocationDefault = new Point( faceAuthLocation[0], faceAuthLocation[1]); } updateFingerprintLocation(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED); mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class); } private int getDisplayWidth() { DisplayInfo displayInfo = new DisplayInfo(); mContext.getDisplay().getDisplayInfo(displayInfo); return displayInfo.getNaturalWidth(); } private void updateFingerprintLocation() { int xLocation = getDisplayWidth() / 2; mDisplay = mContext.getDisplay(); mDisplay.getDisplayInfo(mCachedDisplayInfo); int xFpLocation = mCachedDisplayInfo.getNaturalWidth() / 2; try { xLocation = mContext.getResources().getDimensionPixelSize( xFpLocation = mContext.getResources().getDimensionPixelSize( com.android.systemui.R.dimen .physical_fingerprint_sensor_center_screen_location_x); } catch (Resources.NotFoundException e) { } int yLocation = mContext.getResources().getDimensionPixelSize( com.android.systemui.R.dimen.physical_fingerprint_sensor_center_screen_location_y); mFingerprintLocation = new PointF( xLocation, yLocation); mFingerprintSensorLocationDefault = new Point( xFpLocation, mContext.getResources().getDimensionPixelSize(com.android.systemui.R.dimen .physical_fingerprint_sensor_center_screen_location_y) ); updateSensorLocations(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED); mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class); } // TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this. Loading @@ -672,19 +728,14 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba // updateFingerprintLocation in such a case are unclear. private void updateUdfpsLocation() { if (mUdfpsController != null) { final DisplayInfo displayInfo = new DisplayInfo(); mContext.getDisplay().getDisplayInfo(displayInfo); final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio( mStableDisplaySize.x, mStableDisplaySize.y, displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()); final FingerprintSensorPropertiesInternal udfpsProp = mUdfpsProps.get(0); final Rect previousUdfpsBounds = mUdfpsBounds; mUdfpsBounds = udfpsProp.getLocation().getRect(); mUdfpsBounds.scale(scaleFactor); mUdfpsBounds.scale(mScaleFactor); mUdfpsController.updateOverlayParams(udfpsProp.sensorId, new UdfpsOverlayParams(mUdfpsBounds, displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(), scaleFactor, displayInfo.rotation)); new UdfpsOverlayParams(mUdfpsBounds, mCachedDisplayInfo.getNaturalWidth(), mCachedDisplayInfo.getNaturalHeight(), mScaleFactor, mCachedDisplayInfo.rotation)); if (!Objects.equals(previousUdfpsBounds, mUdfpsBounds)) { for (Callback cb : mCallbacks) { cb.onUdfpsLocationChanged(); Loading @@ -705,6 +756,8 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba mStableDisplaySize = mDisplayManager.getStableDisplaySize(); mActivityTaskManager.registerTaskStackListener(mTaskStackListener); mOrientationListener.enable(); updateSensorLocations(); } @Override Loading Loading @@ -905,7 +958,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba // 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(); } /** Loading Loading @@ -996,7 +1048,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } mCurrentDialog = newDialog; mCurrentDialog.show(mWindowManager, savedState); mOrientationListener.enable(); if (!promptInfo.isAllowBackgroundAuthentication()) { mHandler.post(this::cancelIfOwnerIsNotInForeground); Loading @@ -1015,14 +1066,12 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba mReceiver = null; mCurrentDialog = null; mOrientationListener.disable(); } @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); updateFingerprintLocation(); updateUdfpsLocation(); updateSensorLocations(); // Save the state of the current dialog (buttons showing, etc) if (mCurrentDialog != null) { Loading @@ -1030,7 +1079,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba 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. Loading @@ -1051,8 +1099,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } private void onOrientationChanged() { updateFingerprintLocation(); updateUdfpsLocation(); updateSensorLocations(); if (mCurrentDialog != null) { mCurrentDialog.onOrientationChanged(); } Loading @@ -1062,6 +1109,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba PromptInfo promptInfo, boolean requireConfirmation, int userId, int[] sensorIds, String opPackageName, boolean skipIntro, long operationId, long requestId, @BiometricMultiSensorMode int multiSensorConfig, @NonNull WakefulnessLifecycle wakefulnessLifecycle, @NonNull UserManager userManager, @NonNull LockPatternUtils lockPatternUtils) { Loading @@ -1075,9 +1123,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba .setOperationId(operationId) .setRequestId(requestId) .setMultiSensorConfig(multiSensorConfig) .setScaleFactorProvider(() -> { return getScaleFactor(); }) .setScaleFactorProvider(() -> getScaleFactor()) .build(bgExecutor, sensorIds, mFpProps, mFaceProps, wakefulnessLifecycle, userManager, lockPatternUtils, mInteractionJankMonitor); } Loading @@ -1086,8 +1132,14 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { final AuthDialog dialog = mCurrentDialog; pw.println(" stableDisplaySize=" + mStableDisplaySize); pw.println(" faceAuthSensorLocation=" + mFaceAuthSensorLocation); pw.println(" fingerprintLocation=" + mFingerprintLocation); pw.println(" mCachedDisplayInfo=" + mCachedDisplayInfo); pw.println(" mScaleFactor=" + mScaleFactor); pw.println(" faceAuthSensorLocationDefault=" + mFaceSensorLocationDefault); pw.println(" faceAuthSensorLocation=" + getFaceSensorLocation()); pw.println(" fingerprintSensorLocationDefault=" + mFingerprintSensorLocationDefault); pw.println(" fingerprintSensorLocationInNaturalOrientation=" + getFingerprintSensorLocationInNaturalOrientation()); pw.println(" fingerprintSensorLocation=" + getFingerprintSensorLocation()); pw.println(" udfpsBounds=" + mUdfpsBounds); pw.println(" allFingerprintAuthenticatorsRegistered=" + mAllFingerprintAuthenticatorsRegistered); Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +12 −13 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.content.Context import android.graphics.PointF import android.graphics.Point import android.hardware.biometrics.BiometricFingerprintConstants import android.hardware.biometrics.BiometricSourceType import android.util.Log Loading Loading @@ -79,8 +79,8 @@ class AuthRippleController @Inject constructor( @VisibleForTesting internal var startLightRevealScrimOnKeyguardFadingAway = false var lightRevealScrimAnimator: ValueAnimator? = null var fingerprintSensorLocation: PointF? = null private var faceSensorLocation: PointF? = null var fingerprintSensorLocation: Point? = null private var faceSensorLocation: Point? = null private var circleReveal: LightRevealEffect? = null private var udfpsController: UdfpsController? = null Loading Loading @@ -131,10 +131,10 @@ class AuthRippleController @Inject constructor( circleReveal = CircleReveal( it.x, it.y, 0f, 0, Math.max( Math.max(it.x, centralSurfaces.displayWidth - it.x), Math.max(it.y, centralSurfaces.displayHeight - it.y) Math.max(it.x, centralSurfaces.displayWidth.toInt() - it.x), Math.max(it.y, centralSurfaces.displayHeight.toInt() - it.y) ) ) showUnlockedRipple() Loading @@ -148,10 +148,10 @@ class AuthRippleController @Inject constructor( circleReveal = CircleReveal( it.x, it.y, 0f, 0, Math.max( Math.max(it.x, centralSurfaces.displayWidth - it.x), Math.max(it.y, centralSurfaces.displayHeight - it.y) Math.max(it.x, centralSurfaces.displayWidth.toInt() - it.x), Math.max(it.y, centralSurfaces.displayHeight.toInt() - it.y) ) ) showUnlockedRipple() Loading Loading @@ -228,7 +228,7 @@ class AuthRippleController @Inject constructor( fun updateSensorLocation() { fingerprintSensorLocation = authController.fingerprintSensorLocation faceSensorLocation = authController.faceAuthSensorLocation faceSensorLocation = authController.faceSensorLocation } private fun updateRippleColor() { Loading Loading @@ -362,9 +362,8 @@ class AuthRippleController @Inject constructor( invalidCommand(pw) return } pw.println("custom ripple sensorLocation=" + args[1].toFloat() + ", " + args[2].toFloat()) mView.setSensorLocation(PointF(args[1].toFloat(), args[2].toFloat())) pw.println("custom ripple sensorLocation=" + args[1] + ", " + args[2]) mView.setSensorLocation(Point(args[1].toInt(), args[2].toInt())) showUnlockedRipple() } else -> invalidCommand(pw) Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +10 −8 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.PointF import android.graphics.Point import android.util.AttributeSet import android.view.View import android.view.animation.PathInterpolator Loading Loading @@ -68,7 +68,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at dwellShader.maxRadius = value field = value } private var dwellOrigin: PointF = PointF() private var dwellOrigin: Point = Point() set(value) { dwellShader.origin = value field = value Loading @@ -78,9 +78,9 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at rippleShader.setMaxSize(value * 2f, value * 2f) field = value } private var origin: PointF = PointF() private var origin: Point = Point() set(value) { rippleShader.setCenter(value.x, value.y) rippleShader.setCenter(value.x.toFloat(), value.y.toFloat()) field = value } Loading @@ -97,12 +97,12 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at visibility = GONE } fun setSensorLocation(location: PointF) { fun setSensorLocation(location: Point) { origin = location radius = maxOf(location.x, location.y, width - location.x, height - location.y).toFloat() } fun setFingerprintSensorLocation(location: PointF, sensorRadius: Float) { fun setFingerprintSensorLocation(location: Point, sensorRadius: Float) { origin = location radius = maxOf(location.x, location.y, width - location.x, height - location.y).toFloat() dwellOrigin = location Loading Loading @@ -349,13 +349,15 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at if (drawDwell) { val maskRadius = (1 - (1 - dwellShader.progress) * (1 - dwellShader.progress) * (1 - dwellShader.progress)) * dwellRadius * 2f canvas?.drawCircle(dwellOrigin.x, dwellOrigin.y, maskRadius, dwellPaint) canvas?.drawCircle(dwellOrigin.x.toFloat(), dwellOrigin.y.toFloat(), maskRadius, dwellPaint) } if (drawRipple) { val mask = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) * (1 - rippleShader.progress)) * radius * 2f canvas?.drawCircle(origin.x, origin.y, mask, ripplePaint) canvas?.drawCircle(origin.x.toFloat(), origin.y.toFloat(), mask, ripplePaint) } } }