diff options
| author | 2024-01-03 08:54:42 +0000 | |
|---|---|---|
| committer | 2024-01-03 08:54:42 +0000 | |
| commit | 9c6b32c642bde3a6f7e80fdbbe1b2a77ad93220f (patch) | |
| tree | 56eb290db7b40c9de2a91c68a9eb23885d681c79 | |
| parent | 970067a4be937cd89c4664d1faf5c1d7c611b935 (diff) | |
| parent | e1776eb38ebf314213602e3ee8bd2fc28113c51b (diff) | |
Merge "Adding a new TaskFragmentOperation to set dim area on Task" into main
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); |