Merge "Collect embedded TaskFragment window changes" into tm-qpr-dev am: d0208d9292 am: 929e5378a0
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19561152
Change-Id: I16357ce19bbb742dd0fc98b9fc7aef6416e210ac
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index dfff75b..682483d9 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -3217,12 +3217,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 a2f8c14..8af6236 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2712,10 +2712,7 @@
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 f09ad99..1f6690ac 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -2275,19 +2275,33 @@
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) {
@@ -2342,33 +2356,16 @@
|| 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 8269d96..221e186 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 @@
}
/**
+ * @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 d820ec4..a378752 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -2831,7 +2831,6 @@
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 d34ad7d..9456f0f 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.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 @@
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 @@
+ " 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 @@
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 @@
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 @@
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 @@
break;
}
reparentTaskFragment(oldParent.asTaskFragment(), newParent, organizer,
- errorCallbackToken);
+ errorCallbackToken, transition);
effects |= TRANSACT_EFFECTS_LIFECYCLE;
break;
}
@@ -1162,41 +1172,6 @@
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 @@
}
}
- 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 @@
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 @@
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 @@
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;