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

Commit e747c3e4 authored by Evan Rosky's avatar Evan Rosky
Browse files

Move some display logic into hierarchy [2/2]

Move display update logic from WM into ATM hierarchy by letting
ActivityStack watch for relevant changes and calculate bounds
accordingly and removing configuration updates from WM side
outside of calls from the display-level controller (like how
the other levels work).

One of the main display-changes to account for is rotation. To
make this work without drastically modifying things was to leave
display freeze/startSeamless in WM but move the actual rotation
to ATM while handling SEND_NEW_CONFIGURATION. This prevents
changes to the wm-side hierarchy outside of ATMS's control.

To facilitate this extra communication between ATMS and WM,
this adds rotation into WindowConfiguration. This makes rotation
available to the hierarchy update for policies that care about it
(things like split). It will also replace TaskStack's mRotation
in an upcoming CL and should also let us remove the one-off
variable for landscape->seascape orientation changes (needs
some more research though).

Bug: 113900640
Test: go/wm-smoke + relevant am/wm servicestests
Change-Id: I12c79cc5eb94d48d846f1cf27765c9f9f6741435
parent 39b6f235
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -208,10 +208,12 @@ package android.app {
    method public int getActivityType();
    method public android.graphics.Rect getAppBounds();
    method public android.graphics.Rect getBounds();
    method public int getRotation();
    method public int getWindowingMode();
    method public void setActivityType(int);
    method public void setAppBounds(android.graphics.Rect);
    method public void setBounds(android.graphics.Rect);
    method public void setRotation(int);
    method public void setTo(android.app.WindowConfiguration);
    method public void setWindowingMode(int);
    method public void writeToParcel(android.os.Parcel, int);
@@ -220,6 +222,7 @@ package android.app {
    field public static final int ACTIVITY_TYPE_RECENTS = 3; // 0x3
    field public static final int ACTIVITY_TYPE_STANDARD = 1; // 0x1
    field public static final int ACTIVITY_TYPE_UNDEFINED = 0; // 0x0
    field public static final int ROTATION_UNDEFINED = -1; // 0xffffffff
    field public static final int WINDOWING_MODE_FREEFORM = 5; // 0x5
    field public static final int WINDOWING_MODE_FULLSCREEN = 1; // 0x1
    field public static final int WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY = 4; // 0x4
+42 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.ActivityThread.isSystem;
import static android.app.WindowConfigurationProto.ACTIVITY_TYPE;
import static android.app.WindowConfigurationProto.APP_BOUNDS;
import static android.app.WindowConfigurationProto.WINDOWING_MODE;
import static android.view.Surface.rotationToString;

import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -60,6 +61,17 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
     */
    private Rect mAppBounds;

    /**
     * The current rotation of this window container relative to the default
     * orientation of the display it is on (regardless of how deep in the hierarchy
     * it is). It is used by the configuration hierarchy to apply rotation-dependent
     * policy during bounds calculation.
     */
    private int mRotation = ROTATION_UNDEFINED;

    /** Rotation is not defined, use the parent containers rotation. */
    public static final int ROTATION_UNDEFINED = -1;

    /** The current windowing mode of the configuration. */
    private @WindowingMode int mWindowingMode;

@@ -161,6 +173,9 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
    /** Bit that indicates that the {@link #mAlwaysOnTop} changed.
     * @hide */
    public static final int WINDOW_CONFIG_ALWAYS_ON_TOP = 1 << 4;
    /** Bit that indicates that the {@link #mRotation} changed.
     * @hide */
    public static final int WINDOW_CONFIG_ROTATION = 1 << 5;
    /** @hide */
    @IntDef(flag = true, prefix = { "WINDOW_CONFIG_" }, value = {
            WINDOW_CONFIG_BOUNDS,
@@ -168,6 +183,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
            WINDOW_CONFIG_WINDOWING_MODE,
            WINDOW_CONFIG_ACTIVITY_TYPE,
            WINDOW_CONFIG_ALWAYS_ON_TOP,
            WINDOW_CONFIG_ROTATION,
    })
    public @interface WindowConfig {}

@@ -194,6 +210,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        dest.writeInt(mWindowingMode);
        dest.writeInt(mActivityType);
        dest.writeInt(mAlwaysOnTop);
        dest.writeInt(mRotation);
    }

    private void readFromParcel(Parcel source) {
@@ -202,6 +219,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        mWindowingMode = source.readInt();
        mActivityType = source.readInt();
        mAlwaysOnTop = source.readInt();
        mRotation = source.readInt();
    }

    @Override
@@ -287,6 +305,14 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        return mBounds;
    }

    public int getRotation() {
        return mRotation;
    }

    public void setRotation(int rotation) {
        mRotation = rotation;
    }

    public void setWindowingMode(@WindowingMode int windowingMode) {
        mWindowingMode = windowingMode;
    }
@@ -324,6 +350,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        setWindowingMode(other.mWindowingMode);
        setActivityType(other.mActivityType);
        setAlwaysOnTop(other.mAlwaysOnTop);
        setRotation(other.mRotation);
    }

    /** Set this object to completely undefined.
@@ -339,6 +366,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        setWindowingMode(WINDOWING_MODE_UNDEFINED);
        setActivityType(ACTIVITY_TYPE_UNDEFINED);
        setAlwaysOnTop(ALWAYS_ON_TOP_UNDEFINED);
        setRotation(ROTATION_UNDEFINED);
    }

    /**
@@ -375,6 +403,10 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
            changed |= WINDOW_CONFIG_ALWAYS_ON_TOP;
            setAlwaysOnTop(delta.mAlwaysOnTop);
        }
        if (delta.mRotation != ROTATION_UNDEFINED && delta.mRotation != mRotation) {
            changed |= WINDOW_CONFIG_ROTATION;
            setRotation(delta.mRotation);
        }
        return changed;
    }

@@ -418,6 +450,11 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
            changes |= WINDOW_CONFIG_ALWAYS_ON_TOP;
        }

        if ((compareUndefined || other.mRotation != ROTATION_UNDEFINED)
                && mRotation != other.mRotation) {
            changes |= WINDOW_CONFIG_ROTATION;
        }

        return changes;
    }

@@ -454,6 +491,8 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        if (n != 0) return n;
        n = mAlwaysOnTop - that.mAlwaysOnTop;
        if (n != 0) return n;
        n = mRotation - that.mRotation;
        if (n != 0) return n;

        // if (n != 0) return n;
        return n;
@@ -482,6 +521,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        result = 31 * result + mWindowingMode;
        result = 31 * result + mActivityType;
        result = 31 * result + mAlwaysOnTop;
        result = 31 * result + mRotation;
        return result;
    }

@@ -493,6 +533,8 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
                + " mWindowingMode=" + windowingModeToString(mWindowingMode)
                + " mActivityType=" + activityTypeToString(mActivityType)
                + " mAlwaysOnTop=" + alwaysOnTopToString(mAlwaysOnTop)
                + " mRotation=" + (mRotation == ROTATION_UNDEFINED
                        ? "undefined" : rotationToString(mRotation))
                + "}";
    }

+0 −3
Original line number Diff line number Diff line
@@ -111,9 +111,6 @@ interface IWindowManager
    // caller must call setNewConfiguration() sometime later.
    Configuration updateOrientationFromAppTokens(in Configuration currentConfig,
            IBinder freezeThisOneIfNeeded, int displayId);
    // Notify window manager of the new display override configuration. Returns an array of stack
    // ids that were affected by the update, ActivityManager should resize these stacks.
    int[] setNewDisplayOverrideConfiguration(in Configuration overrideConfig, int displayId);

    void startFreezingScreen(int exitAnim, int enterAnim);
    void stopFreezingScreen();
+22 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
@@ -51,6 +52,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.WindowConfiguration;
import android.content.res.Configuration;
import android.graphics.Point;
import android.os.UserHandle;
import android.util.IntArray;
@@ -156,7 +158,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
    }

    void updateBounds() {
        mDisplay.getSize(mTmpDisplaySize);
        mDisplay.getRealSize(mTmpDisplaySize);
        setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y);
    }

@@ -938,6 +940,25 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        return mStacks.indexOf(stack);
    }

    @Override
    public void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
        final int currRotation = getOverrideConfiguration().windowConfiguration.getRotation();
        if (currRotation != ROTATION_UNDEFINED
                && currRotation != overrideConfiguration.windowConfiguration.getRotation()
                && getWindowContainerController() != null) {
            getWindowContainerController().applyRotation(currRotation,
                    overrideConfiguration.windowConfiguration.getRotation());
        }
        super.onOverrideConfigurationChanged(overrideConfiguration);
    }

    @Override
    public void onConfigurationChanged(Configuration newParentConfig) {
        // update resources before cascade so that docked/pinned stacks use the correct info
        getWindowContainerController().preOnConfigurationChanged();
        super.onConfigurationChanged(newParentConfig);
    }

    void onLockTaskPackagesUpdated() {
        for (int i = mStacks.size() - 1; i >= 0; --i) {
            mStacks.get(i).onLockTaskPackagesUpdated();
+23 −12
Original line number Diff line number Diff line
@@ -46,6 +46,13 @@ import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_TASK_TO_BACK;
import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;

import static com.android.server.am.ActivityStackProto.BOUNDS;
import static com.android.server.am.ActivityStackProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.ActivityStackProto.DISPLAY_ID;
import static com.android.server.am.ActivityStackProto.FULLSCREEN;
import static com.android.server.am.ActivityStackProto.ID;
import static com.android.server.am.ActivityStackProto.RESUMED_ACTIVITY;
import static com.android.server.am.ActivityStackProto.TASKS;
import static com.android.server.wm.ActivityDisplay.POSITION_BOTTOM;
import static com.android.server.wm.ActivityDisplay.POSITION_TOP;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
@@ -56,13 +63,6 @@ import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
import static com.android.server.am.ActivityStackProto.BOUNDS;
import static com.android.server.am.ActivityStackProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.ActivityStackProto.DISPLAY_ID;
import static com.android.server.am.ActivityStackProto.FULLSCREEN;
import static com.android.server.am.ActivityStackProto.ID;
import static com.android.server.am.ActivityStackProto.RESUMED_ACTIVITY;
import static com.android.server.am.ActivityStackProto.TASKS;
import static com.android.server.wm.ActivityStackSupervisor.FindTaskResult;
import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
@@ -513,14 +513,23 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
    public void onConfigurationChanged(Configuration newParentConfig) {
        final int prevWindowingMode = getWindowingMode();
        final boolean prevIsAlwaysOnTop = isAlwaysOnTop();
        super.onConfigurationChanged(newParentConfig);
        final ActivityDisplay display = getDisplay();

        getBounds(mTmpRect2);
        final boolean hasNewBounds = display != null && getWindowContainerController() != null
                && getWindowContainerController().updateBoundsForConfigChange(
                        newParentConfig, getConfiguration(), mTmpRect2);

        super.onConfigurationChanged(newParentConfig);
        if (display == null) {
          return;
        }
        if (prevWindowingMode != getWindowingMode()) {
            display.onStackWindowingModeChanged(this);
        }
        if (hasNewBounds) {
            resize(mTmpRect2, null /* tempTaskBounds */, null /* tempTaskInsetBounds */);
        }
        if (prevIsAlwaysOnTop != isAlwaysOnTop()) {
            // Since always on top is only on when the stack is freeform or pinned, the state
            // can be toggled when the windowing mode changes. We must make sure the stack is
@@ -752,6 +761,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
     * @param bounds Updated bounds.
     */
    private void postAddToDisplay(ActivityDisplay activityDisplay, Rect bounds, boolean onTop) {
        if (mDisplayId != activityDisplay.mDisplayId) {
            // rotations are relative to the display, so pretend like our current rotation is
            // the same as the new display so we don't try to rotate bounds.
            getConfiguration().windowConfiguration.setRotation(
                    activityDisplay.getWindowConfiguration().getRotation());
        }
        mDisplayId = activityDisplay.mDisplayId;
        setBounds(bounds);
        onParentChanged();
@@ -810,10 +825,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        outBounds.setEmpty();
    }

    void getBoundsForNewConfiguration(Rect outBounds) {
        mWindowContainerController.getBoundsForNewConfiguration(outBounds);
    }

    void positionChildWindowContainerAtTop(TaskRecord child) {
        mWindowContainerController.positionChildAtTop(child.getWindowContainerController(),
                true /* includingParents */);
Loading