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

Commit 8e0cd33a authored by Shawn Lin's avatar Shawn Lin Committed by Automerger Merge Worker
Browse files

Merge "Fix cutout flicker while switch screen resolution" into tm-dev am: 842704d4

parents 7222f49e 842704d4
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ open class DisplayCutoutBaseView : View, RegionInterceptableView {

    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
    @JvmField val displayInfo = DisplayInfo()
    @JvmField protected var pendingRotationChange = false
    @JvmField protected var pendingConfigChange = false
    @JvmField protected val paint = Paint()
    @JvmField protected val cutoutPath = Path()

@@ -145,7 +145,7 @@ open class DisplayCutoutBaseView : View, RegionInterceptableView {

    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
    open fun updateCutout() {
        if (pendingRotationChange) {
        if (pendingConfigChange) {
            return
        }
        cutoutPath.reset()
@@ -225,7 +225,7 @@ open class DisplayCutoutBaseView : View, RegionInterceptableView {
    }

    protected open fun updateProtectionBoundingPath() {
        if (pendingRotationChange) {
        if (pendingConfigChange) {
            return
        }
        val m = Matrix()
+73 −27
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.provider.Settings.Secure;
import android.util.DisplayUtils;
import android.util.Log;
import android.util.Size;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.DisplayCutout.BoundsPosition;
import android.view.DisplayInfo;
@@ -151,12 +152,13 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
    private SettingObserver mColorInversionSetting;
    private DelayableExecutor mExecutor;
    private Handler mHandler;
    boolean mPendingRotationChange;
    boolean mPendingConfigChange;
    @VisibleForTesting
    String mDisplayUniqueId;
    private int mTintColor = Color.BLACK;
    @VisibleForTesting
    protected DisplayDecorationSupport mHwcScreenDecorationSupport;
    private Display.Mode mDisplayMode;

    private CameraAvailabilityListener.CameraTransitionCallback mCameraTransitionCallback =
            new CameraAvailabilityListener.CameraTransitionCallback() {
@@ -324,6 +326,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
        mWindowManager = mContext.getSystemService(WindowManager.class);
        mDisplayManager = mContext.getSystemService(DisplayManager.class);
        mRotation = mContext.getDisplay().getRotation();
        mDisplayMode = mContext.getDisplay().getMode();
        mDisplayUniqueId = mContext.getDisplay().getUniqueId();
        mRoundedCornerResDelegate = new RoundedCornerResDelegate(mContext.getResources(),
                mDisplayUniqueId);
@@ -349,8 +352,10 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
            @Override
            public void onDisplayChanged(int displayId) {
                final int newRotation = mContext.getDisplay().getRotation();
                final Display.Mode newDisplayMode = mContext.getDisplay().getMode();
                if ((mOverlays != null || mScreenDecorHwcWindow != null)
                        && mRotation != newRotation) {
                        && (mRotation != newRotation
                        || displayModeChanged(mDisplayMode, newDisplayMode))) {
                    // We cannot immediately update the orientation. Otherwise
                    // WindowManager is still deferring layout until it has finished dispatching
                    // the config changes, which may cause divergence between what we draw
@@ -358,10 +363,16 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
                    // Instead we wait until either:
                    // - we are trying to redraw. This because WM resized our window and told us to.
                    // - the config change has been dispatched, so WM is no longer deferring layout.
                    mPendingRotationChange = true;
                    mPendingConfigChange = true;
                    if (DEBUG) {
                        Log.i(TAG, "Rotation changed, deferring " + newRotation + ", staying at "
                                + mRotation);
                        if (mRotation != newRotation) {
                            Log.i(TAG, "Rotation changed, deferring " + newRotation
                                            + ", staying at " + mRotation);
                        }
                        if (displayModeChanged(mDisplayMode, newDisplayMode)) {
                            Log.i(TAG, "Resolution changed, deferring " + newDisplayMode
                                    + ", staying at " + mDisplayMode);
                        }
                    }

                    if (mOverlays != null) {
@@ -369,7 +380,8 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
                            if (mOverlays[i] != null) {
                                final ViewGroup overlayView = mOverlays[i].getRootView();
                                overlayView.getViewTreeObserver().addOnPreDrawListener(
                                        new RestartingPreDrawListener(overlayView, i, newRotation));
                                        new RestartingPreDrawListener(
                                                overlayView, i, newRotation, newDisplayMode));
                            }
                        }
                    }
@@ -379,7 +391,10 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
                                new RestartingPreDrawListener(
                                        mScreenDecorHwcWindow,
                                        -1, // Pass -1 for views with no specific position.
                                        newRotation));
                                        newRotation, newDisplayMode));
                    }
                    if (mScreenDecorHwcLayer != null) {
                        mScreenDecorHwcLayer.pendingConfigChange = true;
                    }
                }

@@ -435,7 +450,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
        };

        mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
        updateOrientation();
        updateConfiguration();
    }

    @Nullable
@@ -807,6 +822,17 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
        }
    }

    private static boolean displayModeChanged(Display.Mode oldMode, Display.Mode newMode) {
        if (oldMode == null) {
            return true;
        }

        // We purposely ignore refresh rate and id changes here, because we don't need to
        // invalidate for those, and they can trigger the refresh rate to increase
        return oldMode.getPhysicalWidth() != newMode.getPhysicalWidth()
                || oldMode.getPhysicalHeight() != newMode.getPhysicalHeight();
    }

    private int getOverlayWindowGravity(@BoundsPosition int pos) {
        final int rotated = getBoundPositionFromRotation(pos, mRotation);
        switch (rotated) {
@@ -913,8 +939,8 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab

        mExecutor.execute(() -> {
            int oldRotation = mRotation;
            mPendingRotationChange = false;
            updateOrientation();
            mPendingConfigChange = false;
            updateConfiguration();
            if (DEBUG) Log.i(TAG, "onConfigChanged from rot " + oldRotation + " to " + mRotation);
            setupDecorations();
            if (mOverlays != null) {
@@ -941,7 +967,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
        pw.println("  DEBUG_DISABLE_SCREEN_DECORATIONS:" + DEBUG_DISABLE_SCREEN_DECORATIONS);
        pw.println("  mIsPrivacyDotEnabled:" + isPrivacyDotEnabled());
        pw.println("  isOnlyPrivacyDotInSwLayer:" + isOnlyPrivacyDotInSwLayer());
        pw.println("  mPendingRotationChange:" + mPendingRotationChange);
        pw.println("  mPendingConfigChange:" + mPendingConfigChange);
        if (mHwcScreenDecorationSupport != null) {
            pw.println("  mHwcScreenDecorationSupport:");
            pw.println("    format="
@@ -973,7 +999,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
        mRoundedCornerResDelegate.dump(pw, args);
    }

    private void updateOrientation() {
    private void updateConfiguration() {
        Preconditions.checkState(mHandler.getLooper().getThread() == Thread.currentThread(),
                "must call on " + mHandler.getLooper().getThread()
                        + ", but was " + Thread.currentThread());
@@ -982,11 +1008,14 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
        if (mRotation != newRotation) {
            mDotViewController.setNewRotation(newRotation);
        }
        final Display.Mode newMod = mContext.getDisplay().getMode();

        if (!mPendingRotationChange && newRotation != mRotation) {
        if (!mPendingConfigChange
                && (newRotation != mRotation || displayModeChanged(mDisplayMode, newMod))) {
            mRotation = newRotation;
            mDisplayMode = newMod;
            if (mScreenDecorHwcLayer != null) {
                mScreenDecorHwcLayer.pendingRotationChange = false;
                mScreenDecorHwcLayer.pendingConfigChange = false;
                mScreenDecorHwcLayer.updateRotation(mRotation);
                updateHwLayerRoundedCornerExistAndSize();
                updateHwLayerRoundedCornerDrawable();
@@ -1197,7 +1226,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
        @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
        @Override
        public void updateCutout() {
            if (!isAttachedToWindow() || pendingRotationChange) {
            if (!isAttachedToWindow() || pendingConfigChange) {
                return;
            }
            mPosition = getBoundPositionFromRotation(mInitialPosition, mRotation);
@@ -1338,40 +1367,47 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab

        private final View mView;
        private final int mTargetRotation;
        private final Display.Mode mTargetDisplayMode;
        // Pass -1 for ScreenDecorHwcLayer since it's a fullscreen window and has no specific
        // position.
        private final int mPosition;

        private RestartingPreDrawListener(View view, @BoundsPosition int position,
                int targetRotation) {
                int targetRotation, Display.Mode targetDisplayMode) {
            mView = view;
            mTargetRotation = targetRotation;
            mTargetDisplayMode = targetDisplayMode;
            mPosition = position;
        }

        @Override
        public boolean onPreDraw() {
            mView.getViewTreeObserver().removeOnPreDrawListener(this);

            if (mTargetRotation == mRotation) {
            if (mTargetRotation == mRotation
                    && !displayModeChanged(mDisplayMode, mTargetDisplayMode)) {
                if (DEBUG) {
                    final String title = mPosition < 0 ? "ScreenDecorHwcLayer"
                            : getWindowTitleByPos(mPosition);
                    Log.i(TAG, title + " already in target rot "
                            + mTargetRotation + ", allow draw without restarting it");
                            + mTargetRotation + " and in target resolution "
                            + mTargetDisplayMode.getPhysicalWidth() + "x"
                            + mTargetDisplayMode.getPhysicalHeight()
                            + ", allow draw without restarting it");
                }
                return true;
            }

            mPendingRotationChange = false;
            mPendingConfigChange = false;
            // This changes the window attributes - we need to restart the traversal for them to
            // take effect.
            updateOrientation();
            updateConfiguration();
            if (DEBUG) {
                final String title = mPosition < 0 ? "ScreenDecorHwcLayer"
                        : getWindowTitleByPos(mPosition);
                Log.i(TAG, title
                        + " restarting listener fired, restarting draw for rot " + mRotation);
                        + " restarting listener fired, restarting draw for rot " + mRotation
                        + ", resolution " + mDisplayMode.getPhysicalWidth() + "x"
                        + mDisplayMode.getPhysicalHeight());
            }
            mView.invalidate();
            return false;
@@ -1379,8 +1415,8 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
    }

    /**
     * A pre-draw listener, that validates that the rotation we draw in matches the displays
     * rotation before continuing the draw.
     * A pre-draw listener, that validates that the rotation and display resolution we draw in
     * matches the display's rotation and resolution before continuing the draw.
     *
     * This is to prevent a race condition, where we have not received the display changed event
     * yet, and would thus draw in an old orientation.
@@ -1396,11 +1432,21 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
        @Override
        public boolean onPreDraw() {
            final int displayRotation = mContext.getDisplay().getRotation();
            if (displayRotation != mRotation && !mPendingRotationChange) {
            final Display.Mode displayMode = mContext.getDisplay().getMode();
            if (displayRotation != mRotation && displayModeChanged(mDisplayMode, displayMode)
                    && !mPendingConfigChange) {
                if (DEBUG) {
                    if (displayRotation != mRotation) {
                        Log.i(TAG, "Drawing rot " + mRotation + ", but display is at rot "
                                + displayRotation + ". Restarting draw");
                    }
                    if (displayModeChanged(mDisplayMode, displayMode)) {
                        Log.i(TAG, "Drawing at " + mDisplayMode.getPhysicalWidth()
                                + "x" + mDisplayMode.getPhysicalHeight() + ", but display is at "
                                + displayMode.getPhysicalWidth() + "x"
                                + displayMode.getPhysicalHeight() + ". Restarting draw");
                    }
                }
                mView.invalidate();
                return false;
            }
+1 −0
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
        when(mContext.getDisplay()).thenReturn(mDisplay);
        // Not support hwc layer by default
        doReturn(null).when(mDisplay).getDisplayDecorationSupport();
        doReturn(mDisplayMode).when(mDisplay).getMode();

        when(mMockTypedArray.length()).thenReturn(0);
        mPrivacyDotTopLeftDecorProvider = spy(new PrivacyDotCornerDecorProviderImpl(