diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index 3bffa890122ac..e3430a6868647 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -268,6 +268,20 @@ public final class WindowContainerTransaction implements Parcelable { return this; } + /** + * Sets whether a task should be translucent. When {@code false}, the existing translucent of + * the task applies, but when {@code true} the task will be forced to be translucent. + * @hide + */ + @NonNull + public WindowContainerTransaction setForceTranslucent( + @NonNull WindowContainerToken container, boolean forceTranslucent) { + Change chg = getOrCreateChange(container.asBinder()); + chg.mForceTranslucent = forceTranslucent; + chg.mChangeMask |= Change.CHANGE_FORCE_TRANSLUCENT; + 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 @@ -834,11 +848,13 @@ public final class WindowContainerTransaction implements Parcelable { public static final int CHANGE_BOUNDS_TRANSACTION_RECT = 1 << 4; public static final int CHANGE_IGNORE_ORIENTATION_REQUEST = 1 << 5; public static final int CHANGE_FORCE_NO_PIP = 1 << 6; + public static final int CHANGE_FORCE_TRANSLUCENT = 1 << 7; private final Configuration mConfiguration = new Configuration(); private boolean mFocusable = true; private boolean mHidden = false; private boolean mIgnoreOrientationRequest = false; + private boolean mForceTranslucent = false; private int mChangeMask = 0; private @ActivityInfo.Config int mConfigSetMask = 0; @@ -858,6 +874,7 @@ public final class WindowContainerTransaction implements Parcelable { mFocusable = in.readBoolean(); mHidden = in.readBoolean(); mIgnoreOrientationRequest = in.readBoolean(); + mForceTranslucent = in.readBoolean(); mChangeMask = in.readInt(); mConfigSetMask = in.readInt(); mWindowSetMask = in.readInt(); @@ -903,6 +920,9 @@ public final class WindowContainerTransaction implements Parcelable { if ((other.mChangeMask & CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) { mIgnoreOrientationRequest = other.mIgnoreOrientationRequest; } + if ((other.mChangeMask & CHANGE_FORCE_TRANSLUCENT) != 0) { + mForceTranslucent = other.mForceTranslucent; + } mChangeMask |= other.mChangeMask; if (other.mActivityWindowingMode >= 0) { mActivityWindowingMode = other.mActivityWindowingMode; @@ -953,6 +973,15 @@ public final class WindowContainerTransaction implements Parcelable { return mIgnoreOrientationRequest; } + /** Gets the requested force translucent state. */ + public boolean getForceTranslucent() { + if ((mChangeMask & CHANGE_FORCE_TRANSLUCENT) == 0) { + throw new RuntimeException("Force translucent not set. " + + "Check CHANGE_FORCE_TRANSLUCENT first"); + } + return mForceTranslucent; + } + public int getChangeMask() { return mChangeMask; } @@ -1030,6 +1059,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeBoolean(mFocusable); dest.writeBoolean(mHidden); dest.writeBoolean(mIgnoreOrientationRequest); + dest.writeBoolean(mForceTranslucent); dest.writeInt(mChangeMask); dest.writeInt(mConfigSetMask); dest.writeInt(mWindowSetMask); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 2ba0e23f90117..cb90501231c4a 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -489,6 +489,7 @@ class Task extends TaskFragment { static final int FLAG_FORCE_HIDDEN_FOR_PINNED_TASK = 1; static final int FLAG_FORCE_HIDDEN_FOR_TASK_ORG = 1 << 1; private int mForceHiddenFlags = 0; + private boolean mForceTranslucent = false; // TODO(b/160201781): Revisit double invocation issue in Task#removeChild. /** @@ -4348,6 +4349,10 @@ class Task extends TaskFragment { return true; } + void setForceTranslucent(boolean set) { + mForceTranslucent = set; + } + @Override public boolean isAlwaysOnTop() { return !isForceHidden() && super.isAlwaysOnTop(); @@ -4365,6 +4370,11 @@ class Task extends TaskFragment { return mForceHiddenFlags != 0; } + @Override + protected boolean isForceTranslucent() { + return mForceTranslucent; + } + @Override long getProtoFieldId() { return TASK; diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 8d94324a1414f..5f85a14010141 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -740,6 +740,10 @@ class TaskFragment extends WindowContainer { return false; } + protected boolean isForceTranslucent() { + return false; + } + boolean isLeafTaskFragment() { for (int i = mChildren.size() - 1; i >= 0; --i) { if (mChildren.get(i).asTaskFragment() != null) { @@ -865,7 +869,7 @@ class TaskFragment extends WindowContainer { */ @VisibleForTesting boolean isTranslucent(ActivityRecord starting) { - if (!isAttached() || isForceHidden()) { + if (!isAttached() || isForceHidden() || isForceTranslucent()) { return true; } final PooledPredicate p = PooledLambda.obtainPredicate(TaskFragment::isOpaqueActivity, diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 29e407fccdb70..5a2100d4ecacd 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -645,6 +645,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } } + if ((c.getChangeMask() + & WindowContainerTransaction.Change.CHANGE_FORCE_TRANSLUCENT) != 0) { + tr.setForceTranslucent(c.getForceTranslucent()); + effects = TRANSACT_EFFECTS_LIFECYCLE; + } + final int childWindowingMode = c.getActivityWindowingMode(); if (childWindowingMode > -1) { tr.setActivityWindowingMode(childWindowingMode); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 84c2c551de85f..7d4e6fa53a64a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -577,6 +577,22 @@ public class WindowOrganizerTests extends WindowTestsBase { assertTrue(rootTask.shouldBeVisible(null)); } + @Test + public void testContainerTranslucentChanges() { + removeGlobalMinSizeRestriction(); + final Task rootTask = new TaskBuilder(mSupervisor).setCreateActivity(true) + .setWindowingMode(WINDOWING_MODE_FULLSCREEN).build(); + final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(rootTask).build(); + WindowContainerTransaction t = new WindowContainerTransaction(); + assertFalse(rootTask.isTranslucent(activity)); + t.setForceTranslucent(rootTask.mRemoteToken.toWindowContainerToken(), true); + mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); + assertTrue(rootTask.isTranslucent(activity)); + t.setForceTranslucent(rootTask.mRemoteToken.toWindowContainerToken(), false); + mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); + assertFalse(rootTask.isTranslucent(activity)); + } + @Test public void testSetIgnoreOrientationRequest_taskDisplayArea() { removeGlobalMinSizeRestriction();