diff options
6 files changed, 76 insertions, 89 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index f6499f87dd41..ce6df2068525 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -3193,12 +3193,6 @@ "group": "WM_DEBUG_LOCKTASK", "at": "com\/android\/server\/wm\/LockTaskController.java" }, - "956467125": { - "message": "Reparenting Activity to embedded TaskFragment, but the Activity is not collected", - "level": "WARN", - "group": "WM_DEBUG_WINDOW_TRANSITIONS", - "at": "com\/android\/server\/wm\/WindowOrganizerController.java" - }, "958338552": { "message": "grantEmbeddedWindowFocus win=%s dropped focus so setting focus to null since no candidate was found", "level": "VERBOSE", diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index fc3320e76c2a..891bf717e9c1 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -3018,10 +3018,7 @@ class ActivityStarter { newParent = candidateTf; } } - if (newParent.canHaveEmbeddingActivityTransition(mStartActivity)) { - // Make sure the embedded TaskFragment is included in the start activity transition. - newParent.collectEmbeddedTaskFragmentIfNeeded(); - } + newParent.mTransitionController.collect(newParent); if (mStartActivity.getTaskFragment() == null || mStartActivity.getTaskFragment() == newParent) { newParent.addChild(mStartActivity, POSITION_TOP); diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index da731e842aea..32fa4205f301 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -2280,19 +2280,33 @@ class TaskFragment extends WindowContainer<WindowContainer> { super.onConfigurationChanged(newParentConfig); - if (shouldStartChangeTransition(mTmpPrevBounds)) { + final boolean shouldStartChangeTransition = shouldStartChangeTransition(mTmpPrevBounds); + if (shouldStartChangeTransition) { initializeChangeTransition(mTmpPrevBounds); - } else if (mTaskFragmentOrganizer != null) { - // Update the surface here instead of in the organizer so that we can make sure - // it can be synced with the surface freezer. - final SurfaceControl.Transaction t = getSyncTransaction(); - updateSurfacePosition(t); - updateOrganizedTaskFragmentSurfaceSize(t, false /* forceUpdate */); + } + if (mTaskFragmentOrganizer != null) { + if (mTransitionController.isShellTransitionsEnabled() + && !mTransitionController.isCollecting(this)) { + // TaskFragmentOrganizer doesn't have access to the surface for security reasons, so + // update the surface here if it is not collected by Shell transition. + updateOrganizedTaskFragmentSurface(); + } else if (!mTransitionController.isShellTransitionsEnabled() + && !shouldStartChangeTransition) { + // Update the surface here instead of in the organizer so that we can make sure + // it can be synced with the surface freezer for legacy app transition. + updateOrganizedTaskFragmentSurface(); + } } sendTaskFragmentInfoChanged(); } + private void updateOrganizedTaskFragmentSurface() { + final SurfaceControl.Transaction t = getSyncTransaction(); + updateSurfacePosition(t); + updateOrganizedTaskFragmentSurfaceSize(t, false /* forceUpdate */); + } + /** Updates the surface size so that the sub windows cannot be shown out of bounds. */ private void updateOrganizedTaskFragmentSurfaceSize(SurfaceControl.Transaction t, boolean forceUpdate) { @@ -2347,33 +2361,16 @@ class TaskFragment extends WindowContainer<WindowContainer> { || endBounds.height() != startBounds.height(); } - boolean canHaveEmbeddingActivityTransition(@NonNull ActivityRecord child) { - if (!isOrganizedTaskFragment() || !mTransitionController.isShellTransitionsEnabled()) { - return false; - } - // The activity should request open transition when it is becoming visible. - return child.isVisibleRequested(); - } - - void collectEmbeddedTaskFragmentIfNeeded() { - if (!isOrganizedTaskFragment() || mTransitionController.isCollecting(this)) { - return; - } - if (getChildCount() == 0) { - // The TaskFragment is new created, and just becoming non-empty. - mTransitionController.collectExistenceChange(this); - } else { - mTransitionController.collect(this); - } + @Override + boolean isSyncFinished() { + return super.isSyncFinished() && isReadyToTransit(); } @Override void setSurfaceControl(SurfaceControl sc) { super.setSurfaceControl(sc); if (mTaskFragmentOrganizer != null) { - final SurfaceControl.Transaction t = getSyncTransaction(); - updateSurfacePosition(t); - updateOrganizedTaskFragmentSurfaceSize(t, false /* forceUpdate */); + updateOrganizedTaskFragmentSurface(); // If the TaskFragmentOrganizer was set before we created the SurfaceControl, we need to // emit the callbacks now. sendTaskFragmentAppeared(); diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 23928aed6f65..0d6532fe0848 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -227,6 +227,14 @@ class TransitionController { } /** + * @return the collecting transition. {@code null} if there is no collecting transition. + */ + @Nullable + Transition getCollectingTransition() { + return mCollectingTransition; + } + + /** * @return the collecting transition sync Id. This should only be called when there is a * collecting transition. */ diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 92e52de2c01f..c090d63545e2 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2827,7 +2827,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< void initializeChangeTransition(Rect startBounds, @Nullable SurfaceControl freezeTarget) { if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) { mDisplayContent.mTransitionController.collectVisibleChange(this); - // TODO(b/207070762): request shell transition for activityEmbedding change. return; } mDisplayContent.prepareAppTransition(TRANSIT_CHANGE); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index d34ad7d79695..9456f0fcced7 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -21,7 +21,6 @@ import static android.app.ActivityManager.isStartResultSuccessful; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.TRANSIT_CHANGE; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT; @@ -416,7 +415,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub if (!shouldApplyIndependently) { // Although there is an active sync, we want to apply the transaction now. - if (!mTransitionController.isCollecting()) { + // TODO(b/232042367) Redesign the organizer update on activity callback so that we + // we will know about the transition explicitly. + final Transition transition = mTransitionController.getCollectingTransition(); + if (transition == null) { // This should rarely happen, and we should try to avoid using // {@link #applySyncTransaction} with Shell transition. // We still want to apply and merge the transaction to the active sync @@ -426,8 +428,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub + " because there is an ongoing sync for" + " applySyncTransaction()."); } - // TODO(b/207070762) make sure changes are all collected. - applyTransaction(wct, -1 /* syncId */, null /* transition */, caller); + applyTransaction(wct, -1 /* syncId */, transition, caller); return; } @@ -821,7 +822,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT: { final TaskFragmentCreationParams taskFragmentCreationOptions = hop.getTaskFragmentCreationOptions(); - createTaskFragment(taskFragmentCreationOptions, errorCallbackToken, caller); + createTaskFragment(taskFragmentCreationOptions, errorCallbackToken, caller, + transition); break; } case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT: { @@ -848,7 +850,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub break; } } - effects |= deleteTaskFragment(taskFragment, organizer, errorCallbackToken); + effects |= deleteTaskFragment(taskFragment, organizer, errorCallbackToken, + transition); break; } case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT: { @@ -922,8 +925,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub break; } - prepareActivityEmbeddingTransitionForReparentActivityToTaskFragment(parent, - activity); + if (transition != null) { + transition.collect(activity); + if (activity.getParent() != null) { + // Collect the current parent. Its visibility may change as a result of + // this reparenting. + transition.collect(activity.getParent()); + } + transition.collect(parent); + } activity.reparent(parent, POSITION_TOP); effects |= TRANSACT_EFFECTS_LIFECYCLE; break; @@ -1118,7 +1128,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub break; } reparentTaskFragment(oldParent.asTaskFragment(), newParent, organizer, - errorCallbackToken); + errorCallbackToken, transition); effects |= TRANSACT_EFFECTS_LIFECYCLE; break; } @@ -1162,41 +1172,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub return effects; } - private void prepareActivityEmbeddingTransitionForReparentActivityToTaskFragment( - @NonNull TaskFragment taskFragment, @NonNull ActivityRecord activity) { - if (!taskFragment.canHaveEmbeddingActivityTransition(activity)) { - return; - } - - // The reparent can happen in the following cases: - // 1. Reparent an existing activity to split when app launches new intent. - // - This happens after app calls to start activity, but before the activity is actually - // started, so we don't expect any collecting transition, but if it does, we can't - // queue the WCT because the start activity won't wait. - // 2. Reparent an existing activity to split to launch placeholder when Task size changed. - // - We expect to have a collecting transition for the Task resize, so just collect. - // 3. Reparent a new launching activity to an always-expand container. - // 4. Reparent a new launching activity to split to launch placeholder together. - // 5. Reparent a new launching activity to an existing split. - // - The new launching activity should have start an OPEN transition, so just collect. - // 6. Reparent PiP activity back to the original Task. - // - This should be part of the exiting PiP transition, so just collect. - - if (!taskFragment.getBounds().equals(activity.getBounds()) && activity.isVisible() - && !mTransitionController.isCollecting()) { - // 1. Reparent an existing activity to split when app launches new intent. - mTransitionController.requestTransitionIfNeeded(TRANSIT_CHANGE, activity); - } - - // We expect the activity to be in the transition already, so just collect the TaskFragment. - if (mTransitionController.isCollecting(activity)) { - taskFragment.collectEmbeddedTaskFragmentIfNeeded(); - } else { - ProtoLog.w(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Reparenting Activity" - + " to embedded TaskFragment, but the Activity is not collected"); - } - } - /** A helper method to send minimum dimension violation error to the client. */ private void sendMinimumDimensionViolation(TaskFragment taskFragment, Point minDimensions, IBinder errorCallbackToken, String reason) { @@ -1773,8 +1748,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } } - void createTaskFragment(@NonNull TaskFragmentCreationParams creationParams, - @Nullable IBinder errorCallbackToken, @NonNull CallerInfo caller) { + private void createTaskFragment(@NonNull TaskFragmentCreationParams creationParams, + @Nullable IBinder errorCallbackToken, @NonNull CallerInfo caller, + @Nullable Transition transition) { final ActivityRecord ownerActivity = ActivityRecord.forTokenLocked(creationParams.getOwnerToken()); final ITaskFragmentOrganizer organizer = ITaskFragmentOrganizer.Stub.asInterface( @@ -1829,11 +1805,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub taskFragment.setWindowingMode(creationParams.getWindowingMode()); taskFragment.setBounds(creationParams.getInitialBounds()); mLaunchTaskFragments.put(creationParams.getFragmentToken(), taskFragment); + + if (transition != null) transition.collectExistenceChange(taskFragment); } - void reparentTaskFragment(@NonNull TaskFragment oldParent, + private void reparentTaskFragment(@NonNull TaskFragment oldParent, @Nullable WindowContainer<?> newParent, @Nullable ITaskFragmentOrganizer organizer, - @Nullable IBinder errorCallbackToken) { + @Nullable IBinder errorCallbackToken, @Nullable Transition transition) { final TaskFragment newParentTF; if (newParent == null) { // Use the old parent's parent if the caller doesn't specify the new parent. @@ -1875,13 +1853,24 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception); return; } + if (transition != null) { + // Collect the current parent. It's visibility may change as a result of this + // reparenting. + transition.collect(oldParent); + transition.collect(newParentTF); + } while (oldParent.hasChild()) { - oldParent.getChildAt(0).reparent(newParentTF, POSITION_TOP); + final WindowContainer child = oldParent.getChildAt(0); + if (transition != null) { + transition.collect(child); + } + child.reparent(newParentTF, POSITION_TOP); } } private int deleteTaskFragment(@NonNull TaskFragment taskFragment, - @Nullable ITaskFragmentOrganizer organizer, @Nullable IBinder errorCallbackToken) { + @Nullable ITaskFragmentOrganizer organizer, @Nullable IBinder errorCallbackToken, + @Nullable Transition transition) { final int index = mLaunchTaskFragments.indexOfValue(taskFragment); if (index < 0) { final Throwable exception = @@ -1901,6 +1890,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception); return 0; } + + if (transition != null) transition.collectExistenceChange(taskFragment); + mLaunchTaskFragments.removeAt(index); taskFragment.remove(true /* withTransition */, "deleteTaskFragment"); return TRANSACT_EFFECTS_LIFECYCLE; |