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

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

Merge "Add WCT to disable Task to enter PiP" into main

parents 6ef52546 165b7d6f
Loading
Loading
Loading
Loading
+53 −16
Original line number Diff line number Diff line
@@ -351,20 +351,6 @@ public final class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * Used in conjunction with a shell-transition call (usually finishTransition). This is
     * basically a message to the transition system that a particular task should NOT go into
     * PIP even though it normally would. This is to deal with some edge-case situations where
     * Recents will "commit" the transition to go home, but then not actually go-home.
     * @hide
     */
    @NonNull
    public WindowContainerTransaction setDoNotPip(@NonNull WindowContainerToken container) {
        final Change chg = getOrCreateChange(container.asBinder());
        chg.mChangeMask |= Change.CHANGE_FORCE_NO_PIP;
        return this;
    }

    /**
     * Resizes a container by providing a bounds in its parent coordinate.
     * This is only used by {@link TaskFragmentOrganizer}.
@@ -913,6 +899,41 @@ public final class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * Used in conjunction with a shell-transition call (usually finishTransition). This is
     * basically a message to the transition system that a particular task should NOT go into
     * PIP even though it normally would. This is to deal with some edge-case situations where
     * Recents will "commit" the transition to go home, but then not actually go-home.
     * @hide
     */
    @NonNull
    public WindowContainerTransaction setDoNotPip(@NonNull WindowContainerToken container) {
        final Change chg = getOrCreateChange(container.asBinder());
        chg.mChangeMask |= Change.CHANGE_FORCE_NO_PIP;
        return this;
    }

    /**
     * Sets whether a Task or any of its children can enter picture-in-picture.
     * When {@code false}, the container and its children won't be able to enter PiP.
     *
     * Note: this is different from {@link #setDoNotPip}, which is to temporarily disable PiP during
     * finishTransition.
     * @hide
     */
    @NonNull
    public WindowContainerTransaction setDisablePip(
            @NonNull WindowContainerToken container, boolean disablePip) {
        if (!Flags.disallowBubbleToEnterPip()) {
            throw new IllegalStateException(
                    "Flag " + Flags.FLAG_DISALLOW_BUBBLE_TO_ENTER_PIP + " is not enabled");
        }
        final Change chg = getOrCreateChange(container.asBinder());
        chg.mChangeMask |= Change.CHANGE_DISABLE_PIP;
        chg.mDisablePip = disablePip;
        return this;
    }

    /*
     * ===========================================================================================
     * Insets
@@ -1355,6 +1376,7 @@ public final class WindowContainerTransaction implements Parcelable {
        public static final int CHANGE_RELATIVE_BOUNDS = 1 << 8;
        public static final int CHANGE_FORCE_EXCLUDED_FROM_RECENTS = 1 << 9;
        public static final int CHANGE_LAUNCH_NEXT_TO_BUBBLE = 1 << 10;
        public static final int CHANGE_DISABLE_PIP = 1 << 11;

        @IntDef(flag = true, prefix = { "CHANGE_" }, value = {
                CHANGE_FOCUSABLE,
@@ -1368,6 +1390,7 @@ public final class WindowContainerTransaction implements Parcelable {
                CHANGE_RELATIVE_BOUNDS,
                CHANGE_FORCE_EXCLUDED_FROM_RECENTS,
                CHANGE_LAUNCH_NEXT_TO_BUBBLE,
                CHANGE_DISABLE_PIP,
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface ChangeMask {}
@@ -1379,6 +1402,7 @@ public final class WindowContainerTransaction implements Parcelable {
        private boolean mForceTranslucent = false;
        private boolean mDragResizing = false;
        private boolean mForceExcludedFromRecents = false;
        private boolean mDisablePip = false;

        private @ChangeMask int mChangeMask = 0;
        private @ActivityInfo.Config int mConfigSetMask = 0;
@@ -1404,6 +1428,8 @@ public final class WindowContainerTransaction implements Parcelable {
            mForceTranslucent = in.readBoolean();
            mDragResizing = in.readBoolean();
            mForceExcludedFromRecents = in.readBoolean();
            mLaunchNextToBubble = in.readBoolean();
            mDisablePip = in.readBoolean();
            mChangeMask = in.readInt();
            mConfigSetMask = in.readInt();
            mWindowSetMask = in.readInt();
@@ -1419,7 +1445,6 @@ public final class WindowContainerTransaction implements Parcelable {

            mWindowingMode = in.readInt();
            mActivityWindowingMode = in.readInt();
            mLaunchNextToBubble = in.readBoolean();
        }

        /**
@@ -1456,6 +1481,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if ((other.mChangeMask & CHANGE_LAUNCH_NEXT_TO_BUBBLE) != 0) {
                mLaunchNextToBubble = other.mLaunchNextToBubble;
            }
            if ((other.mChangeMask & CHANGE_DISABLE_PIP) != 0) {
                mDisablePip = other.mDisablePip;
            }
            mChangeMask |= other.mChangeMask;
            if (other.mActivityWindowingMode >= WINDOWING_MODE_UNDEFINED) {
                mActivityWindowingMode = other.mActivityWindowingMode;
@@ -1546,6 +1574,11 @@ public final class WindowContainerTransaction implements Parcelable {
            return mForceExcludedFromRecents;
        }

        /** Gets whether the task is disabled to enter picture-in-picture. */
        public boolean getDisablePip() {
            return mDisablePip;
        }

        /** Gets whether the config should be sent to the client at the end of the transition. */
        public boolean getConfigAtTransitionEnd() {
            return mConfigAtTransitionEnd;
@@ -1619,6 +1652,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if ((mChangeMask & CHANGE_FORCE_EXCLUDED_FROM_RECENTS) != 0) {
                sb.append("forceExcludedFromRecents:" + mForceExcludedFromRecents + ",");
            }
            if ((mChangeMask & CHANGE_DISABLE_PIP) != 0) {
                sb.append("disablePip:" + mDisablePip + ",");
            }
            if (mBoundsChangeTransaction != null) {
                sb.append("hasBoundsTransaction,");
            }
@@ -1647,6 +1683,8 @@ public final class WindowContainerTransaction implements Parcelable {
            dest.writeBoolean(mForceTranslucent);
            dest.writeBoolean(mDragResizing);
            dest.writeBoolean(mForceExcludedFromRecents);
            dest.writeBoolean(mLaunchNextToBubble);
            dest.writeBoolean(mDisablePip);
            dest.writeInt(mChangeMask);
            dest.writeInt(mConfigSetMask);
            dest.writeInt(mWindowSetMask);
@@ -1661,7 +1699,6 @@ public final class WindowContainerTransaction implements Parcelable {

            dest.writeInt(mWindowingMode);
            dest.writeInt(mActivityWindowingMode);
            dest.writeBoolean(mLaunchNextToBubble);
        }

        @Override
+11 −0
Original line number Diff line number Diff line
@@ -221,3 +221,14 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    namespace: "windowing_sdk"
    name: "disallow_bubble_to_enter_pip"
    description: "Prevent Bubble task to enter picture-in-picture"
    bug: "389158353"
    is_fixed_read_only: true
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+9 −1
Original line number Diff line number Diff line
@@ -3190,6 +3190,14 @@ final class ActivityRecord extends WindowToken {
                && info.supportsPictureInPicture();
    }

    /**
     * Whether this activity can enter PiP now. This can be {@code false} if the system has disabled
     * this Task from entering PiP.
     */
    boolean canEnterPictureInPicture() {
        return supportsPictureInPicture() && (task == null || !task.isDisablePip());
    }

    boolean supportsFreeform() {
        return supportsFreeformInDisplayArea(getDisplayArea());
    }
@@ -3252,7 +3260,7 @@ final class ActivityRecord extends WindowToken {
     * @return whether this activity is currently allowed to enter PIP.
     */
    boolean checkEnterPictureInPictureState(String caller, boolean beforeStopping) {
        if (!supportsPictureInPicture()) {
        if (!canEnterPictureInPicture()) {
            return false;
        }

+38 −0
Original line number Diff line number Diff line
@@ -634,6 +634,9 @@ class Task extends TaskFragment {
    /** @see #isForceExcludedFromRecents() */
    private boolean mForceExcludedFromRecents;

    /** @see #isDisablePip() */
    private boolean mDisablePip;

    private Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent,
            Intent _affinityIntent, String _affinity, String _rootAffinity,
            ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
@@ -4606,6 +4609,35 @@ class Task extends TaskFragment {
        mForceExcludedFromRecents = excluded;
    }

    /**
     * Whether this Task and its children are disallowed from entering picture-in-picture.
     *
     * This is different from {@link #mSupportsPictureInPicture} which is determined based on the
     * activity manifest. This flag is set by WM Shell to disable PiP for the current Task status.
     */
    boolean isDisablePip() {
        if (!Flags.disallowBubbleToEnterPip()) {
            return false;
        }
        if (mDisablePip) {
            return true;
        }
        // Check if PIP is disabled on any parent Task.
        final WindowContainer parent = getParent();
        if (parent != null && parent.asTask() != null) {
            return parent.asTask().isDisablePip();
        }
        return false;
    }

    void setDisablePip(boolean disablePip) {
        if (!Flags.disallowBubbleToEnterPip()) {
            Slog.w(TAG, "Flag " + Flags.FLAG_DISALLOW_BUBBLE_TO_ENTER_PIP + " is not enabled");
            return;
        }
        mDisablePip = disablePip;
    }

    boolean isForceHiddenForPinnedTask() {
        return (mForceHiddenFlags & FLAG_FORCE_HIDDEN_FOR_PINNED_TASK) != 0;
    }
@@ -5392,6 +5424,9 @@ class Task extends TaskFragment {
        }
        final ActivityRecord[] candidate = new ActivityRecord[1];
        topTask.forAllLeafTaskFragments(tf -> {
            if (tf.getTask().isDisablePip()) {
                return false;
            }
            // Find the top activity that may enter Pip while pausing.
            final ActivityRecord topActivity = tf.getTopNonFinishingActivity();
            if (topActivity != null && topActivity.isState(RESUMED, PAUSING)
@@ -5970,6 +6005,9 @@ class Task extends TaskFragment {
        if (mLaunchNextToBubble) {
            pw.println(prefix + "  mLaunchNextToBubble=true");
        }
        if (mDisablePip) {
            pw.println(prefix + "  mDisablePip=true");
        }
        if (mLastNonFullscreenBounds != null) {
            pw.print(prefix); pw.print("  mLastNonFullscreenBounds=");
            pw.println(mLastNonFullscreenBounds);
+2 −1
Original line number Diff line number Diff line
@@ -1383,9 +1383,10 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
                        // it can be moved to a new created PIP Task, so WINDOWING_MODE_PINNED is
                        // always valid for Task as long as the device supports it.
                        || (windowingMode == WINDOWING_MODE_PINNED && supportsPip);
                supportsPip &= !task.isDisablePip();
            } else if (r != null) {
                supportsFreeform = r.supportsFreeformInDisplayArea(this);
                supportsPip = r.supportsPictureInPicture();
                supportsPip = r.canEnterPictureInPicture();
                supportsMultiWindow = r.supportsMultiWindowInDisplayArea(this);
            }
        }
Loading