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

Commit 8987567e authored by Beverly's avatar Beverly Committed by Beverly Tai
Browse files

Update face scanning anim, fix visibility bugs

- The face scanning view visibility should
always be INVISIBLE if the face scanning anim isn't
running
- The face scanning view height should never
take up the entire screen (there was an issue where the
face sensor location  was being requested before the display
resolutiong/scale size was correct, so the face height location
was reporting INFINITY instead of the actual location
of the face camera sensor)
- Face scanning anim needs to handle resolution changes

Test: Settings > Display > Screen resolution
Test: Check hierarchy viewer for size of the view when
the face scanning animation is running, check different
orientations
Test: Check sysui dumpsys when face scanning animation
is NOT showing (view should be visible on reboot)
Test: atest ScreenDecorationsTest
Bug: 185128224
Fixes: 236193243

Change-Id: I35cd1c607f590fd332bfeac37f220eb11aea320e
parent da4c70fb
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -52,15 +52,18 @@ class FaceScanningOverlay(
    private var cameraProtectionColor = Color.BLACK
    var faceScanningAnimColor = Utils.getColorAttrDefaultColor(context,
            com.android.systemui.R.attr.wallpaperTextColorAccent)
    private var cameraProtectionAnimator: ValueAnimator? = null
    var hideOverlayRunnable: Runnable? = null

    init {
        visibility = View.INVISIBLE // only show this view when face scanning is happening
    }

    override fun setColor(color: Int) {
        cameraProtectionColor = color
        invalidate()
    }

    private var cameraProtectionAnimator: ValueAnimator? = null
    var hideOverlayRunnable: Runnable? = null

    override fun drawCutoutProtection(canvas: Canvas) {
        if (rimProgress > HIDDEN_RIM_SCALE && !protectionRect.isEmpty) {
            val rimPath = Path(protectionPath)
@@ -96,6 +99,10 @@ class FaceScanningOverlay(
        }
    }

    override fun updateVisOnUpdateCutout(): Boolean {
        return false // instead, we always update the visibility whenever face scanning starts/ends
    }

    override fun enableShowProtection(show: Boolean) {
        val showScanningAnimNow = keyguardUpdateMonitor.isFaceScanning && show
        if (showScanningAnimNow == showScanningAnim) {
+20 −11
Original line number Diff line number Diff line
@@ -493,6 +493,13 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
                        cutoutView.onDisplayChanged(displayId);
                    }
                }

                DisplayCutoutView overlay = (DisplayCutoutView) getOverlayView(mFaceScanningViewId);
                if (overlay != null) {
                    // handle display resolution changes
                    overlay.onDisplayChanged(displayId);
                }

                if (mScreenDecorHwcLayer != null) {
                    mScreenDecorHwcLayer.onDisplayChanged(displayId);
                }
@@ -801,7 +808,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
            });
        }
        // Use visibility of privacy dot views & face scanning view to determine the overlay's
        // visibility if the screen decoration SW layer overlay isn't persistenly showing
        // visibility if the screen decoration SW layer overlay isn't persistently showing
        // (ie: rounded corners always showing in SW layer)
        overlay.getRootView().setVisibility(getWindowVisibility(overlay, shouldOptimizeVisibility));
    }
@@ -960,7 +967,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
            viewsMayNeedColorUpdate.add(R.id.rounded_corner_bottom_right);
            viewsMayNeedColorUpdate.add(R.id.display_cutout);
        }
        if (mFaceScanningFactory.getHasProviders()) {
        if (getOverlayView(mFaceScanningViewId) != null) {
            viewsMayNeedColorUpdate.add(mFaceScanningViewId);
        }
        final Integer[] views = new Integer[viewsMayNeedColorUpdate.size()];
@@ -1115,7 +1122,6 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
            updateOverlayProviderViews();
        }

        if (mFaceScanningFactory.getHasProviders()) {
        FaceScanningOverlay faceScanningOverlay =
                (FaceScanningOverlay) getOverlayView(mFaceScanningViewId);
        if (faceScanningOverlay != null) {
@@ -1124,7 +1130,6 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
                            com.android.systemui.R.attr.wallpaperTextColorAccent));
        }
    }
    }

    private boolean hasRoundedCorners() {
        return mRoundedCornerFactory.getHasProviders();
@@ -1342,11 +1347,15 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
            } else {
                newVisible = GONE;
            }
            if (newVisible != getVisibility()) {
            if (updateVisOnUpdateCutout() && newVisible != getVisibility()) {
                setVisibility(newVisible);
            }
        }

        protected boolean updateVisOnUpdateCutout() {
            return true;
        }

        private void updateBoundingPath() {
            final Path path = displayInfo.displayCutout.getCutoutPath();
            if (path != null) {
+3 −0
Original line number Diff line number Diff line
@@ -492,6 +492,9 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
        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);
        }
        return new PointF(mFaceAuthSensorLocation.x * scaleFactor,
                mFaceAuthSensorLocation.y * scaleFactor);
    }
+42 −14
Original line number Diff line number Diff line
@@ -51,15 +51,17 @@ class FaceScanningProviderFactory @Inject constructor(

    override val hasProviders: Boolean
        get() {
            // update display info:
            if (!featureFlags.isEnabled(Flags.FACE_SCANNING_ANIM) ||
                    authController.faceAuthSensorLocation == null) {
                return false
            }

            // update display info
            display?.getDisplayInfo(displayInfo) ?: run {
                Log.w(TAG, "display is null, can't update displayInfo")
            }
            val hasDisplayCutout = DisplayCutout.getFillBuiltInDisplayCutout(
            return DisplayCutout.getFillBuiltInDisplayCutout(
                    context.resources, displayInfo.uniqueId)
            return hasDisplayCutout &&
                    authController.faceAuthSensorLocation != null &&
                    featureFlags.isEnabled(Flags.FACE_SCANNING_ANIM)
        }

    override val providers: List<DecorProvider>
@@ -110,7 +112,10 @@ class FaceScanningOverlayProviderImpl(
        rotation: Int,
        displayUniqueId: String?
    ) {
        // no need to handle rotation changes
        (view.layoutParams as FrameLayout.LayoutParams).let {
            updateLayoutParams(it, rotation)
            view.layoutParams = it
        }
    }

    override fun inflateView(
@@ -124,17 +129,40 @@ class FaceScanningOverlayProviderImpl(
                statusBarStateController,
                keyguardUpdateMonitor)
        view.id = viewId
        view.visibility = View.INVISIBLE // only show this view when face scanning is happening
        var heightLayoutParam = ViewGroup.LayoutParams.MATCH_PARENT
        authController.faceAuthSensorLocation?.y?.let {
            heightLayoutParam = (it * 3).toInt()
        }
        parent.addView(view, FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                heightLayoutParam,
                Gravity.TOP or Gravity.START))
        FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT).let {
            updateLayoutParams(it, rotation)
            parent.addView(view, it)
        }
        return view
    }

    private fun updateLayoutParams(
        layoutParams: FrameLayout.LayoutParams,
        @Surface.Rotation rotation: Int
    ) {
        layoutParams.let { lp ->
            lp.width = ViewGroup.LayoutParams.MATCH_PARENT
            lp.height = ViewGroup.LayoutParams.MATCH_PARENT
            authController.faceAuthSensorLocation?.y?.let { faceAuthSensorHeight ->
                val faceScanningHeight = (faceAuthSensorHeight * 2).toInt()
                when (rotation) {
                    Surface.ROTATION_0, Surface.ROTATION_180 ->
                        lp.height = faceScanningHeight
                    Surface.ROTATION_90, Surface.ROTATION_270 ->
                        lp.width = faceScanningHeight
                }
            }

            lp.gravity = when (rotation) {
                Surface.ROTATION_0 -> Gravity.TOP or Gravity.START
                Surface.ROTATION_90 -> Gravity.LEFT or Gravity.START
                Surface.ROTATION_180 -> Gravity.BOTTOM or Gravity.END
                Surface.ROTATION_270 -> Gravity.RIGHT or Gravity.END
                else -> -1 /* invalid rotation */
            }
        }
    }
}

fun DisplayCutout.getBoundBaseOnCurrentRotation(): List<Int> {