Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81b568b5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Check orientation when retrieving FP location" into tm-qpr-dev

parents 68e81c21 e6e5720d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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;
+4 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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);
        }
    }
+135 −83
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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<>();

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

    /**
@@ -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;
    }

    /**
@@ -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.
@@ -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();
@@ -705,6 +756,8 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba

        mStableDisplaySize = mDisplayManager.getStableDisplaySize();
        mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
        mOrientationListener.enable();
        updateSensorLocations();
    }

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

    /**
@@ -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);
@@ -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) {
@@ -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.
@@ -1051,8 +1099,7 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
    }

    private void onOrientationChanged() {
        updateFingerprintLocation();
        updateUdfpsLocation();
        updateSensorLocations();
        if (mCurrentDialog != null) {
            mCurrentDialog.onOrientationChanged();
        }
@@ -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) {
@@ -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);
    }
@@ -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);
+12 −13
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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()
@@ -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()
@@ -228,7 +228,7 @@ class AuthRippleController @Inject constructor(

    fun updateSensorLocation() {
        fingerprintSensorLocation = authController.fingerprintSensorLocation
        faceSensorLocation = authController.faceAuthSensorLocation
        faceSensorLocation = authController.faceSensorLocation
    }

    private fun updateRippleColor() {
@@ -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)
+10 −8
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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
        }

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