diff options
| author | Chris Li <lihongyu@google.com> | 2022-08-22 12:04:37 +0800 |
|---|---|---|
| committer | Chris Li <lihongyu@google.com> | 2022-09-01 12:00:31 +0800 |
| commit | dc7cb3659d21093f3fc6a0b7b242bf1f743d3c67 (patch) | |
| tree | 960e1bcb938fa8d0740e8b9acbbea992303e6bb6 /core/java/android/window/TaskFragmentOrganizer.java | |
| parent | 907c1ad88d65af7550a255c6ba9ebc8321acb5a5 (diff) | |
Add TaskFragmentOrganizer#applyTransaction with request transition
Instead of having WM Core to "guess" when to request transtiion, let the
organizer to tell whether or not it needs to be applied immediately.
With the shouldApplyIndependently parameter, we can make sure the future
runtime API to change split layout won't affect other ongoing
transition.
Bug: 207070762
Test: atest WmTests:TaskFragmentOrganizerControllerTest
Change-Id: I658b0ba1ae9decc741f09cb53bfff2c45ea076a0
Diffstat (limited to 'core/java/android/window/TaskFragmentOrganizer.java')
| -rw-r--r-- | core/java/android/window/TaskFragmentOrganizer.java | 125 |
1 files changed, 105 insertions, 20 deletions
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() { |
