Cleanup TaskFragmentOrganizer#applyTransaction
Replace the existing usage with the overload method, which is introduced to sync TaskFragmentOrganizer with other transition. Introduced TaskFragmentTransitionType to avoid exposing Shell transition API to CTS. Bug: 232476698 Test: pass existing Change-Id: I666b9ee6b6076766513b97e675fdbaa002428601
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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<WindowContainerTransaction.HierarchyOp> 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() {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user