Merge "Fix open ActivityEmbedding split with Shell transition" into tm-qpr-dev am: 447919823c
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19321172 Change-Id: Ia471a71ba97cf89fa8c214734012075a9b1a33c5 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -3139,6 +3139,12 @@
|
||||
"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",
|
||||
|
||||
@@ -483,11 +483,11 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
||||
postStartTransactionCallbacks.add(t ->
|
||||
startSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish,
|
||||
mTransactionPool, mMainExecutor, mAnimExecutor,
|
||||
null /* position */, cornerRadius, clipRect));
|
||||
change.getEndRelOffset(), cornerRadius, clipRect));
|
||||
} else {
|
||||
startSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish,
|
||||
mTransactionPool, mMainExecutor, mAnimExecutor, null /* position */,
|
||||
cornerRadius, clipRect);
|
||||
mTransactionPool, mMainExecutor, mAnimExecutor,
|
||||
change.getEndRelOffset(), cornerRadius, clipRect);
|
||||
}
|
||||
|
||||
if (info.getAnimationOptions() != null) {
|
||||
@@ -934,7 +934,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
||||
a.restrictDuration(MAX_ANIMATION_DURATION);
|
||||
a.scaleCurrentDuration(mTransitionAnimationScaleSetting);
|
||||
startSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool,
|
||||
mMainExecutor, mAnimExecutor, new Point(bounds.left, bounds.top),
|
||||
mMainExecutor, mAnimExecutor, change.getEndRelOffset(),
|
||||
cornerRadius, change.getEndAbsBounds());
|
||||
}
|
||||
|
||||
@@ -959,7 +959,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
||||
a.restrictDuration(MAX_ANIMATION_DURATION);
|
||||
a.scaleCurrentDuration(mTransitionAnimationScaleSetting);
|
||||
startSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool,
|
||||
mMainExecutor, mAnimExecutor, null /* position */,
|
||||
mMainExecutor, mAnimExecutor, change.getEndRelOffset(),
|
||||
cornerRadius, change.getEndAbsBounds());
|
||||
}
|
||||
|
||||
|
||||
@@ -2973,6 +2973,10 @@ class ActivityStarter {
|
||||
newParent = candidateTf;
|
||||
}
|
||||
}
|
||||
if (newParent.canHaveEmbeddingActivityTransition(mStartActivity)) {
|
||||
// Make sure the embedded TaskFragment is included in the start activity transition.
|
||||
newParent.collectEmbeddedTaskFragmentIfNeeded();
|
||||
}
|
||||
if (mStartActivity.getTaskFragment() == null
|
||||
|| mStartActivity.getTaskFragment() == newParent) {
|
||||
newParent.addChild(mStartActivity, POSITION_TOP);
|
||||
|
||||
@@ -2316,6 +2316,26 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
return !startBounds.equals(getBounds());
|
||||
}
|
||||
|
||||
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
|
||||
void setSurfaceControl(SurfaceControl sc) {
|
||||
super.setSurfaceControl(sc);
|
||||
|
||||
@@ -1149,6 +1149,26 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isTranslucent(@NonNull WindowContainer wc) {
|
||||
final TaskFragment taskFragment = wc.asTaskFragment();
|
||||
if (taskFragment != null) {
|
||||
if (taskFragment.isTranslucent(null /* starting */)) {
|
||||
return true;
|
||||
}
|
||||
final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
|
||||
if (adjacentTaskFragment != null) {
|
||||
// Treat the TaskFragment as translucent if its adjacent TF is, otherwise everything
|
||||
// behind two adjacent TaskFragments are occluded.
|
||||
return adjacentTaskFragment.isTranslucent(null /* starting */);
|
||||
}
|
||||
}
|
||||
// TODO(b/172695805): hierarchical check. This is non-trivial because for containers
|
||||
// it is effected by child visibility but needs to work even
|
||||
// before visibility is committed. This means refactoring some
|
||||
// checks to use requested visibility.
|
||||
return !wc.fillsParent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Under some conditions (eg. all visible targets within a parent container are transitioning
|
||||
* the same way) the transition can be "promoted" to the parent container. This means an
|
||||
@@ -1701,20 +1721,13 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
if (mShowWallpaper || wc.showWallpaper()) {
|
||||
flags |= FLAG_SHOW_WALLPAPER;
|
||||
}
|
||||
if (!wc.fillsParent()) {
|
||||
// TODO(b/172695805): hierarchical check. This is non-trivial because for containers
|
||||
// it is effected by child visibility but needs to work even
|
||||
// before visibility is committed. This means refactoring some
|
||||
// checks to use requested visibility.
|
||||
if (isTranslucent(wc)) {
|
||||
flags |= FLAG_TRANSLUCENT;
|
||||
}
|
||||
final Task task = wc.asTask();
|
||||
if (task != null && task.voiceSession != null) {
|
||||
flags |= FLAG_IS_VOICE_INTERACTION;
|
||||
}
|
||||
if (task != null && task.isTranslucent(null)) {
|
||||
flags |= FLAG_TRANSLUCENT;
|
||||
}
|
||||
final ActivityRecord record = wc.asActivityRecord();
|
||||
if (record != null) {
|
||||
if (record.mUseTransferredAnimation) {
|
||||
|
||||
@@ -21,6 +21,7 @@ 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;
|
||||
@@ -837,6 +838,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
break;
|
||||
}
|
||||
|
||||
prepareActivityEmbeddingTransitionForReparentActivityToTaskFragment(parent,
|
||||
activity);
|
||||
activity.reparent(parent, POSITION_TOP);
|
||||
effects |= TRANSACT_EFFECTS_LIFECYCLE;
|
||||
break;
|
||||
@@ -1061,6 +1064,41 @@ 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) {
|
||||
|
||||
Reference in New Issue
Block a user