summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Louis Chang <louischang@google.com> 2024-01-03 08:54:42 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-01-03 08:54:42 +0000
commit9c6b32c642bde3a6f7e80fdbbe1b2a77ad93220f (patch)
tree56eb290db7b40c9de2a91c68a9eb23885d681c79
parent970067a4be937cd89c4664d1faf5c1d7c611b935 (diff)
parente1776eb38ebf314213602e3ee8bd2fc28113c51b (diff)
Merge "Adding a new TaskFragmentOperation to set dim area on Task" into main
-rw-r--r--core/java/android/window/TaskFragmentOperation.java39
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java8
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java27
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java15
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java13
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java11
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java3
9 files changed, 127 insertions, 6 deletions
diff --git a/core/java/android/window/TaskFragmentOperation.java b/core/java/android/window/TaskFragmentOperation.java
index 0ec9ffe6390b..acc6a749e9b7 100644
--- a/core/java/android/window/TaskFragmentOperation.java
+++ b/core/java/android/window/TaskFragmentOperation.java
@@ -120,6 +120,11 @@ public final class TaskFragmentOperation implements Parcelable {
*/
public static final int OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE = 15;
+ /**
+ * Applies dimming on the parent Task which could cross two TaskFragments.
+ */
+ public static final int OP_TYPE_SET_DIM_ON_TASK = 16;
+
@IntDef(prefix = { "OP_TYPE_" }, value = {
OP_TYPE_UNKNOWN,
OP_TYPE_CREATE_TASK_FRAGMENT,
@@ -138,6 +143,7 @@ public final class TaskFragmentOperation implements Parcelable {
OP_TYPE_REORDER_TO_TOP_OF_TASK,
OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE,
OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE,
+ OP_TYPE_SET_DIM_ON_TASK,
})
@Retention(RetentionPolicy.SOURCE)
public @interface OperationType {}
@@ -165,12 +171,14 @@ public final class TaskFragmentOperation implements Parcelable {
private final boolean mIsolatedNav;
+ private final boolean mDimOnTask;
+
private TaskFragmentOperation(@OperationType int opType,
@Nullable TaskFragmentCreationParams taskFragmentCreationParams,
@Nullable IBinder activityToken, @Nullable Intent activityIntent,
@Nullable Bundle bundle, @Nullable IBinder secondaryFragmentToken,
@Nullable TaskFragmentAnimationParams animationParams,
- boolean isolatedNav) {
+ boolean isolatedNav, boolean dimOnTask) {
mOpType = opType;
mTaskFragmentCreationParams = taskFragmentCreationParams;
mActivityToken = activityToken;
@@ -179,6 +187,7 @@ public final class TaskFragmentOperation implements Parcelable {
mSecondaryFragmentToken = secondaryFragmentToken;
mAnimationParams = animationParams;
mIsolatedNav = isolatedNav;
+ mDimOnTask = dimOnTask;
}
private TaskFragmentOperation(Parcel in) {
@@ -190,6 +199,7 @@ public final class TaskFragmentOperation implements Parcelable {
mSecondaryFragmentToken = in.readStrongBinder();
mAnimationParams = in.readTypedObject(TaskFragmentAnimationParams.CREATOR);
mIsolatedNav = in.readBoolean();
+ mDimOnTask = in.readBoolean();
}
@Override
@@ -202,6 +212,7 @@ public final class TaskFragmentOperation implements Parcelable {
dest.writeStrongBinder(mSecondaryFragmentToken);
dest.writeTypedObject(mAnimationParams, flags);
dest.writeBoolean(mIsolatedNav);
+ dest.writeBoolean(mDimOnTask);
}
@NonNull
@@ -282,6 +293,13 @@ public final class TaskFragmentOperation implements Parcelable {
return mIsolatedNav;
}
+ /**
+ * Returns whether the dim layer should apply on the parent Task.
+ */
+ public boolean isDimOnTask() {
+ return mDimOnTask;
+ }
+
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
@@ -305,6 +323,7 @@ public final class TaskFragmentOperation implements Parcelable {
sb.append(", animationParams=").append(mAnimationParams);
}
sb.append(", isolatedNav=").append(mIsolatedNav);
+ sb.append(", dimOnTask=").append(mDimOnTask);
sb.append('}');
return sb.toString();
@@ -313,7 +332,7 @@ public final class TaskFragmentOperation implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mOpType, mTaskFragmentCreationParams, mActivityToken, mActivityIntent,
- mBundle, mSecondaryFragmentToken, mAnimationParams, mIsolatedNav);
+ mBundle, mSecondaryFragmentToken, mAnimationParams, mIsolatedNav, mDimOnTask);
}
@Override
@@ -329,7 +348,8 @@ public final class TaskFragmentOperation implements Parcelable {
&& Objects.equals(mBundle, other.mBundle)
&& Objects.equals(mSecondaryFragmentToken, other.mSecondaryFragmentToken)
&& Objects.equals(mAnimationParams, other.mAnimationParams)
- && mIsolatedNav == other.mIsolatedNav;
+ && mIsolatedNav == other.mIsolatedNav
+ && mDimOnTask == other.mDimOnTask;
}
@Override
@@ -363,6 +383,8 @@ public final class TaskFragmentOperation implements Parcelable {
private boolean mIsolatedNav;
+ private boolean mDimOnTask;
+
/**
* @param opType the {@link OperationType} of this {@link TaskFragmentOperation}.
*/
@@ -435,13 +457,22 @@ public final class TaskFragmentOperation implements Parcelable {
}
/**
+ * Sets the dimming to apply on the parent Task if any.
+ */
+ @NonNull
+ public Builder setDimOnTask(boolean dimOnTask) {
+ mDimOnTask = dimOnTask;
+ return this;
+ }
+
+ /**
* Constructs the {@link TaskFragmentOperation}.
*/
@NonNull
public TaskFragmentOperation build() {
return new TaskFragmentOperation(mOpType, mTaskFragmentCreationParams, mActivityToken,
mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams,
- mIsolatedNav);
+ mIsolatedNav, mDimOnTask);
}
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index ca3d8d18db83..592f9a57884c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -19,6 +19,7 @@ package androidx.window.extensions.embedding;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_DIM_ON_TASK;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ISOLATED_NAVIGATION;
import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior;
@@ -356,6 +357,13 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
wct.addTaskFragmentOperation(fragmentToken, operation);
}
+ void setTaskFragmentDimOnTask(@NonNull WindowContainerTransaction wct,
+ @NonNull IBinder fragmentToken, boolean dimOnTask) {
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_SET_DIM_ON_TASK).setDimOnTask(dimOnTask).build();
+ wct.addTaskFragmentOperation(fragmentToken, operation);
+ }
+
void updateTaskFragmentInfo(@NonNull TaskFragmentInfo taskFragmentInfo) {
mFragmentInfos.put(taskFragmentInfo.getFragmentToken(), taskFragmentInfo);
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 543570c63ad7..6f356fa35d41 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -20,6 +20,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.pm.PackageManager.MATCH_ALL;
+import static androidx.window.extensions.embedding.WindowAttributes.DIM_AREA_ON_TASK;
+
import android.app.Activity;
import android.app.ActivityThread;
import android.app.WindowConfiguration;
@@ -56,6 +58,7 @@ import androidx.window.extensions.layout.WindowLayoutComponentImpl;
import androidx.window.extensions.layout.WindowLayoutInfo;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
import java.util.ArrayList;
import java.util.List;
@@ -384,6 +387,13 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
setCompanionTaskFragment(wct, primaryContainer.getTaskFragmentToken(),
secondaryContainer.getTaskFragmentToken(), splitRule, isStacked);
+ // Sets the dim area when the two TaskFragments are adjacent.
+ final boolean dimOnTask = !isStacked
+ && splitAttributes.getWindowAttributes().getDimArea() == DIM_AREA_ON_TASK
+ && Flags.fullscreenDimFlag();
+ setTaskFragmentDimOnTask(wct, primaryContainer.getTaskFragmentToken(), dimOnTask);
+ setTaskFragmentDimOnTask(wct, secondaryContainer.getTaskFragmentToken(), dimOnTask);
+
// Setting isolated navigation and clear non-sticky pinned container if needed.
final SplitPinRule splitPinRule =
splitRule instanceof SplitPinRule ? (SplitPinRule) splitRule : null;
@@ -578,6 +588,23 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
bounds.isEmpty() ? WINDOWING_MODE_FULLSCREEN : WINDOWING_MODE_MULTI_WINDOW);
}
+ @Override
+ void setTaskFragmentDimOnTask(@NonNull WindowContainerTransaction wct,
+ @NonNull IBinder fragmentToken, boolean dimOnTask) {
+ final TaskFragmentContainer container = mController.getContainer(fragmentToken);
+ if (container == null) {
+ throw new IllegalStateException("setTaskFragmentDimOnTask on TaskFragment that is"
+ + " not registered with controller.");
+ }
+
+ if (container.isLastDimOnTask() == dimOnTask) {
+ return;
+ }
+
+ container.setLastDimOnTask(dimOnTask);
+ super.setTaskFragmentDimOnTask(wct, fragmentToken, dimOnTask);
+ }
+
/**
* Expands the split container if the current split bounds are smaller than the Activity or
* Intent that is added to the container.
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 810bded8a7f0..b52971a15a3c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -172,6 +172,11 @@ class TaskFragmentContainer {
private boolean mIsIsolatedNavigationEnabled;
/**
+ * Whether to apply dimming on the parent Task that was requested last.
+ */
+ private boolean mLastDimOnTask;
+
+ /**
* @see #TaskFragmentContainer(Activity, Intent, TaskContainer, SplitController,
* TaskFragmentContainer, String, Bundle)
*/
@@ -836,6 +841,16 @@ class TaskFragmentContainer {
mIsIsolatedNavigationEnabled = isolatedNavigationEnabled;
}
+ /** Sets whether to apply dim on the parent Task. */
+ void setLastDimOnTask(boolean lastDimOnTask) {
+ mLastDimOnTask = lastDimOnTask;
+ }
+
+ /** Returns whether to apply dim on the parent Task. */
+ boolean isLastDimOnTask() {
+ return mLastDimOnTask;
+ }
+
/**
* Adds the pending appeared activity that has requested to be launched in this task fragment.
* @see android.app.ActivityClient#isRequestedToLaunchInTaskFragment
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
index 6981d9d7ebb8..941b4e1c3e41 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
@@ -235,6 +235,19 @@ public class SplitPresenterTest {
}
@Test
+ public void testSetTaskFragmentDimOnTask() {
+ final TaskFragmentContainer container = mController.newContainer(mActivity, TASK_ID);
+
+ mPresenter.setTaskFragmentDimOnTask(mTransaction, container.getTaskFragmentToken(), true);
+ verify(mTransaction).addTaskFragmentOperation(eq(container.getTaskFragmentToken()), any());
+
+ // No request to set the same adjacent TaskFragments.
+ clearInvocations(mTransaction);
+ mPresenter.setTaskFragmentDimOnTask(mTransaction, container.getTaskFragmentToken(), true);
+ verify(mTransaction, never()).addTaskFragmentOperation(any(), any());
+ }
+
+ @Test
public void testUpdateAnimationParams() {
final TaskFragmentContainer container = mController.newContainer(mActivity, TASK_ID);
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 4ad4b0c388ec..93cce2aa3fd0 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -2984,7 +2984,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
@Override
Dimmer getDimmer() {
// If this is in an embedded TaskFragment and we want the dim applies on the TaskFragment.
- if (mIsEmbedded && mEmbeddedDimArea == EMBEDDED_DIM_AREA_TASK_FRAGMENT) {
+ if (mIsEmbedded && !isDimmingOnParentTask()) {
return mDimmer;
}
@@ -2993,7 +2993,9 @@ class TaskFragment extends WindowContainer<WindowContainer> {
/** Bounds to be used for dimming, as well as touch related tests. */
void getDimBounds(@NonNull Rect out) {
- if (mIsEmbedded && mEmbeddedDimArea == EMBEDDED_DIM_AREA_PARENT_TASK) {
+ if (mIsEmbedded && isDimmingOnParentTask() && getDimmer().getDimBounds() != null) {
+ // Return the task bounds if the dimmer is showing and should cover on the Task (not
+ // just on this embedded TaskFragment).
out.set(getTask().getBounds());
} else {
out.set(getBounds());
@@ -3004,6 +3006,11 @@ class TaskFragment extends WindowContainer<WindowContainer> {
mEmbeddedDimArea = embeddedDimArea;
}
+ @VisibleForTesting
+ boolean isDimmingOnParentTask() {
+ return mEmbeddedDimArea == EMBEDDED_DIM_AREA_PARENT_TASK;
+ }
+
@Override
void prepareSurfaces() {
if (asTask() != null) {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 9e4a31c3773a..59d0210251d1 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -34,6 +34,7 @@ import static android.window.TaskFragmentOperation.OP_TYPE_REQUEST_FOCUS_ON_TASK
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_COMPANION_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_DIM_ON_TASK;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ISOLATED_NAVIGATION;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_RELATIVE_BOUNDS;
import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
@@ -68,6 +69,8 @@ import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermis
import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
+import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_PARENT_TASK;
+import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_TASK_FRAGMENT;
import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
import static com.android.server.wm.TaskFragment.FLAG_FORCE_HIDDEN_FOR_TASK_FRAGMENT_ORG;
import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
@@ -1493,6 +1496,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
task.removeDecorSurface();
break;
}
+ case OP_TYPE_SET_DIM_ON_TASK: {
+ final boolean dimOnTask = operation.isDimOnTask();
+ taskFragment.setEmbeddedDimArea(dimOnTask ? EMBEDDED_DIM_AREA_PARENT_TASK
+ : EMBEDDED_DIM_AREA_TASK_FRAGMENT);
+ break;
+ }
}
return effects;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index d36ee2c62fd2..a88285ac4c8f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -34,6 +34,7 @@ import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_TOP_OF_TAS
import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_DIM_ON_TASK;
import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_OP_TYPE;
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_THROWABLE;
@@ -870,12 +871,19 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
.setAnimationParams(animationParams)
.build();
mTransaction.addTaskFragmentOperation(mFragmentToken, operation);
+ final TaskFragmentOperation dimOperation = new TaskFragmentOperation.Builder(
+ OP_TYPE_SET_DIM_ON_TASK)
+ .setDimOnTask(true)
+ .build();
+ mTransaction.addTaskFragmentOperation(mFragmentToken, dimOperation);
mOrganizer.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE,
false /* shouldApplyIndependently */);
assertApplyTransactionAllowed(mTransaction);
assertEquals(animationParams, mTaskFragment.getAnimationParams());
assertEquals(Color.GREEN, mTaskFragment.getAnimationParams().getAnimationBackgroundColor());
+
+ assertTrue(mTaskFragment.isDimmingOnParentTask());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 875e708ce1da..e9fe4bb91329 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -684,6 +684,9 @@ public class TaskFragmentTest extends WindowTestsBase {
// Return Task bounds if dimming on parent Task.
final Rect dimBounds = new Rect();
mTaskFragment.setEmbeddedDimArea(EMBEDDED_DIM_AREA_PARENT_TASK);
+ final Dimmer dimmer = mTaskFragment.getDimmer();
+ spyOn(dimmer);
+ doReturn(taskBounds).when(dimmer).getDimBounds();
mTaskFragment.getDimBounds(dimBounds);
assertEquals(taskBounds, dimBounds);