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

Commit cc2d539e authored by Massimo Carli's avatar Massimo Carli Committed by Mariia Sandrikova
Browse files

Respect "nosensor" and "locked" with ignoreOrientationRequest being set

In this implementation, we always resolve the orientation for a
component as the ignoreOrientationRequest was disabled. We then
use the actual flag when deciding the display orientation and when
querying from a descendent to handle the orientation change itself.

Main use case why this is important is Camera apps that rely on those
properties to ensure that they will be able to determine Camera preview
orientation correctly

Fixes:254691921
Test: run `atest WmTests:ActivityRecordTests WmTests:TaskTests
      WmTests:WindowContainerTests`

Change-Id: I96dca18a561e2acf961a462d3a4db484f003be6f
Merged-In: I96dca18a561e2acf961a462d3a4db484f003be6f
parent 92f29629
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -3871,12 +3871,6 @@
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
    },
    "1648338379": {
      "message": "Display id=%d is ignoring all orientation requests, return %d",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "1653025361": {
      "message": "Register task fragment organizer=%s uid=%d pid=%d",
      "level": "VERBOSE",
@@ -4117,6 +4111,12 @@
      "group": "WM_DEBUG_WINDOW_ORGANIZER",
      "at": "com\/android\/server\/wm\/DisplayAreaPolicyBuilder.java"
    },
    "1877863087": {
      "message": "Display id=%d is ignoring orientation request for %d, return %d",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "1878927091": {
      "message": "prepareSurface: No changes in animation for %s",
      "level": "VERBOSE",
+2 −5
Original line number Diff line number Diff line
@@ -7756,10 +7756,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // configuration. This is important to cases where activities with incompatible
        // orientations launch, or user goes back from an activity of bi-orientation to an
        // activity with specified orientation.
        if (getRequestedOrientation() == SCREEN_ORIENTATION_UNSET) {
            return;
        }

        if (onDescendantOrientationChanged(this)) {
            // WM Shell can show additional UI elements, e.g. a restart button for size compat mode
            // so ensure that WM Shell is called when an activity becomes visible.
@@ -8329,7 +8325,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // If orientation is respected when insets are applied, then stableBounds will be empty.
        boolean orientationRespectedWithInsets =
                orientationRespectedWithInsets(parentBounds, stableBounds);
        if (handlesOrientationChangeFromDescendant() && orientationRespectedWithInsets) {
        if (orientationRespectedWithInsets
                && handlesOrientationChangeFromDescendant(mOrientation)) {
            // No need to letterbox because of fixed orientation. Display will handle
            // fixed-orientation requests and a display rotation is enough to respect requested
            // orientation with insets applied.
+33 −12
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import static com.android.server.wm.DisplayAreaProto.WINDOW_CONTAINER;
import static com.android.server.wm.WindowContainerChildProto.DISPLAY_AREA;

import android.annotation.Nullable;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
@@ -141,26 +143,30 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
    }

    @Override
    @ScreenOrientation
    int getOrientation(int candidate) {
        final int orientation = super.getOrientation(candidate);
        if (getIgnoreOrientationRequest(orientation)) {
            // In all the other case, mLastOrientationSource will be reassigned to a new value
            mLastOrientationSource = null;
        if (getIgnoreOrientationRequest()) {
            return SCREEN_ORIENTATION_UNSET;
        }

        return super.getOrientation(candidate);
        return orientation;
    }

    @Override
    boolean handlesOrientationChangeFromDescendant() {
        return !getIgnoreOrientationRequest()
                && super.handlesOrientationChangeFromDescendant();
    boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
        return !getIgnoreOrientationRequest(orientation)
                && super.handlesOrientationChangeFromDescendant(orientation);
    }

    @Override
    boolean onDescendantOrientationChanged(WindowContainer requestingContainer) {
    boolean onDescendantOrientationChanged(@Nullable WindowContainer requestingContainer) {
        // If this is set to ignore the orientation request, we don't propagate descendant
        // orientation request.
        return !getIgnoreOrientationRequest()
        final int orientation = requestingContainer != null
                ? requestingContainer.mOrientation : SCREEN_ORIENTATION_UNSET;
        return !getIgnoreOrientationRequest(orientation)
                && super.onDescendantOrientationChanged(requestingContainer);
    }

@@ -224,6 +230,23 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
        }
    }

    /**
     * @return {@value true} if we need to ignore the orientation in input.
     */
    // TODO(b/262366204): Rename getIgnoreOrientationRequest to shouldIgnoreOrientationRequest
    boolean getIgnoreOrientationRequest(@ScreenOrientation int orientation) {
        // We always respect orientation request for ActivityInfo.SCREEN_ORIENTATION_LOCKED
        // ActivityInfo.SCREEN_ORIENTATION_NOSENSOR.
        // Main use case why this is important is Camera apps that rely on those
        // properties to ensure that they will be able to determine Camera preview
        // orientation correctly
        if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED
                || orientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
            return false;
        }
        return getIgnoreOrientationRequest();
    }

    boolean getIgnoreOrientationRequest() {
        // Adding an exception for when ignoreOrientationRequest is overridden at runtime for all
        // DisplayArea-s. For example, this is needed for the Kids Mode since many Kids apps aren't
@@ -640,11 +663,9 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
        }

        @Override
        @ScreenOrientation
        int getOrientation(int candidate) {
            mLastOrientationSource = null;
            if (getIgnoreOrientationRequest()) {
                return SCREEN_ORIENTATION_UNSET;
            }

            // Find a window requesting orientation.
            final WindowState win = getWindow(mGetOrientingWindow);
+21 −32
Original line number Diff line number Diff line
@@ -1558,13 +1558,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    @Override
    boolean onDescendantOrientationChanged(WindowContainer requestingContainer) {
    boolean onDescendantOrientationChanged(@Nullable WindowContainer requestingContainer) {
        final Configuration config = updateOrientation(
                requestingContainer, false /* forceUpdate */);
        // If display rotation class tells us that it doesn't consider app requested orientation,
        // this display won't rotate just because of an app changes its requested orientation. Thus
        // it indicates that this display chooses not to handle this request.
        final boolean handled = handlesOrientationChangeFromDescendant();
        final int orientation = requestingContainer != null ? requestingContainer.mOrientation
                : SCREEN_ORIENTATION_UNSET;
        final boolean handled = handlesOrientationChangeFromDescendant(orientation);
        if (config == null) {
            return handled;
        }
@@ -1587,8 +1589,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    @Override
    boolean handlesOrientationChangeFromDescendant() {
        return !getIgnoreOrientationRequest()
    boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
        return !getIgnoreOrientationRequest(orientation)
                && !getDisplayRotation().isFixedToUserRotation();
    }

@@ -1689,7 +1691,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            return ROTATION_UNDEFINED;
        }
        if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM
                || getIgnoreOrientationRequest()) {
                || getIgnoreOrientationRequest(r.mOrientation)) {
            return ROTATION_UNDEFINED;
        }
        if (r.mOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
@@ -2688,15 +2690,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    @ScreenOrientation
    @Override
    int getOrientation() {
        mLastOrientationSource = null;
        if (!handlesOrientationChangeFromDescendant()) {
            // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
            ProtoLog.v(WM_DEBUG_ORIENTATION,
                    "Display id=%d is ignoring all orientation requests, return %d",
                    mDisplayId, SCREEN_ORIENTATION_UNSPECIFIED);
            return SCREEN_ORIENTATION_UNSPECIFIED;
        }

        if (mWmService.mDisplayFrozen) {
            if (mWmService.mPolicy.isKeyguardLocked()) {
                // Use the last orientation the while the display is frozen with the keyguard
@@ -2712,6 +2705,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }

        final int orientation = super.getOrientation();

        if (!handlesOrientationChangeFromDescendant(orientation)) {
            mLastOrientationSource = null;
            // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
            ProtoLog.v(WM_DEBUG_ORIENTATION,
                    "Display id=%d is ignoring orientation request for %d, return %d",
                    mDisplayId, orientation, SCREEN_ORIENTATION_UNSPECIFIED);
            return SCREEN_ORIENTATION_UNSPECIFIED;
        }

        if (orientation == SCREEN_ORIENTATION_UNSET) {
            // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
            ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -3832,18 +3835,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    /** Called when the focused {@link TaskDisplayArea} on this display may have changed. */
    void onLastFocusedTaskDisplayAreaChanged(@Nullable TaskDisplayArea taskDisplayArea) {
        // Only record the TaskDisplayArea that handles orientation request.
        if (taskDisplayArea != null && taskDisplayArea.handlesOrientationChangeFromDescendant()) {
        mOrientationRequestingTaskDisplayArea = taskDisplayArea;
            return;
        }

        // If the previous TDA no longer handles orientation request, clear it.
        if (mOrientationRequestingTaskDisplayArea != null
                && !mOrientationRequestingTaskDisplayArea
                .handlesOrientationChangeFromDescendant()) {
            mOrientationRequestingTaskDisplayArea = null;
        }
    }

    /**
@@ -5053,13 +5045,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }

        @Override
        int getOrientation(int candidate) {
            if (getIgnoreOrientationRequest()) {
                return SCREEN_ORIENTATION_UNSET;
            }

        @ScreenOrientation
        int getOrientation(@ScreenOrientation int candidate) {
            // IME does not participate in orientation.
            return candidate;
            return getIgnoreOrientationRequest(candidate) ? SCREEN_ORIENTATION_UNSET : candidate;
        }

        @Override
+4 −3
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -2686,8 +2687,8 @@ class Task extends TaskFragment {
    }

    @Override
    boolean handlesOrientationChangeFromDescendant() {
        if (!super.handlesOrientationChangeFromDescendant()) {
    boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
        if (!super.handlesOrientationChangeFromDescendant(orientation)) {
            return false;
        }

@@ -2702,7 +2703,7 @@ class Task extends TaskFragment {
        // Check for leaf Task.
        // Display won't rotate for the orientation request if the Task/TaskDisplayArea
        // can't specify orientation.
        return canSpecifyOrientation() && getDisplayArea().canSpecifyOrientation();
        return canSpecifyOrientation() && getDisplayArea().canSpecifyOrientation(orientation);
    }

    void resize(boolean relayout, boolean forced) {
Loading