diff options
| author | Chris Li <lihongyu@google.com> | 2022-09-01 06:59:10 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2022-09-01 06:59:10 +0000 |
| commit | 2c9b75902eeb545d3328f4ba579c3de505f99346 (patch) | |
| tree | 3f2b5340fa1ee145f2d308747d4f72d503dcabb0 /core/java | |
| parent | ff778d202306b04710230077d41e04b67e4019af (diff) | |
| parent | dc7cb3659d21093f3fc6a0b7b242bf1f743d3c67 (diff) | |
Merge "Add TaskFragmentOrganizer#applyTransaction with request transition" into tm-qpr-dev
Diffstat (limited to 'core/java')
3 files changed, 115 insertions, 26 deletions
diff --git a/core/java/android/window/ITaskFragmentOrganizerController.aidl b/core/java/android/window/ITaskFragmentOrganizerController.aidl index 884ca77ea377..3250dd8f7308 100644 --- a/core/java/android/window/ITaskFragmentOrganizerController.aidl +++ b/core/java/android/window/ITaskFragmentOrganizerController.aidl @@ -57,6 +57,12 @@ interface ITaskFragmentOrganizerController { * Notifies the server that the organizer has finished handling the given transaction. The * server should apply the given {@link WindowContainerTransaction} for the necessary changes. */ - void onTransactionHandled(in ITaskFragmentOrganizer organizer, in IBinder transactionToken, - in WindowContainerTransaction wct); + void onTransactionHandled(in IBinder transactionToken, in WindowContainerTransaction wct, + int transitionType, boolean shouldApplyIndependently); + + /** + * Requests the server to apply the given {@link WindowContainerTransaction}. + */ + void applyTransaction(in WindowContainerTransaction wct, int transitionType, + boolean shouldApplyIndependently); } diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java index 19b1374ae767..649785a80f43 100644 --- a/core/java/android/window/TaskFragmentOrganizer.java +++ b/core/java/android/window/TaskFragmentOrganizer.java @@ -16,17 +16,25 @@ package android.window; +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.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENTED_TO_TASK; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED; +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.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; +import android.app.WindowConfiguration; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; @@ -34,6 +42,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.SparseArray; import android.view.RemoteAnimationDefinition; +import android.view.WindowManager; import java.util.ArrayList; import java.util.List; @@ -168,21 +177,111 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * {@link #onTransactionReady(TaskFragmentTransaction)} * @param wct {@link WindowContainerTransaction} that the server should apply for * update of the transaction. - * @see com.android.server.wm.WindowOrganizerController#enforceTaskPermission for permission - * requirement. + * @param transitionType {@link WindowManager.TransitionType} 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 + * free if there is any other active sync. If {@code false}, + * 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) { + @NonNull WindowContainerTransaction wct, + @WindowManager.TransitionType int transitionType, boolean shouldApplyIndependently) { wct.setTaskFragmentOrganizer(mInterface); try { - getController().onTransactionHandled(mInterface, transactionToken, wct); + getController().onTransactionHandled(transactionToken, wct, transitionType, + shouldApplyIndependently); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** + * Routes to {@link ITaskFragmentOrganizerController#applyTransaction} instead of + * {@link IWindowOrganizerController#applyTransaction} for the different transition options. + * + * @see #applyTransaction(WindowContainerTransaction, int, boolean, 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 */); + } + + /** + * 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 + * transition. + * @param shouldApplyIndependently If {@code true}, the {@code wct} will request a new + * transition, which will be queued until the sync engine is + * free if there is any other active sync. If {@code false}, + * 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) { + if (wct.isEmpty()) { + return; + } + wct.setTaskFragmentOrganizer(mInterface); + try { + getController().applyTransaction(wct, transitionType, shouldApplyIndependently); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * 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 a TaskFragment is created and organized by this organizer. * * @param taskFragmentInfo Info of the TaskFragment that is created. @@ -424,22 +523,8 @@ public class TaskFragmentOrganizer extends WindowOrganizer { } // Notify the server, and the server should apply the WindowContainerTransaction. - onTransactionHandled(transaction.getTransactionToken(), wct); - } - - @Override - public void applyTransaction(@NonNull WindowContainerTransaction t) { - t.setTaskFragmentOrganizer(mInterface); - super.applyTransaction(t); - } - - // Suppress the lint because it is not a registration method. - @SuppressWarnings("ExecutorRegistration") - @Override - public int applySyncTransaction(@NonNull WindowContainerTransaction t, - @NonNull WindowContainerTransactionCallback callback) { - t.setTaskFragmentOrganizer(mInterface); - return super.applySyncTransaction(t, callback); + onTransactionHandled(transaction.getTransactionToken(), wct, getTransitionType(wct), + false /* shouldApplyIndependently */); } private final ITaskFragmentOrganizer mInterface = new ITaskFragmentOrganizer.Stub() { diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index 9ebdea82593b..ffbdf08e99dc 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -763,10 +763,8 @@ public final class WindowContainerTransaction implements Parcelable { * @hide */ @NonNull - WindowContainerTransaction setTaskFragmentOrganizer(@NonNull ITaskFragmentOrganizer organizer) { - if (mTaskFragmentOrganizer != null) { - throw new IllegalStateException("Can't set multiple organizers for one transaction."); - } + public WindowContainerTransaction setTaskFragmentOrganizer( + @NonNull ITaskFragmentOrganizer organizer) { mTaskFragmentOrganizer = organizer; return this; } |
