diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 43d4530cbf1d0..dbe7e087d1e32 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -3429,14 +3429,20 @@ package android.window { public class TaskFragmentOrganizer extends android.window.WindowOrganizer { ctor public TaskFragmentOrganizer(@NonNull java.util.concurrent.Executor); + method public void applyTransaction(@NonNull android.window.WindowContainerTransaction, int, boolean); method @NonNull public java.util.concurrent.Executor getExecutor(); method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizerToken(); + method public void onTransactionHandled(@NonNull android.os.IBinder, @NonNull android.window.WindowContainerTransaction, int, boolean); method public void onTransactionReady(@NonNull android.window.TaskFragmentTransaction); method @CallSuper public void registerOrganizer(); method @CallSuper public void unregisterOrganizer(); field public static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type"; field public static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info"; field public static final String KEY_ERROR_CALLBACK_THROWABLE = "fragment_throwable"; + field public static final int TASK_FRAGMENT_TRANSIT_CHANGE = 6; // 0x6 + field public static final int TASK_FRAGMENT_TRANSIT_CLOSE = 2; // 0x2 + field public static final int TASK_FRAGMENT_TRANSIT_NONE = 0; // 0x0 + field public static final int TASK_FRAGMENT_TRANSIT_OPEN = 1; // 0x1 } public final class TaskFragmentOrganizerToken implements android.os.Parcelable { @@ -3558,8 +3564,8 @@ package android.window { public class WindowOrganizer { ctor public WindowOrganizer(); - method @RequiresPermission(value=android.Manifest.permission.MANAGE_ACTIVITY_TASKS, conditional=true) public int applySyncTransaction(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.WindowContainerTransactionCallback); - method @RequiresPermission(value=android.Manifest.permission.MANAGE_ACTIVITY_TASKS, conditional=true) public void applyTransaction(@NonNull android.window.WindowContainerTransaction); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public int applySyncTransaction(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.WindowContainerTransactionCallback); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void applyTransaction(@NonNull android.window.WindowContainerTransaction); } @UiContext public abstract class WindowProviderService extends android.app.Service { diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java index ef19c55019dc1..283df7608806d 100644 --- a/core/java/android/window/TaskFragmentOrganizer.java +++ b/core/java/android/window/TaskFragmentOrganizer.java @@ -20,22 +20,20 @@ import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_OPEN; -import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT; -import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT; -import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT; import android.annotation.CallSuper; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.app.WindowConfiguration; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.view.RemoteAnimationDefinition; import android.view.WindowManager; -import java.util.List; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; /** @@ -62,6 +60,52 @@ public class TaskFragmentOrganizer extends WindowOrganizer { */ public static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type"; + /** + * No change set. + */ + @WindowManager.TransitionType + @TaskFragmentTransitionType + public static final int TASK_FRAGMENT_TRANSIT_NONE = TRANSIT_NONE; + + /** + * A window that didn't exist before has been created and made visible. + */ + @WindowManager.TransitionType + @TaskFragmentTransitionType + public static final int TASK_FRAGMENT_TRANSIT_OPEN = TRANSIT_OPEN; + + /** + * A window that was visible no-longer exists (was finished or destroyed). + */ + @WindowManager.TransitionType + @TaskFragmentTransitionType + public static final int TASK_FRAGMENT_TRANSIT_CLOSE = TRANSIT_CLOSE; + + /** + * A window is visible before and after but changes in some way (eg. it resizes or changes + * windowing-mode). + */ + @WindowManager.TransitionType + @TaskFragmentTransitionType + public static final int TASK_FRAGMENT_TRANSIT_CHANGE = TRANSIT_CHANGE; + + /** + * Introduced a sub set of {@link WindowManager.TransitionType} for the types that are used for + * TaskFragment transition. + * + * Doing this instead of exposing {@link WindowManager.TransitionType} because we want to keep + * the Shell transition API hidden until it comes fully stable. + * @hide + */ + @IntDef(prefix = { "TASK_FRAGMENT_TRANSIT_" }, value = { + TASK_FRAGMENT_TRANSIT_NONE, + TASK_FRAGMENT_TRANSIT_OPEN, + TASK_FRAGMENT_TRANSIT_CLOSE, + TASK_FRAGMENT_TRANSIT_CHANGE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface TaskFragmentTransitionType {} + /** * Creates a {@link Bundle} with an exception, operation type and TaskFragmentInfo (if any) * that can be passed to {@link ITaskFragmentOrganizer#onTaskFragmentError}. @@ -155,7 +199,7 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * {@link #onTransactionReady(TaskFragmentTransaction)} * @param wct {@link WindowContainerTransaction} that the server should apply for * update of the transaction. - * @param transitionType {@link WindowManager.TransitionType} if it needs to start a + * @param transitionType {@link TaskFragmentTransitionType} if it needs to start a * transition. * @param shouldApplyIndependently If {@code true}, the {@code wct} will request a new * transition, which will be queued until the sync engine is @@ -163,11 +207,10 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * the {@code wct} will be directly applied to the active sync. * @see com.android.server.wm.WindowOrganizerController#enforceTaskFragmentOrganizerPermission * for permission enforcement. - * @hide */ public void onTransactionHandled(@NonNull IBinder transactionToken, @NonNull WindowContainerTransaction wct, - @WindowManager.TransitionType int transitionType, boolean shouldApplyIndependently) { + @TaskFragmentTransitionType int transitionType, boolean shouldApplyIndependently) { wct.setTaskFragmentOrganizer(mInterface); try { getController().onTransactionHandled(transactionToken, wct, transitionType, @@ -178,22 +221,19 @@ public class TaskFragmentOrganizer extends WindowOrganizer { } /** - * Routes to {@link ITaskFragmentOrganizerController#applyTransaction} instead of - * {@link IWindowOrganizerController#applyTransaction} for the different transition options. - * + * Must use {@link #applyTransaction(WindowContainerTransaction, int, boolean)} instead. * @see #applyTransaction(WindowContainerTransaction, int, boolean) */ @Override public void applyTransaction(@NonNull WindowContainerTransaction wct) { - // TODO(b/207070762) doing so to keep CTS compatibility. Remove in the next release. - applyTransaction(wct, getTransitionType(wct), false /* shouldApplyIndependently */); + throw new RuntimeException("Not allowed!"); } /** * Requests the server to apply the given {@link WindowContainerTransaction}. * * @param wct {@link WindowContainerTransaction} to apply. - * @param transitionType {@link WindowManager.TransitionType} if it needs to start a + * @param transitionType {@link TaskFragmentTransitionType} if it needs to start a * transition. * @param shouldApplyIndependently If {@code true}, the {@code wct} will request a new * transition, which will be queued until the sync engine is @@ -201,10 +241,9 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * the {@code wct} will be directly applied to the active sync. * @see com.android.server.wm.WindowOrganizerController#enforceTaskFragmentOrganizerPermission * for permission enforcement. - * @hide */ public void applyTransaction(@NonNull WindowContainerTransaction wct, - @WindowManager.TransitionType int transitionType, boolean shouldApplyIndependently) { + @TaskFragmentTransitionType int transitionType, boolean shouldApplyIndependently) { if (wct.isEmpty()) { return; } @@ -216,49 +255,6 @@ public class TaskFragmentOrganizer extends WindowOrganizer { } } - /** - * Gets the default {@link WindowManager.TransitionType} based on the requested - * {@link WindowContainerTransaction}. - * @hide - */ - // TODO(b/207070762): let Extensions to set the transition type instead. - @WindowManager.TransitionType - public static int getTransitionType(@NonNull WindowContainerTransaction wct) { - if (wct.isEmpty()) { - return TRANSIT_NONE; - } - for (WindowContainerTransaction.Change change : wct.getChanges().values()) { - if ((change.getWindowSetMask() & WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) { - // Treat as TRANSIT_CHANGE when there is TaskFragment resizing. - return TRANSIT_CHANGE; - } - } - boolean containsCreatingTaskFragment = false; - boolean containsDeleteTaskFragment = false; - final List ops = wct.getHierarchyOps(); - for (int i = ops.size() - 1; i >= 0; i--) { - final int type = ops.get(i).getType(); - if (type == HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT) { - // Treat as TRANSIT_CHANGE when there is activity reparent. - return TRANSIT_CHANGE; - } - if (type == HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT) { - containsCreatingTaskFragment = true; - } else if (type == HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT) { - containsDeleteTaskFragment = true; - } - } - if (containsCreatingTaskFragment) { - return TRANSIT_OPEN; - } - if (containsDeleteTaskFragment) { - return TRANSIT_CLOSE; - } - - // Use TRANSIT_CHANGE as default. - return TRANSIT_CHANGE; - } - /** * Called when the transaction is ready so that the organizer can update the TaskFragments based * on the changes in transaction. @@ -266,7 +262,7 @@ public class TaskFragmentOrganizer extends WindowOrganizer { public void onTransactionReady(@NonNull TaskFragmentTransaction transaction) { // Notify the server to finish the transaction. onTransactionHandled(transaction.getTransactionToken(), new WindowContainerTransaction(), - TRANSIT_NONE, false /* shouldApplyIndependently */); + TASK_FRAGMENT_TRANSIT_NONE, false /* shouldApplyIndependently */); } private final ITaskFragmentOrganizer mInterface = new ITaskFragmentOrganizer.Stub() { diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java index 930aaa2b291b6..695d01e923168 100644 --- a/core/java/android/window/WindowOrganizer.java +++ b/core/java/android/window/WindowOrganizer.java @@ -40,14 +40,11 @@ public class WindowOrganizer { * Apply multiple WindowContainer operations at once. * * Note that using this API requires the caller to hold - * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}, unless the caller is using - * {@link TaskFragmentOrganizer}, in which case it is allowed to change TaskFragment that is - * created by itself. + * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}. * * @param t The transaction to apply. */ - @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS, - conditional = true) + @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void applyTransaction(@NonNull WindowContainerTransaction t) { try { if (!t.isEmpty()) { @@ -62,9 +59,7 @@ public class WindowOrganizer { * Apply multiple WindowContainer operations at once. * * Note that using this API requires the caller to hold - * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}, unless the caller is using - * {@link TaskFragmentOrganizer}, in which case it is allowed to change TaskFragment that is - * created by itself. + * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}. * * @param t The transaction to apply. * @param callback This transaction will use the synchronization scheme described in @@ -73,8 +68,7 @@ public class WindowOrganizer { * @return An ID for the sync operation which will later be passed to transactionReady callback. * This lets the caller differentiate overlapping sync operations. */ - @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS, - conditional = true) + @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public int applySyncTransaction(@NonNull WindowContainerTransaction t, @NonNull WindowContainerTransactionCallback callback) { try { diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index 6f9a4ff8188a5..19950ecbdb539 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -20,11 +20,11 @@ import static android.app.ActivityManager.START_SUCCESS; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.TRANSIT_CLOSE; -import static android.view.WindowManager.TRANSIT_OPEN; import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_OP_TYPE; import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO; import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_THROWABLE; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CLOSE; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_OPEN; import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENTED_TO_TASK; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR; @@ -340,7 +340,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen container.setInfo(wct, taskFragmentInfo); if (container.isFinished()) { - mTransactionManager.getCurrentTransactionRecord().setOriginType(TRANSIT_CLOSE); + mTransactionManager.getCurrentTransactionRecord() + .setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE); mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */); } else { // Update with the latest Task configuration. @@ -376,22 +377,27 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Do not finish the dependents if the last activity is reparented to PiP. // Instead, the original split should be cleanup, and the dependent may be // expanded to fullscreen. - mTransactionManager.getCurrentTransactionRecord().setOriginType(TRANSIT_CLOSE); + mTransactionManager.getCurrentTransactionRecord() + .setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE); cleanupForEnterPip(wct, container); mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */); } else if (taskFragmentInfo.isTaskClearedForReuse()) { // Do not finish the dependents if this TaskFragment was cleared due to // launching activity in the Task. - mTransactionManager.getCurrentTransactionRecord().setOriginType(TRANSIT_CLOSE); + mTransactionManager.getCurrentTransactionRecord() + .setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE); mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */); } else if (taskFragmentInfo.isClearedForReorderActivityToFront()) { // Do not finish the dependents if this TaskFragment was cleared to reorder // the launching Activity to front of the Task. + mTransactionManager.getCurrentTransactionRecord() + .setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE); mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */); } else if (!container.isWaitingActivityAppear()) { // Do not finish the container before the expected activity appear until // timeout. - mTransactionManager.getCurrentTransactionRecord().setOriginType(TRANSIT_CLOSE); + mTransactionManager.getCurrentTransactionRecord() + .setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE); mPresenter.cleanupContainer(wct, container, true /* shouldFinishDependent */); } } else if (wasInPip && isInPip) { @@ -585,7 +591,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen container.setInfo(wct, taskFragmentInfo); container.clearPendingAppearedActivities(); if (container.isEmpty()) { - mTransactionManager.getCurrentTransactionRecord().setOriginType(TRANSIT_CLOSE); + mTransactionManager.getCurrentTransactionRecord() + .setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE); mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */); } break; @@ -1000,7 +1007,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @GuardedBy("mLock") void onTaskFragmentAppearEmptyTimeout(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container) { - mTransactionManager.getCurrentTransactionRecord().setOriginType(TRANSIT_CLOSE); + mTransactionManager.getCurrentTransactionRecord() + .setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE); mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */); } @@ -1563,7 +1571,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // (not resumed yet). if (isOnCreated || primaryActivity.isResumed()) { // Only set trigger type if the launch happens in foreground. - mTransactionManager.getCurrentTransactionRecord().setOriginType(TRANSIT_OPEN); + mTransactionManager.getCurrentTransactionRecord() + .setOriginType(TASK_FRAGMENT_TRANSIT_OPEN); return null; } final ActivityOptions options = ActivityOptions.makeBasic(); @@ -1591,7 +1600,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return false; } - mTransactionManager.getCurrentTransactionRecord().setOriginType(TRANSIT_CLOSE); + mTransactionManager.getCurrentTransactionRecord() + .setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE); mPresenter.cleanupContainer(wct, splitContainer.getSecondaryContainer(), false /* shouldFinishDependent */); return true; @@ -1891,7 +1901,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen synchronized (mLock) { final TransactionRecord transactionRecord = mTransactionManager .startNewTransaction(); - transactionRecord.setOriginType(TRANSIT_OPEN); + transactionRecord.setOriginType(TASK_FRAGMENT_TRANSIT_OPEN); SplitController.this.onActivityCreated(transactionRecord.getTransaction(), activity); // The WCT should be applied and merged to the activity launch transition. @@ -1980,7 +1990,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen synchronized (mLock) { final TransactionRecord transactionRecord = mTransactionManager .startNewTransaction(); - transactionRecord.setOriginType(TRANSIT_OPEN); + transactionRecord.setOriginType(TASK_FRAGMENT_TRANSIT_OPEN); final WindowContainerTransaction wct = transactionRecord.getTransaction(); final TaskFragmentContainer launchedInTaskFragment; if (launchingActivity != null) { diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TransactionManager.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TransactionManager.java index 0071fea41aa8a..396956e56bb55 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TransactionManager.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TransactionManager.java @@ -16,12 +16,12 @@ package androidx.window.extensions.embedding; -import static android.view.WindowManager.TRANSIT_CHANGE; -import static android.view.WindowManager.TRANSIT_NONE; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CHANGE; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_NONE; import android.os.IBinder; -import android.view.WindowManager.TransitionType; import android.window.TaskFragmentOrganizer; +import android.window.TaskFragmentOrganizer.TaskFragmentTransitionType; import android.window.WindowContainerTransaction; import androidx.annotation.NonNull; @@ -122,8 +122,8 @@ class TransactionManager { * @see #setOriginType(int) * @see #getTransactionTransitionType() */ - @TransitionType - private int mOriginType = TRANSIT_NONE; + @TaskFragmentTransitionType + private int mOriginType = TASK_FRAGMENT_TRANSIT_NONE; TransactionRecord(@Nullable IBinder taskFragmentTransactionToken) { mTaskFragmentTransactionToken = taskFragmentTransactionToken; @@ -136,12 +136,12 @@ class TransactionManager { } /** - * Sets the {@link TransitionType} that triggers this transaction. If there are multiple - * calls, only the first call will be respected as the "origin" type. + * Sets the {@link TaskFragmentTransitionType} that triggers this transaction. If there are + * multiple calls, only the first call will be respected as the "origin" type. */ - void setOriginType(@TransitionType int type) { + void setOriginType(@TaskFragmentTransitionType int type) { ensureCurrentTransaction(); - if (mOriginType != TRANSIT_NONE) { + if (mOriginType != TASK_FRAGMENT_TRANSIT_NONE) { // Skip if the origin type has already been set. return; } @@ -188,14 +188,16 @@ class TransactionManager { } /** - * Gets the {@link TransitionType} that we will request transition with for the + * Gets the {@link TaskFragmentTransitionType} that we will request transition with for the * current {@link WindowContainerTransaction}. */ @VisibleForTesting - @TransitionType + @TaskFragmentTransitionType int getTransactionTransitionType() { - // Use TRANSIT_CHANGE as default if there is not opening/closing window. - return mOriginType != TRANSIT_NONE ? mOriginType : TRANSIT_CHANGE; + // Use TASK_FRAGMENT_TRANSIT_CHANGE as default if there is not opening/closing window. + return mOriginType != TASK_FRAGMENT_TRANSIT_NONE + ? mOriginType + : TASK_FRAGMENT_TRANSIT_CHANGE; } } } diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TransactionManagerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TransactionManagerTest.java index 62006bd513999..459b6d2c31f98 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TransactionManagerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TransactionManagerTest.java @@ -16,9 +16,9 @@ package androidx.window.extensions.embedding; -import static android.view.WindowManager.TRANSIT_CHANGE; -import static android.view.WindowManager.TRANSIT_CLOSE; -import static android.view.WindowManager.TRANSIT_OPEN; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CHANGE; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CLOSE; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_OPEN; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions; @@ -86,27 +86,29 @@ public class TransactionManagerTest { @Test public void testSetTransactionOriginType() { - // Return TRANSIT_CHANGE if there is no trigger type set. + // Return TASK_FRAGMENT_TRANSIT_CHANGE if there is no trigger type set. TransactionRecord transactionRecord = mTransactionManager.startNewTransaction(); - assertEquals(TRANSIT_CHANGE, transactionRecord.getTransactionTransitionType()); + assertEquals(TASK_FRAGMENT_TRANSIT_CHANGE, + transactionRecord.getTransactionTransitionType()); // Return the first set type. mTransactionManager.getCurrentTransactionRecord().abort(); transactionRecord = mTransactionManager.startNewTransaction(); - transactionRecord.setOriginType(TRANSIT_OPEN); + transactionRecord.setOriginType(TASK_FRAGMENT_TRANSIT_OPEN); - assertEquals(TRANSIT_OPEN, transactionRecord.getTransactionTransitionType()); + assertEquals(TASK_FRAGMENT_TRANSIT_OPEN, transactionRecord.getTransactionTransitionType()); - transactionRecord.setOriginType(TRANSIT_CLOSE); + transactionRecord.setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE); - assertEquals(TRANSIT_OPEN, transactionRecord.getTransactionTransitionType()); + assertEquals(TASK_FRAGMENT_TRANSIT_OPEN, transactionRecord.getTransactionTransitionType()); // Reset when #startNewTransaction(). transactionRecord.abort(); transactionRecord = mTransactionManager.startNewTransaction(); - assertEquals(TRANSIT_CHANGE, transactionRecord.getTransactionTransitionType()); + assertEquals(TASK_FRAGMENT_TRANSIT_CHANGE, + transactionRecord.getTransactionTransitionType()); } @Test 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 834302e82507b..298cecbb61228 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -19,9 +19,16 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.TRANSIT_CHANGE; +import static android.view.WindowManager.TRANSIT_CLOSE; +import static android.view.WindowManager.TRANSIT_NONE; +import static android.view.WindowManager.TRANSIT_OPEN; import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_OP_TYPE; import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_THROWABLE; -import static android.window.TaskFragmentOrganizer.getTransitionType; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CHANGE; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CLOSE; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_NONE; +import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_OPEN; import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENTED_TO_TASK; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR; @@ -581,7 +588,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment); mTransaction.startActivityInTaskFragment( mFragmentToken, ownerActivity.token, new Intent(), null /* activityOptions */); - mOrganizer.applyTransaction(mTransaction); + mOrganizer.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_OPEN, + false /* shouldApplyIndependently */); // Not allowed because TaskFragment is not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); @@ -602,7 +610,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { .build(); mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment); mTransaction.reparentActivityToTaskFragment(mFragmentToken, activity.token); - mOrganizer.applyTransaction(mTransaction); + mOrganizer.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE, + false /* shouldApplyIndependently */); // Not allowed because TaskFragment is not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); @@ -628,7 +637,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { .build(); mWindowOrganizerController.mLaunchTaskFragments.put(fragmentToken2, taskFragment2); mTransaction.setAdjacentTaskFragments(mFragmentToken, fragmentToken2, null /* params */); - mOrganizer.applyTransaction(mTransaction); + mOrganizer.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE, + false /* shouldApplyIndependently */); // Not allowed because TaskFragments are not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); @@ -661,7 +671,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { .build(); mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment); mTransaction.requestFocusOnTaskFragment(mFragmentToken); - mOrganizer.applyTransaction(mTransaction); + mOrganizer.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE, + false /* shouldApplyIndependently */); // Not allowed because TaskFragment is not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); @@ -729,7 +740,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { final ActivityRecord activity = createActivityRecord(task); // Skip manipulate the SurfaceControl. doNothing().when(activity).setDropInputMode(anyInt()); - mOrganizer.applyTransaction(mTransaction); + mOrganizer.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE, + false /* shouldApplyIndependently */); mTaskFragment = new TaskFragmentBuilder(mAtm) .setParentTask(task) .setFragmentToken(mFragmentToken) @@ -830,8 +842,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { // Allow organizer to create TaskFragment and start/reparent activity to TaskFragment. createTaskFragmentFromOrganizer(mTransaction, ownerActivity, fragmentToken); - mController.onTransactionHandled(new Binder(), mTransaction, - getTransitionType(mTransaction), false /* shouldApplyIndependently */); + mController.onTransactionHandled(new Binder(), mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE, + false /* shouldApplyIndependently */); // Nothing should happen as the organizer is not registered. assertNull(mWindowOrganizerController.getTaskFragment(fragmentToken)); @@ -1379,12 +1391,31 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { final IBinder transactionToken = tokenCaptor.getValue(); final WindowContainerTransaction wct = wctCaptor.getValue(); wct.setTaskFragmentOrganizer(mIOrganizer); - mController.onTransactionHandled(transactionToken, wct, getTransitionType(wct), + mController.onTransactionHandled(transactionToken, wct, TASK_FRAGMENT_TRANSIT_CHANGE, false /* shouldApplyIndependently */); verify(mTransitionController).continueTransitionReady(); } + @Test + public void testWindowOrganizerApplyTransaction_throwException() { + // Not allow to use #applyTransaction(WindowContainerTransaction). + assertThrows(RuntimeException.class, () -> mOrganizer.applyTransaction(mTransaction)); + + // Allow to use the overload method. + mOrganizer.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE, + false /* shouldApplyIndependently */); + } + + @Test + public void testTaskFragmentTransitionType() { + // 1-1 relationship with WindowManager.TransitionType + assertEquals(TRANSIT_NONE, TASK_FRAGMENT_TRANSIT_NONE); + assertEquals(TRANSIT_OPEN, TASK_FRAGMENT_TRANSIT_OPEN); + assertEquals(TRANSIT_CLOSE, TASK_FRAGMENT_TRANSIT_CLOSE); + assertEquals(TRANSIT_CHANGE, TASK_FRAGMENT_TRANSIT_CHANGE); + } + /** * Creates a {@link TaskFragment} with the {@link WindowContainerTransaction}. Calls * {@link WindowOrganizerController#applyTransaction(WindowContainerTransaction)} to apply the @@ -1406,13 +1437,14 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { /** Asserts that applying the given transaction will throw a {@link SecurityException}. */ private void assertApplyTransactionDisallowed(WindowContainerTransaction t) { assertThrows(SecurityException.class, () -> - mController.applyTransaction(t, getTransitionType(t), + mController.applyTransaction(t, TASK_FRAGMENT_TRANSIT_CHANGE, false /* shouldApplyIndependently */)); } /** Asserts that applying the given transaction will not throw any exception. */ private void assertApplyTransactionAllowed(WindowContainerTransaction t) { - mController.applyTransaction(t, getTransitionType(t), false /* shouldApplyIndependently */); + mController.applyTransaction(t, TASK_FRAGMENT_TRANSIT_CHANGE, + false /* shouldApplyIndependently */); } /** Asserts that there will be a transaction for TaskFragment appeared. */