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

Commit 762bb503 authored by Mariia Sandrikova's avatar Mariia Sandrikova Committed by Automerger Merge Worker
Browse files

Remember and revert camera compat orientation change when camera closes am: c53fa6ba

parents 6d9586ec c53fa6ba
Loading
Loading
Loading
Loading
+30 −0
Original line number Original line Diff line number Diff line
@@ -469,6 +469,18 @@
      "group": "WM_DEBUG_TASKS",
      "group": "WM_DEBUG_TASKS",
      "at": "com\/android\/server\/wm\/RecentTasks.java"
      "at": "com\/android\/server\/wm\/RecentTasks.java"
    },
    },
    "-1643780158": {
      "message": "Saving original orientation before camera compat, last orientation is %d",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
    },
    "-1639406696": {
      "message": "NOSENSOR override detected",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayRotationReversionController.java"
    },
    "-1638958146": {
    "-1638958146": {
      "message": "Removing activity %s from task=%s adding to task=%s Callers=%s",
      "message": "Removing activity %s from task=%s adding to task=%s Callers=%s",
      "level": "INFO",
      "level": "INFO",
@@ -751,6 +763,12 @@
      "group": "WM_DEBUG_IME",
      "group": "WM_DEBUG_IME",
      "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
      "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
    },
    },
    "-1397175017": {
      "message": "Other orientation overrides are in place: not reverting",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayRotationReversionController.java"
    },
    "-1394745488": {
    "-1394745488": {
      "message": "ControlAdapter onAnimationCancelled mSource: %s mControlTarget: %s",
      "message": "ControlAdapter onAnimationCancelled mSource: %s mControlTarget: %s",
      "level": "INFO",
      "level": "INFO",
@@ -1669,6 +1687,12 @@
      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
      "at": "com\/android\/server\/wm\/Transition.java"
      "at": "com\/android\/server\/wm\/Transition.java"
    },
    },
    "-529187878": {
      "message": "Reverting orientation after camera compat force rotation",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
    },
    "-521613870": {
    "-521613870": {
      "message": "App died during pause, not stopping: %s",
      "message": "App died during pause, not stopping: %s",
      "level": "VERBOSE",
      "level": "VERBOSE",
@@ -2365,6 +2389,12 @@
      "group": "WM_DEBUG_FOCUS_LIGHT",
      "group": "WM_DEBUG_FOCUS_LIGHT",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    },
    "138097009": {
      "message": "NOSENSOR override is absent: reverting",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayRotationReversionController.java"
    },
    "140319294": {
    "140319294": {
      "message": "IME target changed within ActivityRecord",
      "message": "IME target changed within ActivityRecord",
      "level": "DEBUG",
      "level": "DEBUG",
+12 −0
Original line number Original line Diff line number Diff line
@@ -746,6 +746,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     */
     */
    DisplayWindowPolicyControllerHelper mDwpcHelper;
    DisplayWindowPolicyControllerHelper mDwpcHelper;


    private final DisplayRotationReversionController mRotationReversionController;

    private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
    private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
        WindowStateAnimator winAnimator = w.mWinAnimator;
        WindowStateAnimator winAnimator = w.mWinAnimator;
        final ActivityRecord activity = w.mActivityRecord;
        final ActivityRecord activity = w.mActivityRecord;
@@ -1170,6 +1172,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                mWmService.mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
                mWmService.mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
                            /* checkDeviceConfig */ false)
                            /* checkDeviceConfig */ false)
                        ? new DisplayRotationCompatPolicy(this) : null;
                        ? new DisplayRotationCompatPolicy(this) : null;
        mRotationReversionController = new DisplayRotationReversionController(this);


        mInputMonitor = new InputMonitor(mWmService, this);
        mInputMonitor = new InputMonitor(mWmService, this);
        mInsetsPolicy = new InsetsPolicy(mInsetsStateController, this);
        mInsetsPolicy = new InsetsPolicy(mInsetsStateController, this);
@@ -1284,6 +1287,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                .show(mOverlayLayer);
                .show(mOverlayLayer);
    }
    }


    DisplayRotationReversionController getRotationReversionController() {
        return mRotationReversionController;
    }

    boolean isReady() {
    boolean isReady() {
        // The display is ready when the system and the individual display are both ready.
        // The display is ready when the system and the individual display are both ready.
        return mWmService.mDisplayReady && mDisplayReady;
        return mWmService.mDisplayReady && mDisplayReady;
@@ -1666,9 +1673,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }
    }


    private boolean updateOrientation(boolean forceUpdate) {
    private boolean updateOrientation(boolean forceUpdate) {
        final WindowContainer prevOrientationSource = mLastOrientationSource;
        final int orientation = getOrientation();
        final int orientation = getOrientation();
        // The last orientation source is valid only after getOrientation.
        // The last orientation source is valid only after getOrientation.
        final WindowContainer orientationSource = getLastOrientationSource();
        final WindowContainer orientationSource = getLastOrientationSource();
        if (orientationSource != prevOrientationSource
                && mRotationReversionController.isRotationReversionEnabled()) {
            mRotationReversionController.updateForNoSensorOverride();
        }
        final ActivityRecord r =
        final ActivityRecord r =
                orientationSource != null ? orientationSource.asActivityRecord() : null;
                orientationSource != null ? orientationSource.asActivityRecord() : null;
        if (r != null) {
        if (r != null) {
+34 −6
Original line number Original line Diff line number Diff line
@@ -34,6 +34,9 @@ import static com.android.server.wm.DisplayRotationProto.IS_FIXED_TO_USER_ROTATI
import static com.android.server.wm.DisplayRotationProto.LAST_ORIENTATION;
import static com.android.server.wm.DisplayRotationProto.LAST_ORIENTATION;
import static com.android.server.wm.DisplayRotationProto.ROTATION;
import static com.android.server.wm.DisplayRotationProto.ROTATION;
import static com.android.server.wm.DisplayRotationProto.USER_ROTATION;
import static com.android.server.wm.DisplayRotationProto.USER_ROTATION;
import static com.android.server.wm.DisplayRotationReversionController.REVERSION_TYPE_CAMERA_COMPAT;
import static com.android.server.wm.DisplayRotationReversionController.REVERSION_TYPE_HALF_FOLD;
import static com.android.server.wm.DisplayRotationReversionController.REVERSION_TYPE_NOSENSOR;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_ACTIVE;
import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_ACTIVE;
@@ -106,6 +109,9 @@ public class DisplayRotation {
        int mExit;
        int mExit;
    }
    }


    @Nullable
    final FoldController mFoldController;

    private final WindowManagerService mService;
    private final WindowManagerService mService;
    private final DisplayContent mDisplayContent;
    private final DisplayContent mDisplayContent;
    private final DisplayPolicy mDisplayPolicy;
    private final DisplayPolicy mDisplayPolicy;
@@ -127,8 +133,6 @@ public class DisplayRotation {
    private OrientationListener mOrientationListener;
    private OrientationListener mOrientationListener;
    private StatusBarManagerInternal mStatusBarManagerInternal;
    private StatusBarManagerInternal mStatusBarManagerInternal;
    private SettingsObserver mSettingsObserver;
    private SettingsObserver mSettingsObserver;
    @Nullable
    private FoldController mFoldController;
    @NonNull
    @NonNull
    private final DeviceStateController mDeviceStateController;
    private final DeviceStateController mDeviceStateController;


@@ -279,7 +283,11 @@ public class DisplayRotation {
            if (mSupportAutoRotation && mContext.getResources().getBoolean(
            if (mSupportAutoRotation && mContext.getResources().getBoolean(
                    R.bool.config_windowManagerHalfFoldAutoRotateOverride)) {
                    R.bool.config_windowManagerHalfFoldAutoRotateOverride)) {
                mFoldController = new FoldController();
                mFoldController = new FoldController();
            } else {
                mFoldController = null;
            }
            }
        } else {
            mFoldController = null;
        }
        }
    }
    }


@@ -337,6 +345,11 @@ public class DisplayRotation {
        return -1;
        return -1;
    }
    }


    @VisibleForTesting
    boolean useDefaultSettingsProvider() {
        return isDefaultDisplay;
    }

    /**
    /**
     * Updates the configuration which may have different values depending on current user, e.g.
     * Updates the configuration which may have different values depending on current user, e.g.
     * runtime resource overlay.
     * runtime resource overlay.
@@ -870,7 +883,7 @@ public class DisplayRotation {
    @VisibleForTesting
    @VisibleForTesting
    void setUserRotation(int userRotationMode, int userRotation) {
    void setUserRotation(int userRotationMode, int userRotation) {
        mRotationChoiceShownToUserForConfirmation = ROTATION_UNDEFINED;
        mRotationChoiceShownToUserForConfirmation = ROTATION_UNDEFINED;
        if (isDefaultDisplay) {
        if (useDefaultSettingsProvider()) {
            // We'll be notified via settings listener, so we don't need to update internal values.
            // We'll be notified via settings listener, so we don't need to update internal values.
            final ContentResolver res = mContext.getContentResolver();
            final ContentResolver res = mContext.getContentResolver();
            final int accelerometerRotation =
            final int accelerometerRotation =
@@ -1814,7 +1827,7 @@ public class DisplayRotation {
                return false;
                return false;
            }
            }
            if (mDeviceState == DeviceStateController.DeviceState.HALF_FOLDED) {
            if (mDeviceState == DeviceStateController.DeviceState.HALF_FOLDED) {
                return !(isTabletop ^ mTabletopRotations.contains(mRotation));
                return isTabletop == mTabletopRotations.contains(mRotation);
            }
            }
            return true;
            return true;
        }
        }
@@ -1838,7 +1851,8 @@ public class DisplayRotation {
            return mDeviceState == DeviceStateController.DeviceState.OPEN
            return mDeviceState == DeviceStateController.DeviceState.OPEN
                    && !mShouldIgnoreSensorRotation // Ignore if the hinge angle still moving
                    && !mShouldIgnoreSensorRotation // Ignore if the hinge angle still moving
                    && mInHalfFoldTransition
                    && mInHalfFoldTransition
                    && mHalfFoldSavedRotation != -1 // Ignore if we've already reverted.
                    && mDisplayContent.getRotationReversionController().isOverrideActive(
                        REVERSION_TYPE_HALF_FOLD)
                    && mUserRotationMode
                    && mUserRotationMode
                        == WindowManagerPolicy.USER_ROTATION_LOCKED; // Ignore if we're unlocked.
                        == WindowManagerPolicy.USER_ROTATION_LOCKED; // Ignore if we're unlocked.
        }
        }
@@ -1846,6 +1860,8 @@ public class DisplayRotation {
        int revertOverriddenRotation() {
        int revertOverriddenRotation() {
            int savedRotation = mHalfFoldSavedRotation;
            int savedRotation = mHalfFoldSavedRotation;
            mHalfFoldSavedRotation = -1;
            mHalfFoldSavedRotation = -1;
            mDisplayContent.getRotationReversionController()
                    .revertOverride(REVERSION_TYPE_HALF_FOLD);
            mInHalfFoldTransition = false;
            mInHalfFoldTransition = false;
            return savedRotation;
            return savedRotation;
        }
        }
@@ -1865,6 +1881,8 @@ public class DisplayRotation {
                    && mDeviceState != DeviceStateController.DeviceState.HALF_FOLDED) {
                    && mDeviceState != DeviceStateController.DeviceState.HALF_FOLDED) {
                // The device has transitioned to HALF_FOLDED state: save the current rotation and
                // The device has transitioned to HALF_FOLDED state: save the current rotation and
                // update the device rotation.
                // update the device rotation.
                mDisplayContent.getRotationReversionController().beforeOverrideApplied(
                        REVERSION_TYPE_HALF_FOLD);
                mHalfFoldSavedRotation = mRotation;
                mHalfFoldSavedRotation = mRotation;
                mDeviceState = newState;
                mDeviceState = newState;
                // Now mFoldState is set to HALF_FOLDED, the overrideFrozenRotation function will
                // Now mFoldState is set to HALF_FOLDED, the overrideFrozenRotation function will
@@ -2069,6 +2087,8 @@ public class DisplayRotation {
            final int mHalfFoldSavedRotation;
            final int mHalfFoldSavedRotation;
            final boolean mInHalfFoldTransition;
            final boolean mInHalfFoldTransition;
            final DeviceStateController.DeviceState mDeviceState;
            final DeviceStateController.DeviceState mDeviceState;
            @Nullable final boolean[] mRotationReversionSlots;

            @Nullable final String mDisplayRotationCompatPolicySummary;
            @Nullable final String mDisplayRotationCompatPolicySummary;


            Record(DisplayRotation dr, int fromRotation, int toRotation) {
            Record(DisplayRotation dr, int fromRotation, int toRotation) {
@@ -2109,6 +2129,8 @@ public class DisplayRotation {
                        ? null
                        ? null
                        : dc.mDisplayRotationCompatPolicy
                        : dc.mDisplayRotationCompatPolicy
                                .getSummaryForDisplayRotationHistoryRecord();
                                .getSummaryForDisplayRotationHistoryRecord();
                mRotationReversionSlots =
                        dr.mDisplayContent.getRotationReversionController().getSlotsCopy();
            }
            }


            void dump(String prefix, PrintWriter pw) {
            void dump(String prefix, PrintWriter pw) {
@@ -2134,6 +2156,12 @@ public class DisplayRotation {
                if (mDisplayRotationCompatPolicySummary != null) {
                if (mDisplayRotationCompatPolicySummary != null) {
                    pw.println(prefix + mDisplayRotationCompatPolicySummary);
                    pw.println(prefix + mDisplayRotationCompatPolicySummary);
                }
                }
                if (mRotationReversionSlots != null) {
                    pw.println(prefix + " reversionSlots= NOSENSOR "
                            + mRotationReversionSlots[REVERSION_TYPE_NOSENSOR] + ", CAMERA "
                            + mRotationReversionSlots[REVERSION_TYPE_CAMERA_COMPAT] + " HALF_FOLD "
                            + mRotationReversionSlots[REVERSION_TYPE_HALF_FOLD]);
                }
            }
            }
        }
        }


+34 −0
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@ import static android.view.Display.TYPE_INTERNAL;


import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
import static com.android.server.wm.DisplayRotationReversionController.REVERSION_TYPE_CAMERA_COMPAT;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
@@ -156,6 +157,11 @@ final class DisplayRotationCompatPolicy {
    @ScreenOrientation
    @ScreenOrientation
    int getOrientation() {
    int getOrientation() {
        mLastReportedOrientation = getOrientationInternal();
        mLastReportedOrientation = getOrientationInternal();
        if (mLastReportedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
            rememberOverriddenOrientationIfNeeded();
        } else {
            restoreOverriddenOrientationIfNeeded();
        }
        return mLastReportedOrientation;
        return mLastReportedOrientation;
    }
    }


@@ -277,6 +283,34 @@ final class DisplayRotationCompatPolicy {
                + " }";
                + " }";
    }
    }


    private void restoreOverriddenOrientationIfNeeded() {
        if (!isOrientationOverridden()) {
            return;
        }
        if (mDisplayContent.getRotationReversionController().revertOverride(
                REVERSION_TYPE_CAMERA_COMPAT)) {
            ProtoLog.v(WM_DEBUG_ORIENTATION,
                    "Reverting orientation after camera compat force rotation");
            // Reset last orientation source since we have reverted the orientation.
            mDisplayContent.mLastOrientationSource = null;
        }
    }

    private boolean isOrientationOverridden() {
        return mDisplayContent.getRotationReversionController().isOverrideActive(
                REVERSION_TYPE_CAMERA_COMPAT);
    }

    private void rememberOverriddenOrientationIfNeeded() {
        if (!isOrientationOverridden()) {
            mDisplayContent.getRotationReversionController().beforeOverrideApplied(
                    REVERSION_TYPE_CAMERA_COMPAT);
            ProtoLog.v(WM_DEBUG_ORIENTATION,
                    "Saving original orientation before camera compat, last orientation is %d",
                    mDisplayContent.getLastOrientation());
        }
    }

    // Refreshing only when configuration changes after rotation.
    // Refreshing only when configuration changes after rotation.
    private boolean shouldRefreshActivity(ActivityRecord activity, Configuration newConfig,
    private boolean shouldRefreshActivity(ActivityRecord activity, Configuration newConfig,
            Configuration lastReportedConfig) {
            Configuration lastReportedConfig) {
+148 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wm;

import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;

import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;

import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.content.ActivityInfoProto;
import android.view.Surface;

import com.android.internal.protolog.common.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;

/**
 * Defines the behavior of reversion from device rotation overrides.
 *
 * <p>There are 3 override types:
 * <ol>
 *  <li>The top application has {@link SCREEN_ORIENTATION_NOSENSOR} set and is rotated to
 *  {@link ROTATION_0}.
 *  <li>Camera compat treatment has rotated the app {@link DisplayRotationCompatPolicy}.
 *  <li>The device is half-folded and has auto-rotate is temporarily enabled.
 * </ol>
 *
 * <p>Before an override is enabled, a component should call {@code beforeOverrideApplied}. When
 * it wishes to revert, it should call {@code revertOverride}. The user rotation will be restored
 * if there are no other overrides present.
 */
final class DisplayRotationReversionController {

    static final int REVERSION_TYPE_NOSENSOR = 0;
    static final int REVERSION_TYPE_CAMERA_COMPAT = 1;
    static final int REVERSION_TYPE_HALF_FOLD = 2;
    private static final int NUM_SLOTS = 3;

    @Surface.Rotation
    private int mUserRotationOverridden = WindowConfiguration.ROTATION_UNDEFINED;
    @WindowManagerPolicy.UserRotationMode
    private int mUserRotationModeOverridden;

    private final boolean[] mSlots = new boolean[NUM_SLOTS];
    private final DisplayContent mDisplayContent;

    DisplayRotationReversionController(DisplayContent content) {
        mDisplayContent = content;
    }

    boolean isRotationReversionEnabled() {
        return mDisplayContent.mDisplayRotationCompatPolicy != null
                || mDisplayContent.getDisplayRotation().mFoldController != null
                || mDisplayContent.getIgnoreOrientationRequest();
    }

    void beforeOverrideApplied(int slotIndex) {
        if (mSlots[slotIndex]) return;
        maybeSaveUserRotation();
        mSlots[slotIndex] = true;
    }

    boolean isOverrideActive(int slotIndex) {
        return mSlots[slotIndex];
    }

    @Nullable
    boolean[] getSlotsCopy() {
        return isRotationReversionEnabled() ? mSlots.clone() : null;
    }

    void updateForNoSensorOverride() {
        if (!mSlots[REVERSION_TYPE_NOSENSOR]) {
            if (isTopFullscreenActivityNoSensor()) {
                ProtoLog.v(WM_DEBUG_ORIENTATION, "NOSENSOR override detected");
                beforeOverrideApplied(REVERSION_TYPE_NOSENSOR);
            }
        } else {
            if (!isTopFullscreenActivityNoSensor()) {
                ProtoLog.v(WM_DEBUG_ORIENTATION, "NOSENSOR override is absent: reverting");
                revertOverride(REVERSION_TYPE_NOSENSOR);
            }
        }
    }

    boolean isAnyOverrideActive() {
        for (int i = 0; i < NUM_SLOTS; ++i) {
            if (mSlots[i]) {
                return true;
            }
        }
        return false;
    }

    boolean revertOverride(int slotIndex) {
        if (!mSlots[slotIndex]) return false;
        mSlots[slotIndex] = false;
        if (isAnyOverrideActive()) {
            ProtoLog.v(WM_DEBUG_ORIENTATION,
                    "Other orientation overrides are in place: not reverting");
            return false;
        }
        // Only override if the rotation is frozen and there are no other active slots.
        if (mDisplayContent.getDisplayRotation().isRotationFrozen()) {
            mDisplayContent.getDisplayRotation().setUserRotation(
                    mUserRotationModeOverridden,
                    mUserRotationOverridden);
            return true;
        } else {
            return false;
        }
    }

    private void maybeSaveUserRotation() {
        if (!isAnyOverrideActive()) {
            mUserRotationModeOverridden =
                    mDisplayContent.getDisplayRotation().getUserRotationMode();
            mUserRotationOverridden = mDisplayContent.getDisplayRotation().getUserRotation();
        }
    }

    private boolean isTopFullscreenActivityNoSensor() {
        final Task topFullscreenTask =
                mDisplayContent.getTask(
                        t -> t.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
        if (topFullscreenTask != null) {
            final ActivityRecord topActivity =
                    topFullscreenTask.topRunningActivity();
            return topActivity != null && topActivity.getOrientation()
                    == ActivityInfoProto.SCREEN_ORIENTATION_NOSENSOR;
        }
        return false;
    }
}
Loading