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

Commit ed1460ec authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Task level letterboxing for cold start with ignore orientation request"

parents da0f644d 53f705fb
Loading
Loading
Loading
Loading
+34 −6
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCR
import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;

import android.app.ActivityManager;
import android.util.ArraySet;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.util.ArrayMap;
import android.util.Slog;
import android.view.SurfaceControl;

@@ -37,7 +39,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {

    private final SyncTransactionQueue mSyncQueue;

    private final ArraySet<Integer> mTasks = new ArraySet<>();
    private final ArrayMap<Integer, SurfaceControl> mTasks = new ArrayMap<>();

    FullscreenTaskListener(SyncTransactionQueue syncQueue) {
        mSyncQueue = syncQueue;
@@ -46,16 +48,16 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
    @Override
    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
        synchronized (mTasks) {
            if (mTasks.contains(taskInfo.taskId)) {
            if (mTasks.containsKey(taskInfo.taskId)) {
                throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId);
            }
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d",
                    taskInfo.taskId);
            mTasks.add(taskInfo.taskId);
            mTasks.put(taskInfo.taskId, leash);
            mSyncQueue.runInSync(t -> {
                // Reset several properties back to fullscreen (PiP, for example, leaves all these
                // properties in a bad state).
                t.setPosition(leash, 0, 0);
                updateSurfacePosition(t, taskInfo, leash);
                t.setWindowCrop(leash, null);
                // TODO(shell-transitions): Eventually set everything in transition so there's no
                //                          SF Transaction here.
@@ -71,7 +73,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
    @Override
    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
        synchronized (mTasks) {
            if (!mTasks.remove(taskInfo.taskId)) {
            if (mTasks.remove(taskInfo.taskId) == null) {
                Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
                return;
            }
@@ -80,6 +82,23 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
        }
    }

    @Override
    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
        synchronized (mTasks) {
            if (!mTasks.containsKey(taskInfo.taskId)) {
                Slog.e(TAG, "Changed Task wasn't appeared or already vanished: #"
                        + taskInfo.taskId);
                return;
            }
            final SurfaceControl leash = mTasks.get(taskInfo.taskId);
            mSyncQueue.runInSync(t -> {
                // Reposition the task in case the bounds has been changed (such as Task level
                // letterboxing).
                updateSurfacePosition(t, taskInfo, leash);
            });
        }
    }

    @Override
    public void dump(@NonNull PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
@@ -92,4 +111,13 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
    public String toString() {
        return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN);
    }

    /** Places the Task surface to the latest position. */
    private static void updateSurfacePosition(SurfaceControl.Transaction t,
            ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
        // TODO(170725334) drop this after ag/12876439
        final Configuration config = taskInfo.getConfiguration();
        final Rect bounds = config.windowConfiguration.getBounds();
        t.setPosition(leash, bounds.left, bounds.top);
    }
}
+27 −13
Original line number Diff line number Diff line
@@ -6406,6 +6406,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        mLastReportedConfiguration.setConfiguration(global, override);
    }

    boolean hasCompatDisplayInsets() {
        return mCompatDisplayInsets != null;
    }

    /**
     * @return {@code true} if this activity is in size compatibility mode that uses the different
     *         density than its parent or its bounds don't fit in parent naturally.
@@ -6544,7 +6548,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        mSizeCompatScale = 1f;
        mSizeCompatBounds = null;
        mCompatDisplayInsets = null;
        onRequestedOverrideConfigurationChanged(EMPTY);

        // Recompute from Task because letterbox can also happen on Task level.
        task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration());
    }

    @Override
@@ -6653,9 +6659,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                ? requestedOrientation
                : newParentConfiguration.orientation;
        int rotation = newParentConfiguration.windowConfiguration.getRotation();
        final boolean canChangeOrientation = handlesOrientationChangeFromDescendant();
        if (canChangeOrientation && !mCompatDisplayInsets.mIsFloating) {
            // Use parent rotation because the original display can rotate by requested orientation.
        final boolean isFixedToUserRotation = mDisplayContent == null
                || mDisplayContent.getDisplayRotation().isFixedToUserRotation();
        if (!isFixedToUserRotation && !mCompatDisplayInsets.mIsFloating) {
            // Use parent rotation because the original display can be rotated.
            resolvedConfig.windowConfiguration.setRotation(rotation);
        } else {
            final int overrideRotation = resolvedConfig.windowConfiguration.getRotation();
@@ -6671,7 +6678,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        final Rect containingAppBounds = new Rect();
        final Rect containingBounds = mTmpBounds;
        mCompatDisplayInsets.getContainerBounds(containingAppBounds, containingBounds, rotation,
                orientation, orientationRequested, canChangeOrientation);
                orientation, orientationRequested, isFixedToUserRotation);
        resolvedBounds.set(containingBounds);
        // The size of floating task is fixed (only swap), so the aspect ratio is already correct.
        if (!mCompatDisplayInsets.mIsFloating) {
@@ -7740,7 +7747,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        final Rect[] mStableInsets = new Rect[4];

        /** Constructs the environment to simulate the bounds behavior of the given container. */
        CompatDisplayInsets(DisplayContent display, WindowContainer container) {
        CompatDisplayInsets(DisplayContent display, ActivityRecord container) {
            mIsFloating = container.getWindowConfiguration().tasksAreFloating();
            if (mIsFloating) {
                final Rect containerBounds = container.getWindowConfiguration().getBounds();
@@ -7756,16 +7763,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                return;
            }

            // If the activity is not floating, assume it fills the display.
            if (container.getTask().isTaskLetterboxed()) {
                // For apps in Task letterbox, it should fill the task bounds.
                final Rect taskBounds = container.getTask().getBounds();
                mWidth = taskBounds.width();
                mHeight = taskBounds.height();
            } else {
                // If the activity is not floating nor letterboxed, assume it fills the display.
                mWidth = display.mBaseDisplayWidth;
                mHeight = display.mBaseDisplayHeight;
            }
            final DisplayPolicy policy = display.getDisplayPolicy();
            for (int rotation = 0; rotation < 4; rotation++) {
                mNonDecorInsets[rotation] = new Rect();
                mStableInsets[rotation] = new Rect();
                final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
                final int dw = rotated ? mHeight : mWidth;
                final int dh = rotated ? mWidth : mHeight;
                final int dw = rotated ? display.mBaseDisplayHeight : display.mBaseDisplayWidth;
                final int dh = rotated ? display.mBaseDisplayWidth : display.mBaseDisplayHeight;
                final DisplayCutout cutout = display.calculateDisplayCutoutForRotation(rotation)
                        .getDisplayCutout();
                policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]);
@@ -7791,7 +7805,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

        /** Gets the horizontal centered container bounds for size compatibility mode. */
        void getContainerBounds(Rect outAppBounds, Rect outBounds, int rotation, int orientation,
                boolean orientationRequested, boolean canChangeOrientation) {
                boolean orientationRequested, boolean isFixedToUserRotation) {
            getFrameByOrientation(outBounds, orientation);
            if (mIsFloating) {
                outAppBounds.set(outBounds);
@@ -7804,7 +7818,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            final boolean isOrientationMismatched =
                    ((outBounds.width() > outBounds.height()) != (dW > dH));

            if (isOrientationMismatched && !canChangeOrientation && orientationRequested) {
            if (isOrientationMismatched && isFixedToUserRotation && orientationRequested) {
                // The orientation is mismatched but the display cannot rotate. The bounds will fit
                // to the short side of container.
                if (orientation == ORIENTATION_LANDSCAPE) {
+5 −0
Original line number Diff line number Diff line
@@ -145,6 +145,11 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
        return super.getOrientation(candidate);
    }

    @Override
    boolean handlesOrientationChangeFromDescendant() {
        return !mIgnoreOrientationRequest && super.handlesOrientationChangeFromDescendant();
    }

    /**
     * Sets whether this {@link DisplayArea} should ignore fixed-orientation request from apps and
     * windows below it.
+3 −4
Original line number Diff line number Diff line
@@ -109,7 +109,6 @@ import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY;
import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA;
import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
import static com.android.server.wm.DisplayContentProto.SINGLE_TASK_INSTANCE;
import static com.android.server.wm.Task.ActivityState.RESUMED;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -1310,7 +1309,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        // 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 = getDisplayRotation().respectAppRequestedOrientation();
        final boolean handled = handlesOrientationChangeFromDescendant();
        if (config == null) {
            return handled;
        }
@@ -1334,7 +1333,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    @Override
    boolean handlesOrientationChangeFromDescendant() {
        return getDisplayRotation().respectAppRequestedOrientation();
        return !mIgnoreOrientationRequest && !getDisplayRotation().isFixedToUserRotation();
    }

    /**
@@ -2346,7 +2345,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    @Override
    int getOrientation() {
        mLastOrientationSource = null;
        if (mIgnoreOrientationRequest) {
        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",
+0 −9
Original line number Diff line number Diff line
@@ -857,15 +857,6 @@ public class DisplayRotation {
        return mFixedToUserRotation;
    }

    /**
     * Returns {@code true} if this display rotation takes app requested orientation into
     * consideration; {@code false} otherwise. For the time being the only case where this is {@code
     * false} is when {@link #isFixedToUserRotation()} is {@code true}.
     */
    boolean respectAppRequestedOrientation() {
        return !isFixedToUserRotation();
    }

    public int getLandscapeRotation() {
        return mLandscapeRotation;
    }
Loading