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

Commit 284cd266 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Apply rotation animation to restore rotated activity" into rvc-dev am: 45e7091f

Change-Id: I35ec8d410a5d7b79c9a97f014b2140794d09a55d
parents bfec27ae 45e7091f
Loading
Loading
Loading
Loading
+51 −14
Original line number Original line Diff line number Diff line
@@ -5125,28 +5125,50 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }
    }


    void startFreezingScreen() {
    void startFreezingScreen() {
        startFreezingScreen(ROTATION_UNDEFINED /* overrideOriginalDisplayRotation */);
    }

    void startFreezingScreen(int overrideOriginalDisplayRotation) {
        ProtoLog.i(WM_DEBUG_ORIENTATION,
        ProtoLog.i(WM_DEBUG_ORIENTATION,
                "Set freezing of %s: visible=%b freezing=%b visibleRequested=%b. %s",
                "Set freezing of %s: visible=%b freezing=%b visibleRequested=%b. %s",
                appToken, isVisible(), mFreezingScreen, mVisibleRequested,
                appToken, isVisible(), mFreezingScreen, mVisibleRequested,
                new RuntimeException().fillInStackTrace());
                new RuntimeException().fillInStackTrace());
        if (mVisibleRequested) {
        if (!mVisibleRequested) {
            return;
        }

        // If the override is given, the rotation of display doesn't change but we still want to
        // cover the activity whose configuration is changing by freezing the display and running
        // the rotation animation.
        final boolean forceRotation = overrideOriginalDisplayRotation != ROTATION_UNDEFINED;
        if (!mFreezingScreen) {
        if (!mFreezingScreen) {
            mFreezingScreen = true;
            mFreezingScreen = true;
            mWmService.registerAppFreezeListener(this);
            mWmService.registerAppFreezeListener(this);
            mWmService.mAppsFreezingScreen++;
            mWmService.mAppsFreezingScreen++;
            if (mWmService.mAppsFreezingScreen == 1) {
            if (mWmService.mAppsFreezingScreen == 1) {
                    mWmService.startFreezingDisplayLocked(0, 0, getDisplayContent());
                if (forceRotation) {
                    // Make sure normal rotation animation will be applied.
                    mDisplayContent.getDisplayRotation().cancelSeamlessRotation();
                }
                mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */,
                        mDisplayContent, overrideOriginalDisplayRotation);
                mWmService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
                mWmService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
                mWmService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
                mWmService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
            }
            }
        }
        }
        if (forceRotation) {
            // The rotation of the real display won't change, so in order to unfreeze the screen
            // via {@link #checkAppWindowsReadyToShow}, the windows have to be able to call
            // {@link WindowState#reportResized} (it is skipped if the window is freezing) to update
            // the drawn state.
            return;
        }
        final int count = mChildren.size();
        final int count = mChildren.size();
        for (int i = 0; i < count; i++) {
        for (int i = 0; i < count; i++) {
            final WindowState w = mChildren.get(i);
            final WindowState w = mChildren.get(i);
            w.onStartFreezingScreen();
            w.onStartFreezingScreen();
        }
        }
    }
    }
    }


    boolean isFreezingScreen() {
    boolean isFreezingScreen() {
        return mFreezingScreen;
        return mFreezingScreen;
@@ -6159,6 +6181,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
        ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
    }
    }


    @Override
    void onCancelFixedRotationTransform(int originalDisplayRotation) {
        if (this != mDisplayContent.getLastOrientationSource()
                || getRequestedConfigurationOrientation() != ORIENTATION_UNDEFINED) {
            // Only need to handle the activity that should be rotated with display.
            return;
        }

        // Perform rotation animation according to the rotation of this activity.
        startFreezingScreen(originalDisplayRotation);
        // This activity may relaunch or perform configuration change so once it has reported drawn,
        // the screen can be unfrozen.
        ensureActivityConfiguration(0 /* globalChanges */, !PRESERVE_WINDOWS);
    }

    void setRequestedOrientation(int requestedOrientation) {
    void setRequestedOrientation(int requestedOrientation) {
        setOrientation(requestedOrientation, mayFreezeScreenLocked());
        setOrientation(requestedOrientation, mayFreezeScreenLocked());
        mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
        mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
+5 −1
Original line number Original line Diff line number Diff line
@@ -495,6 +495,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
     * The launching activity which is using fixed rotation transformation.
     * The launching activity which is using fixed rotation transformation.
     *
     *
     * @see #handleTopActivityLaunchingInDifferentOrientation
     * @see #handleTopActivityLaunchingInDifferentOrientation
     * @see DisplayRotation#shouldRotateSeamlessly
     */
     */
    ActivityRecord mFixedRotationLaunchingApp;
    ActivityRecord mFixedRotationLaunchingApp;


@@ -1238,7 +1239,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo


        if (configChanged) {
        if (configChanged) {
            mWaitingForConfig = true;
            mWaitingForConfig = true;
            mWmService.startFreezingDisplayLocked(0 /* exitAnim */, 0 /* enterAnim */, this);
            mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */, this);
            sendNewConfiguration();
            sendNewConfiguration();
        }
        }


@@ -1476,6 +1477,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            sendNewConfiguration();
            sendNewConfiguration();
            return true;
            return true;
        }
        }
        // The display won't rotate (e.g. the orientation from sensor has updated again before
        // applying rotation to display), so clear it to stop using seamless rotation.
        mFixedRotationLaunchingApp = null;
        return false;
        return false;
    }
    }


+22 −1
Original line number Original line Diff line number Diff line
@@ -537,8 +537,29 @@ public class DisplayRotation {
    }
    }


    void prepareNormalRotationAnimation() {
    void prepareNormalRotationAnimation() {
        cancelSeamlessRotation();
        final RotationAnimationPair anim = selectRotationAnimation();
        final RotationAnimationPair anim = selectRotationAnimation();
        mService.startFreezingDisplayLocked(anim.mExit, anim.mEnter, mDisplayContent);
        mService.startFreezingDisplay(anim.mExit, anim.mEnter, mDisplayContent);
    }

    /**
     * This ensures that normal rotation animation is used. E.g. {@link #mRotatingSeamlessly} was
     * set by previous {@link #updateRotationUnchecked}, but another orientation change happens
     * before calling {@link DisplayContent#sendNewConfiguration} (remote rotation hasn't finished)
     * and it doesn't choose seamless rotation.
     */
    void cancelSeamlessRotation() {
        if (!mRotatingSeamlessly) {
            return;
        }
        mDisplayContent.forAllWindows(w -> {
            if (w.mSeamlesslyRotated) {
                w.finishSeamlessRotation(false /* timeout */);
                w.mSeamlesslyRotated = false;
            }
        }, true /* traverseTopToBottom */);
        mSeamlessRotationCount = 0;
        mRotatingSeamlessly = false;
    }
    }


    private void prepareSeamlessRotation() {
    private void prepareSeamlessRotation() {
+23 −17
Original line number Original line Diff line number Diff line
@@ -41,7 +41,6 @@ import android.graphics.Rect;
import android.os.Trace;
import android.os.Trace;
import android.util.Slog;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
import android.view.Surface.OutOfResourcesException;
@@ -117,8 +116,9 @@ class ScreenRotationAnimation {
    private BlackFrame mEnteringBlackFrame;
    private BlackFrame mEnteringBlackFrame;
    private int mWidth, mHeight;
    private int mWidth, mHeight;


    private int mOriginalRotation;
    private final int mOriginalRotation;
    private int mOriginalWidth, mOriginalHeight;
    private final int mOriginalWidth;
    private final int mOriginalHeight;
    private int mCurRotation;
    private int mCurRotation;


    private Rect mOriginalDisplayRect = new Rect();
    private Rect mOriginalDisplayRect = new Rect();
@@ -140,20 +140,18 @@ class ScreenRotationAnimation {
    /** Intensity of light/whiteness of the layout after rotation occurs. */
    /** Intensity of light/whiteness of the layout after rotation occurs. */
    private float mEndLuma;
    private float mEndLuma;


    public ScreenRotationAnimation(Context context, DisplayContent displayContent,
    ScreenRotationAnimation(DisplayContent displayContent, @Surface.Rotation int originalRotation) {
            boolean fixedToUserRotation, boolean isSecure, WindowManagerService service) {
        mService = displayContent.mWmService;
        mService = service;
        mContext = mService.mContext;
        mContext = context;
        mDisplayContent = displayContent;
        mDisplayContent = displayContent;
        displayContent.getBounds(mOriginalDisplayRect);
        displayContent.getBounds(mOriginalDisplayRect);


        // Screenshot does NOT include rotation!
        // Screenshot does NOT include rotation!
        final Display display = displayContent.getDisplay();
        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
        int originalRotation = display.getRotation();
        final int realOriginalRotation = displayInfo.rotation;
        final int originalWidth;
        final int originalWidth;
        final int originalHeight;
        final int originalHeight;
        DisplayInfo displayInfo = displayContent.getDisplayInfo();
        if (displayContent.getDisplayRotation().isFixedToUserRotation()) {
        if (fixedToUserRotation) {
            // Emulated orientation.
            // Emulated orientation.
            mForceDefaultOrientation = true;
            mForceDefaultOrientation = true;
            originalWidth = displayContent.mBaseDisplayWidth;
            originalWidth = displayContent.mBaseDisplayWidth;
@@ -163,8 +161,8 @@ class ScreenRotationAnimation {
            originalWidth = displayInfo.logicalWidth;
            originalWidth = displayInfo.logicalWidth;
            originalHeight = displayInfo.logicalHeight;
            originalHeight = displayInfo.logicalHeight;
        }
        }
        if (originalRotation == Surface.ROTATION_90
        if (realOriginalRotation == Surface.ROTATION_90
                || originalRotation == Surface.ROTATION_270) {
                || realOriginalRotation == Surface.ROTATION_270) {
            mWidth = originalHeight;
            mWidth = originalHeight;
            mHeight = originalWidth;
            mHeight = originalWidth;
        } else {
        } else {
@@ -173,10 +171,18 @@ class ScreenRotationAnimation {
        }
        }


        mOriginalRotation = originalRotation;
        mOriginalRotation = originalRotation;
        mOriginalWidth = originalWidth;
        // If the delta is not zero, the rotation of display may not change, but we still want to
        mOriginalHeight = originalHeight;
        // apply rotation animation because there should be a top app shown as rotated. So the
        // specified original rotation customizes the direction of animation to have better look
        // when restoring the rotated app to the same rotation as current display.
        final int delta = DisplayContent.deltaRotation(originalRotation, realOriginalRotation);
        final boolean flipped = delta == Surface.ROTATION_90 || delta == Surface.ROTATION_270;
        mOriginalWidth = flipped ? originalHeight : originalWidth;
        mOriginalHeight = flipped ? originalWidth : originalHeight;
        mSurfaceRotationAnimationController = new SurfaceRotationAnimationController();
        mSurfaceRotationAnimationController = new SurfaceRotationAnimationController();


        // Check whether the current screen contains any secure content.
        final boolean isSecure = displayContent.hasSecureWindowOnScreen();
        final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
        final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
        try {
        try {
            mBackColorSurface = displayContent.makeChildSurface(null)
            mBackColorSurface = displayContent.makeChildSurface(null)
@@ -202,7 +208,7 @@ class ScreenRotationAnimation {
            t2.apply(true /* sync */);
            t2.apply(true /* sync */);


            // Capture a screenshot into the surface we just created.
            // Capture a screenshot into the surface we just created.
            final int displayId = display.getDisplayId();
            final int displayId = displayContent.getDisplayId();
            final Surface surface = mService.mSurfaceFactory.get();
            final Surface surface = mService.mSurfaceFactory.get();
            surface.copyFrom(mScreenshotLayer);
            surface.copyFrom(mScreenshotLayer);
            SurfaceControl.ScreenshotGraphicBuffer gb =
            SurfaceControl.ScreenshotGraphicBuffer gb =
@@ -242,7 +248,7 @@ class ScreenRotationAnimation {


        ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
        ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
                    "  FREEZE %s: CREATE", mScreenshotLayer);
                    "  FREEZE %s: CREATE", mScreenshotLayer);
        setRotation(t, originalRotation);
        setRotation(t, realOriginalRotation);
        t.apply();
        t.apply();
    }
    }


+16 −13
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.StatusBarManager.DISABLE_MASK;
import static android.app.StatusBarManager.DISABLE_MASK;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
import static android.content.pm.PackageManager.FEATURE_PC;
import static android.content.pm.PackageManager.FEATURE_PC;
@@ -2941,7 +2942,7 @@ public class WindowManagerService extends IWindowManager.Stub
                mClientFreezingScreen = true;
                mClientFreezingScreen = true;
                final long origId = Binder.clearCallingIdentity();
                final long origId = Binder.clearCallingIdentity();
                try {
                try {
                    startFreezingDisplayLocked(exitAnim, enterAnim);
                    startFreezingDisplay(exitAnim, enterAnim);
                    mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
                    mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
                    mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
                    mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
                } finally {
                } finally {
@@ -5479,13 +5480,17 @@ public class WindowManagerService extends IWindowManager.Stub
        return changed;
        return changed;
    }
    }


    void startFreezingDisplayLocked(int exitAnim, int enterAnim) {
    void startFreezingDisplay(int exitAnim, int enterAnim) {
        startFreezingDisplayLocked(exitAnim, enterAnim,
        startFreezingDisplay(exitAnim, enterAnim, getDefaultDisplayContentLocked());
                getDefaultDisplayContentLocked());
    }
    }


    void startFreezingDisplayLocked(int exitAnim, int enterAnim,
    void startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent) {
            DisplayContent displayContent) {
        startFreezingDisplay(exitAnim, enterAnim, displayContent,
                ROTATION_UNDEFINED /* overrideOriginalRotation */);
    }

    void startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent,
            int overrideOriginalRotation) {
        if (mDisplayFrozen || displayContent.getDisplayRotation().isRotatingSeamlessly()) {
        if (mDisplayFrozen || displayContent.getDisplayRotation().isRotatingSeamlessly()) {
            return;
            return;
        }
        }
@@ -5529,14 +5534,12 @@ public class WindowManagerService extends IWindowManager.Stub
            screenRotationAnimation.kill();
            screenRotationAnimation.kill();
        }
        }


        // Check whether the current screen contains any secure content.
        boolean isSecure = displayContent.hasSecureWindowOnScreen();

        displayContent.updateDisplayInfo();
        displayContent.updateDisplayInfo();
        screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
        final int originalRotation = overrideOriginalRotation != ROTATION_UNDEFINED
                displayContent.getDisplayRotation().isFixedToUserRotation(), isSecure,
                ? overrideOriginalRotation
                this);
                : displayContent.getDisplayInfo().rotation;
        displayContent.setRotationAnimation(screenRotationAnimation);
        displayContent.setRotationAnimation(new ScreenRotationAnimation(displayContent,
                originalRotation));
    }
    }


    void stopFreezingDisplayLocked() {
    void stopFreezingDisplayLocked() {
Loading