Merge "Collect embedded TaskFragment window changes" into tm-qpr-dev am: d0208d9292
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19561152 Change-Id: If22315d886a178ffd74f0a60b21548ac9ab24f30 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -3193,12 +3193,6 @@
|
|||||||
"group": "WM_DEBUG_LOCKTASK",
|
"group": "WM_DEBUG_LOCKTASK",
|
||||||
"at": "com\/android\/server\/wm\/LockTaskController.java"
|
"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": {
|
"958338552": {
|
||||||
"message": "grantEmbeddedWindowFocus win=%s dropped focus so setting focus to null since no candidate was found",
|
"message": "grantEmbeddedWindowFocus win=%s dropped focus so setting focus to null since no candidate was found",
|
||||||
"level": "VERBOSE",
|
"level": "VERBOSE",
|
||||||
|
|||||||
@@ -2741,10 +2741,7 @@ class ActivityStarter {
|
|||||||
newParent = candidateTf;
|
newParent = candidateTf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newParent.canHaveEmbeddingActivityTransition(mStartActivity)) {
|
newParent.mTransitionController.collect(newParent);
|
||||||
// Make sure the embedded TaskFragment is included in the start activity transition.
|
|
||||||
newParent.collectEmbeddedTaskFragmentIfNeeded();
|
|
||||||
}
|
|
||||||
if (mStartActivity.getTaskFragment() == null
|
if (mStartActivity.getTaskFragment() == null
|
||||||
|| mStartActivity.getTaskFragment() == newParent) {
|
|| mStartActivity.getTaskFragment() == newParent) {
|
||||||
newParent.addChild(mStartActivity, POSITION_TOP);
|
newParent.addChild(mStartActivity, POSITION_TOP);
|
||||||
|
|||||||
@@ -2275,19 +2275,33 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
|||||||
|
|
||||||
super.onConfigurationChanged(newParentConfig);
|
super.onConfigurationChanged(newParentConfig);
|
||||||
|
|
||||||
if (shouldStartChangeTransition(mTmpPrevBounds)) {
|
final boolean shouldStartChangeTransition = shouldStartChangeTransition(mTmpPrevBounds);
|
||||||
|
if (shouldStartChangeTransition) {
|
||||||
initializeChangeTransition(mTmpPrevBounds);
|
initializeChangeTransition(mTmpPrevBounds);
|
||||||
} else if (mTaskFragmentOrganizer != null) {
|
}
|
||||||
// Update the surface here instead of in the organizer so that we can make sure
|
if (mTaskFragmentOrganizer != null) {
|
||||||
// it can be synced with the surface freezer.
|
if (mTransitionController.isShellTransitionsEnabled()
|
||||||
final SurfaceControl.Transaction t = getSyncTransaction();
|
&& !mTransitionController.isCollecting(this)) {
|
||||||
updateSurfacePosition(t);
|
// TaskFragmentOrganizer doesn't have access to the surface for security reasons, so
|
||||||
updateOrganizedTaskFragmentSurfaceSize(t, false /* forceUpdate */);
|
// 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();
|
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. */
|
/** Updates the surface size so that the sub windows cannot be shown out of bounds. */
|
||||||
private void updateOrganizedTaskFragmentSurfaceSize(SurfaceControl.Transaction t,
|
private void updateOrganizedTaskFragmentSurfaceSize(SurfaceControl.Transaction t,
|
||||||
boolean forceUpdate) {
|
boolean forceUpdate) {
|
||||||
@@ -2342,33 +2356,16 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
|||||||
|| endBounds.height() != startBounds.height();
|
|| endBounds.height() != startBounds.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean canHaveEmbeddingActivityTransition(@NonNull ActivityRecord child) {
|
@Override
|
||||||
if (!isOrganizedTaskFragment() || !mTransitionController.isShellTransitionsEnabled()) {
|
boolean isSyncFinished() {
|
||||||
return false;
|
return super.isSyncFinished() && isReadyToTransit();
|
||||||
}
|
|
||||||
// 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
|
@Override
|
||||||
void setSurfaceControl(SurfaceControl sc) {
|
void setSurfaceControl(SurfaceControl sc) {
|
||||||
super.setSurfaceControl(sc);
|
super.setSurfaceControl(sc);
|
||||||
if (mTaskFragmentOrganizer != null) {
|
if (mTaskFragmentOrganizer != null) {
|
||||||
final SurfaceControl.Transaction t = getSyncTransaction();
|
updateOrganizedTaskFragmentSurface();
|
||||||
updateSurfacePosition(t);
|
|
||||||
updateOrganizedTaskFragmentSurfaceSize(t, false /* forceUpdate */);
|
|
||||||
// If the TaskFragmentOrganizer was set before we created the SurfaceControl, we need to
|
// If the TaskFragmentOrganizer was set before we created the SurfaceControl, we need to
|
||||||
// emit the callbacks now.
|
// emit the callbacks now.
|
||||||
sendTaskFragmentAppeared();
|
sendTaskFragmentAppeared();
|
||||||
|
|||||||
@@ -226,6 +226,14 @@ class TransitionController {
|
|||||||
return mCollectingTransition != null;
|
return mCollectingTransition != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
* @return the collecting transition sync Id. This should only be called when there is a
|
||||||
* collecting transition.
|
* collecting transition.
|
||||||
|
|||||||
@@ -2827,7 +2827,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
void initializeChangeTransition(Rect startBounds, @Nullable SurfaceControl freezeTarget) {
|
void initializeChangeTransition(Rect startBounds, @Nullable SurfaceControl freezeTarget) {
|
||||||
if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
|
if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
|
||||||
mDisplayContent.mTransitionController.collectVisibleChange(this);
|
mDisplayContent.mTransitionController.collectVisibleChange(this);
|
||||||
// TODO(b/207070762): request shell transition for activityEmbedding change.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mDisplayContent.prepareAppTransition(TRANSIT_CHANGE);
|
mDisplayContent.prepareAppTransition(TRANSIT_CHANGE);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import static android.app.ActivityManager.isStartResultSuccessful;
|
|||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||||
import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
|
import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
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_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_CHILDREN_TASKS_REPARENT;
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
|
||||||
@@ -416,7 +415,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
|
|
||||||
if (!shouldApplyIndependently) {
|
if (!shouldApplyIndependently) {
|
||||||
// Although there is an active sync, we want to apply the transaction now.
|
// 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
|
// This should rarely happen, and we should try to avoid using
|
||||||
// {@link #applySyncTransaction} with Shell transition.
|
// {@link #applySyncTransaction} with Shell transition.
|
||||||
// We still want to apply and merge the transaction to the active sync
|
// 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"
|
+ " because there is an ongoing sync for"
|
||||||
+ " applySyncTransaction().");
|
+ " applySyncTransaction().");
|
||||||
}
|
}
|
||||||
// TODO(b/207070762) make sure changes are all collected.
|
applyTransaction(wct, -1 /* syncId */, transition, caller);
|
||||||
applyTransaction(wct, -1 /* syncId */, null /* transition */, caller);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -821,7 +822,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT: {
|
case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT: {
|
||||||
final TaskFragmentCreationParams taskFragmentCreationOptions =
|
final TaskFragmentCreationParams taskFragmentCreationOptions =
|
||||||
hop.getTaskFragmentCreationOptions();
|
hop.getTaskFragmentCreationOptions();
|
||||||
createTaskFragment(taskFragmentCreationOptions, errorCallbackToken, caller);
|
createTaskFragment(taskFragmentCreationOptions, errorCallbackToken, caller,
|
||||||
|
transition);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT: {
|
case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT: {
|
||||||
@@ -848,7 +850,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects |= deleteTaskFragment(taskFragment, organizer, errorCallbackToken);
|
effects |= deleteTaskFragment(taskFragment, organizer, errorCallbackToken,
|
||||||
|
transition);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT: {
|
case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT: {
|
||||||
@@ -922,8 +925,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareActivityEmbeddingTransitionForReparentActivityToTaskFragment(parent,
|
if (transition != null) {
|
||||||
activity);
|
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);
|
activity.reparent(parent, POSITION_TOP);
|
||||||
effects |= TRANSACT_EFFECTS_LIFECYCLE;
|
effects |= TRANSACT_EFFECTS_LIFECYCLE;
|
||||||
break;
|
break;
|
||||||
@@ -1118,7 +1128,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
reparentTaskFragment(oldParent.asTaskFragment(), newParent, organizer,
|
reparentTaskFragment(oldParent.asTaskFragment(), newParent, organizer,
|
||||||
errorCallbackToken);
|
errorCallbackToken, transition);
|
||||||
effects |= TRANSACT_EFFECTS_LIFECYCLE;
|
effects |= TRANSACT_EFFECTS_LIFECYCLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1162,41 +1172,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
return effects;
|
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. */
|
/** A helper method to send minimum dimension violation error to the client. */
|
||||||
private void sendMinimumDimensionViolation(TaskFragment taskFragment, Point minDimensions,
|
private void sendMinimumDimensionViolation(TaskFragment taskFragment, Point minDimensions,
|
||||||
IBinder errorCallbackToken, String reason) {
|
IBinder errorCallbackToken, String reason) {
|
||||||
@@ -1773,8 +1748,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void createTaskFragment(@NonNull TaskFragmentCreationParams creationParams,
|
private void createTaskFragment(@NonNull TaskFragmentCreationParams creationParams,
|
||||||
@Nullable IBinder errorCallbackToken, @NonNull CallerInfo caller) {
|
@Nullable IBinder errorCallbackToken, @NonNull CallerInfo caller,
|
||||||
|
@Nullable Transition transition) {
|
||||||
final ActivityRecord ownerActivity =
|
final ActivityRecord ownerActivity =
|
||||||
ActivityRecord.forTokenLocked(creationParams.getOwnerToken());
|
ActivityRecord.forTokenLocked(creationParams.getOwnerToken());
|
||||||
final ITaskFragmentOrganizer organizer = ITaskFragmentOrganizer.Stub.asInterface(
|
final ITaskFragmentOrganizer organizer = ITaskFragmentOrganizer.Stub.asInterface(
|
||||||
@@ -1829,11 +1805,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
taskFragment.setWindowingMode(creationParams.getWindowingMode());
|
taskFragment.setWindowingMode(creationParams.getWindowingMode());
|
||||||
taskFragment.setBounds(creationParams.getInitialBounds());
|
taskFragment.setBounds(creationParams.getInitialBounds());
|
||||||
mLaunchTaskFragments.put(creationParams.getFragmentToken(), taskFragment);
|
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 WindowContainer<?> newParent, @Nullable ITaskFragmentOrganizer organizer,
|
||||||
@Nullable IBinder errorCallbackToken) {
|
@Nullable IBinder errorCallbackToken, @Nullable Transition transition) {
|
||||||
final TaskFragment newParentTF;
|
final TaskFragment newParentTF;
|
||||||
if (newParent == null) {
|
if (newParent == null) {
|
||||||
// Use the old parent's parent if the caller doesn't specify the new parent.
|
// 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);
|
HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
|
||||||
return;
|
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()) {
|
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,
|
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);
|
final int index = mLaunchTaskFragments.indexOfValue(taskFragment);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
final Throwable exception =
|
final Throwable exception =
|
||||||
@@ -1901,6 +1890,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
|
HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (transition != null) transition.collectExistenceChange(taskFragment);
|
||||||
|
|
||||||
mLaunchTaskFragments.removeAt(index);
|
mLaunchTaskFragments.removeAt(index);
|
||||||
taskFragment.remove(true /* withTransition */, "deleteTaskFragment");
|
taskFragment.remove(true /* withTransition */, "deleteTaskFragment");
|
||||||
return TRANSACT_EFFECTS_LIFECYCLE;
|
return TRANSACT_EFFECTS_LIFECYCLE;
|
||||||
|
|||||||
Reference in New Issue
Block a user