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

Commit e84ca14b authored by Joshua McCloskey's avatar Joshua McCloskey
Browse files

Correctly scale down UDFPS offset for diff display

Test: Verified manually that UDFPS pointer is in
the correct location after scaling.
Fixes: 231158953

Change-Id: I8359e885cb4872ab8d43209352c6645018c4597c
parent 7ce51c29
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.util.Log
import android.widget.FrameLayout
import android.widget.TextView
import com.android.systemui.R
import com.android.systemui.biometrics.AuthController.ScaleFactorProvider

private const val TAG = "AuthBiometricFingerprintView"

@@ -35,6 +36,7 @@ open class AuthBiometricFingerprintView(
        private set

    private var udfpsAdapter: UdfpsDialogMeasureAdapter? = null
    private var scaleFactorProvider: ScaleFactorProvider? = null

    /** Set the [sensorProps] of this sensor so the view can be customized prior to layout. */
    fun setSensorProperties(sensorProps: FingerprintSensorPropertiesInternal) {
@@ -42,9 +44,15 @@ open class AuthBiometricFingerprintView(
        udfpsAdapter = if (isUdfps) UdfpsDialogMeasureAdapter(this, sensorProps) else null
    }

    fun setScaleFactorProvider(scaleProvider: ScaleFactorProvider?) {
        scaleFactorProvider = scaleProvider
    }

    override fun onMeasureInternal(width: Int, height: Int): AuthDialog.LayoutParams {
        val layoutParams = super.onMeasureInternal(width, height)
        return udfpsAdapter?.onMeasureInternal(width, height, layoutParams) ?: layoutParams
        val scale = scaleFactorProvider?.provide() ?: 1.0f
        return udfpsAdapter?.onMeasureInternal(width, height, layoutParams,
            scale) ?: layoutParams
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
+9 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.biometrics.AuthController.ScaleFactorProvider;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -133,6 +134,7 @@ public class AuthContainerView extends LinearLayout
        long mRequestId = -1;
        boolean mSkipAnimation = false;
        @BiometricMultiSensorMode int mMultiSensorConfig = BIOMETRIC_MULTI_SENSOR_DEFAULT;
        ScaleFactorProvider mScaleProvider;
    }

    public static class Builder {
@@ -196,6 +198,11 @@ public class AuthContainerView extends LinearLayout
            return this;
        }

        public Builder setScaleFactorProvider(ScaleFactorProvider scaleProvider) {
            mConfig.mScaleProvider = scaleProvider;
            return this;
        }

        public AuthContainerView build(@Background DelayableExecutor bgExecutor, int[] sensorIds,
                @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
                @Nullable List<FaceSensorPropertiesInternal> faceProps,
@@ -296,12 +303,14 @@ public class AuthContainerView extends LinearLayout
                        (AuthBiometricFingerprintAndFaceView) layoutInflater.inflate(
                                R.layout.auth_biometric_fingerprint_and_face_view, null, false);
                fingerprintAndFaceView.setSensorProperties(fpProperties);
                fingerprintAndFaceView.setScaleFactorProvider(config.mScaleProvider);
                mBiometricView = fingerprintAndFaceView;
            } else if (fpProperties != null) {
                final AuthBiometricFingerprintView fpView =
                        (AuthBiometricFingerprintView) layoutInflater.inflate(
                                R.layout.auth_biometric_fingerprint_view, null, false);
                fpView.setSensorProperties(fpProperties);
                fpView.setScaleFactorProvider(config.mScaleProvider);
                mBiometricView = fpView;
            } else if (faceProperties != null) {
                mBiometricView = (AuthBiometricFaceView) layoutInflater.inflate(
+13 −0
Original line number Diff line number Diff line
@@ -1031,10 +1031,23 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
                .setOperationId(operationId)
                .setRequestId(requestId)
                .setMultiSensorConfig(multiSensorConfig)
                .setScaleFactorProvider(() -> {
                    return getScaleFactor();
                })
                .build(bgExecutor, sensorIds, mFpProps, mFaceProps, wakefulnessLifecycle,
                        userManager, lockPatternUtils);
    }

    /**
     * Provides a float that represents the resolution scale(if the controller is for UDFPS).
     */
    public interface ScaleFactorProvider {
        /**
         * Returns a float representing the scaled resolution(if the controller if for UDFPS).
         */
        float provide();
    }

    /**
     * AuthController callback used to receive signal for when biometric authenticators are
     * registered.
+24 −17
Original line number Diff line number Diff line
@@ -64,15 +64,16 @@ public class UdfpsDialogMeasureAdapter {

    @NonNull
    AuthDialog.LayoutParams onMeasureInternal(
            int width, int height, @NonNull AuthDialog.LayoutParams layoutParams) {
            int width, int height, @NonNull AuthDialog.LayoutParams layoutParams,
            float scaleFactor) {

        final int displayRotation = mView.getDisplay().getRotation();
        switch (displayRotation) {
            case Surface.ROTATION_0:
                return onMeasureInternalPortrait(width, height);
                return onMeasureInternalPortrait(width, height, scaleFactor);
            case Surface.ROTATION_90:
            case Surface.ROTATION_270:
                return onMeasureInternalLandscape(width, height);
                return onMeasureInternalLandscape(width, height, scaleFactor);
            default:
                Log.e(TAG, "Unsupported display rotation: " + displayRotation);
                return layoutParams;
@@ -90,7 +91,8 @@ public class UdfpsDialogMeasureAdapter {
    }

    @NonNull
    private AuthDialog.LayoutParams onMeasureInternalPortrait(int width, int height) {
    private AuthDialog.LayoutParams onMeasureInternalPortrait(int width, int height,
            float scaleFactor) {
        final WindowMetrics windowMetrics = mWindowManager.getMaximumWindowMetrics();

        // Figure out where the bottom of the sensor anim should be.
@@ -101,12 +103,13 @@ public class UdfpsDialogMeasureAdapter {
        final Insets navbarInsets = getNavbarInsets(windowMetrics);
        mBottomSpacerHeight = calculateBottomSpacerHeightForPortrait(
                mSensorProps, displayHeight, textIndicatorHeight, buttonBarHeight,
                dialogMargin, navbarInsets.bottom);
                dialogMargin, navbarInsets.bottom, scaleFactor);

        // Go through each of the children and do the custom measurement.
        int totalHeight = 0;
        final int numChildren = mView.getChildCount();
        final int sensorDiameter = mSensorProps.getLocation().sensorRadius * 2;
        final int sensorDiameter =
                (int) (scaleFactor * mSensorProps.getLocation().sensorRadius * 2);
        for (int i = 0; i < numChildren; i++) {
            final View child = mView.getChildAt(i);
            if (child.getId() == R.id.biometric_icon_frame) {
@@ -176,7 +179,8 @@ public class UdfpsDialogMeasureAdapter {
    }

    @NonNull
    private AuthDialog.LayoutParams onMeasureInternalLandscape(int width, int height) {
    private AuthDialog.LayoutParams onMeasureInternalLandscape(int width, int height,
            float scaleFactor) {
        final WindowMetrics windowMetrics = mWindowManager.getMaximumWindowMetrics();

        // Find the spacer height needed to vertically align the icon with the sensor.
@@ -197,9 +201,10 @@ public class UdfpsDialogMeasureAdapter {
        final int dialogMargin = getDialogMarginPx();
        final int horizontalInset = navbarInsets.left + navbarInsets.right;
        final int horizontalSpacerWidth = calculateHorizontalSpacerWidthForLandscape(
                mSensorProps, displayWidth, dialogMargin, horizontalInset);
                mSensorProps, displayWidth, dialogMargin, horizontalInset, scaleFactor);

        final int sensorDiameter = mSensorProps.getLocation().sensorRadius * 2;
        final int sensorDiameter =
                (int) (scaleFactor * mSensorProps.getLocation().sensorRadius * 2);
        final int remeasuredWidth = sensorDiameter + 2 * horizontalSpacerWidth;

        int remeasuredHeight = 0;
@@ -281,11 +286,11 @@ public class UdfpsDialogMeasureAdapter {
    static int calculateBottomSpacerHeightForPortrait(
            @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayHeightPx,
            int textIndicatorHeightPx, int buttonBarHeightPx, int dialogMarginPx,
            int navbarBottomInsetPx) {
            int navbarBottomInsetPx, float scaleFactor) {
        final SensorLocationInternal location = sensorProperties.getLocation();
        final int sensorDistanceFromBottom = displayHeightPx
                - location.sensorLocationY
                - location.sensorRadius;
                - (int) (scaleFactor * location.sensorLocationY)
                - (int) (scaleFactor * location.sensorRadius);

        final int spacerHeight = sensorDistanceFromBottom
                - textIndicatorHeightPx
@@ -298,7 +303,8 @@ public class UdfpsDialogMeasureAdapter {
                    + ", Distance from bottom: " + sensorDistanceFromBottom
                    + ", Bottom margin: " + dialogMarginPx
                    + ", Navbar bottom inset: " + navbarBottomInsetPx
                    + ", Bottom spacer height (portrait): " + spacerHeight);
                    + ", Bottom spacer height (portrait): " + spacerHeight
                    + ", Scale Factor: " + scaleFactor);
        }

        return spacerHeight;
@@ -346,11 +352,11 @@ public class UdfpsDialogMeasureAdapter {
    @VisibleForTesting
    static int calculateHorizontalSpacerWidthForLandscape(
            @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayWidthPx,
            int dialogMarginPx, int navbarHorizontalInsetPx) {
            int dialogMarginPx, int navbarHorizontalInsetPx, float scaleFactor) {
        final SensorLocationInternal location = sensorProperties.getLocation();
        final int sensorDistanceFromEdge = displayWidthPx
                - location.sensorLocationY
                - location.sensorRadius;
                - (int) (scaleFactor * location.sensorLocationY)
                - (int) (scaleFactor * location.sensorRadius);

        final int horizontalPadding = sensorDistanceFromEdge
                - dialogMarginPx
@@ -361,7 +367,8 @@ public class UdfpsDialogMeasureAdapter {
                    + ", Distance from edge: " + sensorDistanceFromEdge
                    + ", Dialog margin: " + dialogMarginPx
                    + ", Navbar horizontal inset: " + navbarHorizontalInsetPx
                    + ", Horizontal spacer width (landscape): " + horizontalPadding);
                    + ", Horizontal spacer width (landscape): " + horizontalPadding
                    + ", Scale Factor: " + scaleFactor);
        }

        return horizontalPadding;
+3 −2
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ public class UdfpsDialogMeasureAdapterTest extends SysuiTestCase {
        assertEquals(970,
                UdfpsDialogMeasureAdapter.calculateBottomSpacerHeightForPortrait(
                        props, displayHeightPx, textIndicatorHeightPx, buttonBarHeightPx,
                        dialogBottomMarginPx, navbarHeightPx
                        dialogBottomMarginPx, navbarHeightPx, 1.0f /* resolutionScale */
                ));
    }

@@ -135,6 +135,7 @@ public class UdfpsDialogMeasureAdapterTest extends SysuiTestCase {

        assertEquals(1205,
                UdfpsDialogMeasureAdapter.calculateHorizontalSpacerWidthForLandscape(
                        props, displayWidthPx, dialogMarginPx, navbarHorizontalInsetPx));
                        props, displayWidthPx, dialogMarginPx, navbarHorizontalInsetPx,
                        1.0f /* resolutionScale */));
    }
}