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

Commit 3e31414a authored by Colin Cross's avatar Colin Cross Committed by Android (Google) Code Review
Browse files

Merge "resolve merge conflicts of 5e664d99 to master"

parents 917d108f 95383803
Loading
Loading
Loading
Loading
+71 −32
Original line number Diff line number Diff line
@@ -632,6 +632,12 @@ public class WindowManagerService extends IWindowManager.Stub
    WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
    SettingsObserver mSettingsObserver;

    // A count of the windows which are 'seamlessly rotated', e.g. a surface
    // at an old orientation is being transformed. We freeze orientation updates
    // while any windows are seamlessly rotated, so we need to track when this
    // hits zero so we can apply deferred orientation updates.
    int mSeamlessRotationCount = 0;

    private final class SettingsObserver extends ContentObserver {
        private final Uri mDisplayInversionEnabledUri =
                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
@@ -5489,6 +5495,13 @@ public class WindowManagerService extends IWindowManager.Stub
            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress.");
            return false;
        }
        if (mDisplayFrozen) {
            // Even if the screen rotation animation has finished (e.g. isAnimating
            // returns false), there is still some time where we haven't yet unfrozen
            // the display. We also need to abort rotation here.
            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, still finishing previous rotation");
            return false;
        }

        if (!mDisplayEnabled) {
            // No point choosing a rotation if the display is not enabled.
@@ -5496,6 +5509,38 @@ public class WindowManagerService extends IWindowManager.Stub
            return false;
        }

        final DisplayContent displayContent = getDefaultDisplayContentLocked();
        final WindowList windows = displayContent.getWindowList();

        final int oldRotation = mRotation;
        boolean rotateSeamlessly = mPolicy.shouldRotateSeamlessly(oldRotation, mRotation);

        if (rotateSeamlessly) {
            for (int i = windows.size() - 1; i >= 0; i--) {
                WindowState w = windows.get(i);
                // We can't rotate (seamlessly or not) while waiting for the last seamless rotation
                // to complete (that is, waiting for windows to redraw). It's tempting to check
                // w.mSeamlessRotationCount but that could be incorrect in the case of window-removal.
                if (w.mSeamlesslyRotated) {
                    return false;
                }
                // In what can only be called an unfortunate workaround we require
                // seamlessly rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE
                // flag. Due to limitations in the client API, there is no way for
                // the client to set this flag in a race free fashion. If we seamlessly rotate
                // a window which does not have this flag, but then gains it, we will get
                // an incorrect visual result (rotated viewfinder). This means if we want to
                // support seamlessly rotating windows which could gain this flag, we can't
                // rotate windows without it. This limits seamless rotation in N to camera framework
                // users, windows without children, and native code. This is unfortunate but
                // having the camera work is our primary goal.
                if (w.isChildWindow() & w.isVisibleNow() &&
                        !w.mWinAnimator.mSurfaceController.getTransformToDisplayInverse()) {
                    rotateSeamlessly = false;
                }
            }
        }

        // TODO: Implement forced rotation changes.
        //       Set mAltOrientation to indicate that the application is receiving
        //       an orientation that has different metrics than it expected.
@@ -5524,8 +5569,6 @@ public class WindowManagerService extends IWindowManager.Stub
                + ", lastOrientation=" + mLastOrientation);
        }

        int oldRotation = mRotation;

        mRotation = rotation;
        mAltOrientation = altOrientation;
        mPolicy.setRotationLw(mRotation);
@@ -5534,7 +5577,6 @@ public class WindowManagerService extends IWindowManager.Stub
        mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
        mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
        mWaitingForConfig = true;
        final DisplayContent displayContent = getDefaultDisplayContentLocked();
        displayContent.setLayoutNeeded();
        final int[] anim = new int[2];
        if (displayContent.isDimming()) {
@@ -5542,33 +5584,6 @@ public class WindowManagerService extends IWindowManager.Stub
        } else {
            mPolicy.selectRotationAnimationLw(anim);
        }
        boolean rotateSeamlessly = mPolicy.shouldRotateSeamlessly(oldRotation, mRotation);
        final WindowList windows = displayContent.getWindowList();
        // We can't rotate seamlessly while an existing seamless rotation is still
        // waiting on windows to finish drawing.
        if (rotateSeamlessly) {
            for (int i = windows.size() - 1; i >= 0; i--) {
                WindowState w = windows.get(i);
                if (w.mSeamlesslyRotated) {
                    rotateSeamlessly = false;
                    break;
                }
                // In what can only be called an unfortunate workaround we require
                // seamlessly rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE
                // flag. Due to limitations in the client API, there is no way for
                // the client to set this flag in a race free fashion. If we seamlessly rotate
                // a window which does not have this flag, but then gains it, we will get
                // an incorrect visual result (rotated viewfinder). This means if we want to
                // support seamlessly rotating windows which could gain this flag, we can't
                // rotate windows without it. This limits seamless rotation in N to camera framework
                // users, windows without children, and native code. This is unfortunate but
                // having the camera work is our primary goal.
                if (w.isChildWindow() & w.isVisibleNow() &&
                        !w.mWinAnimator.mSurfaceController.getTransformToDisplayInverse()) {
                    rotateSeamlessly = false;
                }
            }
        }

        if (!rotateSeamlessly) {
            startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
@@ -5581,6 +5596,10 @@ public class WindowManagerService extends IWindowManager.Stub
            // When we are rotating seamlessly, we allow the elements to transition
            // to their rotated state independently and without a freeze required.
            screenRotationAnimation = null;

            // We have to reset this in case a window was removed before it
            // finished seamless rotation.
            mSeamlessRotationCount = 0;
        }

        // We need to update our screen size information to match the new rotation. If the rotation
@@ -7524,8 +7543,8 @@ public class WindowManagerService extends IWindowManager.Stub
                            if (w.mSeamlesslyRotated) {
                                layoutNeeded = true;
                                w.setDisplayLayoutNeeded();
                                markForSeamlessRotation(w, false);
                            }
                            w.mSeamlesslyRotated = false;
                        }
                        if (layoutNeeded) {
                            mWindowPlacerLocked.performSurfacePlacement();
@@ -9583,6 +9602,26 @@ public class WindowManagerService extends IWindowManager.Stub
        mPolicy.registerShortcutKey(shortcutCode, shortcutKeyReceiver);
    }

    void markForSeamlessRotation(WindowState w, boolean seamlesslyRotated) {
        if (seamlesslyRotated == w.mSeamlesslyRotated) {
            return;
        }
        w.mSeamlesslyRotated = seamlesslyRotated;
        if (seamlesslyRotated) {
            mSeamlessRotationCount++;
        } else {
            mSeamlessRotationCount--;
        }
        if (mSeamlessRotationCount == 0) {
            if (DEBUG_ORIENTATION) {
                Slog.i(TAG, "Performing post-rotate rotation after seamless rotation");
            }
            if (updateRotationUncheckedLocked(false)) {
                mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
            }
        }
    }

    private final class LocalService extends WindowManagerInternal {
        @Override
        public void requestTraversalFromDisplayManager() {
+2 −2
Original line number Diff line number Diff line
@@ -1350,7 +1350,7 @@ class WindowStateAnimator {
        // If we are undergoing seamless rotation, the surface has already
        // been set up to persist at it's old location. We need to freeze
        // updates until a resize occurs.
        w.mSeamlesslyRotated = w.mSeamlesslyRotated && !mSurfaceResized;
        mService.markForSeamlessRotation(w, w.mSeamlesslyRotated && !mSurfaceResized);

        calculateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect);

@@ -1991,7 +1991,7 @@ class WindowStateAnimator {
            cropRect.set(0, 0, w.mRequestedWidth, w.mRequestedWidth + w.mRequestedHeight);
            mSurfaceController.setCropInTransaction(cropRect, false);
        } else {
            w.mSeamlesslyRotated = true;
            mService.markForSeamlessRotation(w, true);
            transform.getValues(mService.mTmpFloats);

            float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];