Merge "Transfer PipContentOverlay when swipe to home with Shell transition" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
7fe1c1386d
@@ -98,16 +98,22 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
|
||||
default void onTaskInfoChanged(RunningTaskInfo taskInfo) {}
|
||||
default void onTaskVanished(RunningTaskInfo taskInfo) {}
|
||||
default void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {}
|
||||
/** Whether this task listener supports compat UI. */
|
||||
/** Whether this task listener supports compat UI. */
|
||||
default boolean supportCompatUI() {
|
||||
// All TaskListeners should support compat UI except PIP.
|
||||
return true;
|
||||
}
|
||||
/** Attaches the a child window surface to the task surface. */
|
||||
/** Attaches a child window surface to the task surface. */
|
||||
default void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
|
||||
throw new IllegalStateException(
|
||||
"This task listener doesn't support child surface attachment.");
|
||||
}
|
||||
/** Reparents a child window surface to the task surface. */
|
||||
default void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
throw new IllegalStateException(
|
||||
"This task listener doesn't support child surface reparent.");
|
||||
}
|
||||
default void dump(@NonNull PrintWriter pw, String prefix) {};
|
||||
}
|
||||
|
||||
@@ -620,6 +626,23 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
|
||||
updateCameraCompatControlState(info.getTaskInfo().token, state);
|
||||
}
|
||||
|
||||
/** Reparents a child window surface to the task surface. */
|
||||
public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
final TaskListener taskListener;
|
||||
synchronized (mLock) {
|
||||
taskListener = mTasks.contains(taskId)
|
||||
? getTaskListener(mTasks.get(taskId).getTaskInfo())
|
||||
: null;
|
||||
}
|
||||
if (taskListener == null) {
|
||||
ProtoLog.w(WM_SHELL_TASK_ORG, "Failed to find Task to reparent surface taskId=%d",
|
||||
taskId);
|
||||
return;
|
||||
}
|
||||
taskListener.reparentChildSurfaceToTask(taskId, sc, t);
|
||||
}
|
||||
|
||||
private void logSizeCompatRestartButtonEventReported(@NonNull TaskAppearedInfo info,
|
||||
int event) {
|
||||
ActivityInfo topActivityInfo = info.getTaskInfo().topActivityInfo;
|
||||
|
||||
@@ -367,10 +367,20 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
|
||||
@Override
|
||||
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
|
||||
if (mTaskInfo.taskId != taskId) {
|
||||
b.setParent(findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
t.reparent(sc, findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
private SurfaceControl findTaskSurface(int taskId) {
|
||||
if (mTaskInfo == null || mTaskLeash == null || mTaskInfo.taskId != taskId) {
|
||||
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
|
||||
}
|
||||
b.setParent(mTaskLeash);
|
||||
return mTaskLeash;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -275,12 +275,22 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
|
||||
|
||||
@Override
|
||||
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
|
||||
b.setParent(findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
t.reparent(sc, findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
private SurfaceControl findTaskSurface(int taskId) {
|
||||
if (getRootTaskId() == taskId) {
|
||||
b.setParent(mRootTaskLeash);
|
||||
return mRootTaskLeash;
|
||||
} else if (getTaskId1() == taskId) {
|
||||
b.setParent(mTaskLeash1);
|
||||
return mTaskLeash1;
|
||||
} else if (getTaskId2() == taskId) {
|
||||
b.setParent(mTaskLeash2);
|
||||
return mTaskLeash2;
|
||||
} else {
|
||||
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
|
||||
}
|
||||
|
||||
@@ -109,6 +109,24 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
|
||||
b.setParent(findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
t.reparent(sc, findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
private SurfaceControl findTaskSurface(int taskId) {
|
||||
if (!mTasks.contains(taskId)) {
|
||||
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
|
||||
}
|
||||
return mTasks.get(taskId).mLeash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw, String prefix) {
|
||||
final String innerPrefix = prefix + " ";
|
||||
|
||||
@@ -133,10 +133,20 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
|
||||
@Override
|
||||
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
|
||||
b.setParent(findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
t.reparent(sc, findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
private SurfaceControl findTaskSurface(int taskId) {
|
||||
if (!mDataByTaskId.contains(taskId)) {
|
||||
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
|
||||
}
|
||||
b.setParent(mDataByTaskId.get(taskId).surface);
|
||||
return mDataByTaskId.get(taskId).surface;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -343,10 +343,20 @@ class LegacySplitScreenTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
|
||||
@Override
|
||||
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
|
||||
b.setParent(findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
t.reparent(sc, findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
private SurfaceControl findTaskSurface(int taskId) {
|
||||
if (!mLeashByTaskId.contains(taskId)) {
|
||||
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
|
||||
}
|
||||
b.setParent(mLeashByTaskId.get(taskId));
|
||||
return mLeashByTaskId.get(taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -47,12 +47,13 @@ interface IPip {
|
||||
/**
|
||||
* Notifies the swiping Activity to PiP onto home transition is finished
|
||||
*
|
||||
* @param taskId the Task id that the Activity and overlay are currently in.
|
||||
* @param componentName ComponentName represents the Activity
|
||||
* @param destinationBounds the destination bounds the PiP window lands into
|
||||
* @param overlay an optional overlay to fade out after entering PiP
|
||||
*/
|
||||
oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds,
|
||||
in SurfaceControl overlay) = 2;
|
||||
oneway void stopSwipePipToHome(int taskId, in ComponentName componentName,
|
||||
in Rect destinationBounds, in SurfaceControl overlay) = 2;
|
||||
|
||||
/**
|
||||
* Sets listener to get pinned stack animation callbacks.
|
||||
|
||||
@@ -250,7 +250,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
* An optional overlay used to mask content changing between an app in/out of PiP, only set if
|
||||
* {@link PipTransitionState#getInSwipePipToHomeTransition()} is true.
|
||||
*/
|
||||
private SurfaceControl mSwipePipToHomeOverlay;
|
||||
@Nullable
|
||||
SurfaceControl mSwipePipToHomeOverlay;
|
||||
|
||||
public PipTaskOrganizer(Context context,
|
||||
@NonNull SyncTransactionQueue syncTransactionQueue,
|
||||
@@ -357,12 +358,24 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
* Callback when launcher finishes swipe-pip-to-home operation.
|
||||
* Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards.
|
||||
*/
|
||||
public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
|
||||
public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
|
||||
SurfaceControl overlay) {
|
||||
// do nothing if there is no startSwipePipToHome being called before
|
||||
if (mPipTransitionState.getInSwipePipToHomeTransition()) {
|
||||
mPipBoundsState.setBounds(destinationBounds);
|
||||
mSwipePipToHomeOverlay = overlay;
|
||||
if (!mPipTransitionState.getInSwipePipToHomeTransition()) {
|
||||
return;
|
||||
}
|
||||
mPipBoundsState.setBounds(destinationBounds);
|
||||
mSwipePipToHomeOverlay = overlay;
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
// With Shell transition, the overlay was attached to the remote transition leash, which
|
||||
// will be removed when the current transition is finished, so we need to reparent it
|
||||
// to the actual Task surface now.
|
||||
// PipTransition is responsible to fade it out and cleanup when finishing the enter PIP
|
||||
// transition.
|
||||
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
mTaskOrganizer.reparentChildSurfaceToTask(taskId, overlay, t);
|
||||
t.setLayer(overlay, Integer.MAX_VALUE);
|
||||
t.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,7 +695,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
|
||||
private void onEndOfSwipePipToHomeTransition() {
|
||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||
mSwipePipToHomeOverlay = null;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -836,6 +848,24 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
|
||||
b.setParent(findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
t.reparent(sc, findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
private SurfaceControl findTaskSurface(int taskId) {
|
||||
if (mTaskInfo == null || mLeash == null || mTaskInfo.taskId != taskId) {
|
||||
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
|
||||
}
|
||||
return mLeash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFixedRotationStarted(int displayId, int newRotation) {
|
||||
mNextRotation = newRotation;
|
||||
@@ -891,9 +921,13 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
clearWaitForFixedRotation();
|
||||
}
|
||||
|
||||
/** Called when exiting PIP tranisiton is finished to do the state cleanup. */
|
||||
/** Called when exiting PIP transition is finished to do the state cleanup. */
|
||||
void onExitPipFinished(TaskInfo info) {
|
||||
clearWaitForFixedRotation();
|
||||
if (mSwipePipToHomeOverlay != null) {
|
||||
removeContentOverlay(mSwipePipToHomeOverlay, null /* callback */);
|
||||
mSwipePipToHomeOverlay = null;
|
||||
}
|
||||
mPipTransitionState.setInSwipePipToHomeTransition(false);
|
||||
mPictureInPictureParams = null;
|
||||
mPipTransitionState.setTransitionState(PipTransitionState.UNDEFINED);
|
||||
|
||||
@@ -604,11 +604,18 @@ public class PipTransition extends PipTransitionController {
|
||||
&& taskInfo.pictureInPictureParams.isAutoEnterEnabled()
|
||||
&& mPipTransitionState.getInSwipePipToHomeTransition()) {
|
||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||
SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
|
||||
tx.setMatrix(leash, Matrix.IDENTITY_MATRIX, new float[9])
|
||||
final SurfaceControl swipePipToHomeOverlay = mPipOrganizer.mSwipePipToHomeOverlay;
|
||||
startTransaction.setMatrix(leash, Matrix.IDENTITY_MATRIX, new float[9])
|
||||
.setPosition(leash, destinationBounds.left, destinationBounds.top)
|
||||
.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height());
|
||||
startTransaction.merge(tx);
|
||||
if (swipePipToHomeOverlay != null) {
|
||||
// Launcher fade in the overlay on top of the fullscreen Task. It is possible we
|
||||
// reparent the PIP activity to a new PIP task (in case there are other activities
|
||||
// in the original Task), so we should also reparent the overlay to the PIP task.
|
||||
startTransaction.reparent(swipePipToHomeOverlay, leash)
|
||||
.setLayer(swipePipToHomeOverlay, Integer.MAX_VALUE);
|
||||
mPipOrganizer.mSwipePipToHomeOverlay = null;
|
||||
}
|
||||
startTransaction.apply();
|
||||
if (rotationDelta != Surface.ROTATION_0 && mInFixedRotation) {
|
||||
// For fixed rotation, set the destination bounds to the new rotation coordinates
|
||||
@@ -618,6 +625,10 @@ public class PipTransition extends PipTransitionController {
|
||||
mPipBoundsState.setBounds(destinationBounds);
|
||||
onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, null /* tx */);
|
||||
sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
|
||||
if (swipePipToHomeOverlay != null) {
|
||||
mPipOrganizer.fadeOutAndRemoveOverlay(swipePipToHomeOverlay,
|
||||
null /* callback */, false /* withStartDelay */);
|
||||
}
|
||||
mPipTransitionState.setInSwipePipToHomeTransition(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -595,9 +595,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
return entryBounds;
|
||||
}
|
||||
|
||||
private void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
|
||||
private void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
|
||||
SurfaceControl overlay) {
|
||||
mPipTaskOrganizer.stopSwipePipToHome(componentName, destinationBounds, overlay);
|
||||
mPipTaskOrganizer.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay);
|
||||
}
|
||||
|
||||
private String getTransitionTag(int direction) {
|
||||
@@ -928,11 +928,12 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
|
||||
SurfaceControl overlay) {
|
||||
public void stopSwipePipToHome(int taskId, ComponentName componentName,
|
||||
Rect destinationBounds, SurfaceControl overlay) {
|
||||
executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome",
|
||||
(controller) -> {
|
||||
controller.stopSwipePipToHome(componentName, destinationBounds, overlay);
|
||||
controller.stopSwipePipToHome(taskId, componentName, destinationBounds,
|
||||
overlay);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -280,10 +280,20 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
|
||||
@Override
|
||||
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
|
||||
b.setParent(findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
t.reparent(sc, findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
private SurfaceControl findTaskSurface(int taskId) {
|
||||
if (mRootTaskInfo.taskId == taskId) {
|
||||
b.setParent(mRootLeash);
|
||||
return mRootLeash;
|
||||
} else if (mChildrenLeashes.contains(taskId)) {
|
||||
b.setParent(mChildrenLeashes.get(taskId));
|
||||
return mChildrenLeashes.get(taskId);
|
||||
} else {
|
||||
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
|
||||
}
|
||||
|
||||
@@ -227,10 +227,20 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
|
||||
@Override
|
||||
public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
|
||||
b.setParent(findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
|
||||
SurfaceControl.Transaction t) {
|
||||
t.reparent(sc, findTaskSurface(taskId));
|
||||
}
|
||||
|
||||
private SurfaceControl findTaskSurface(int taskId) {
|
||||
if (mRootTaskInfo.taskId == taskId) {
|
||||
b.setParent(mRootLeash);
|
||||
return mRootLeash;
|
||||
} else if (mChildrenLeashes.contains(taskId)) {
|
||||
b.setParent(mChildrenLeashes.get(taskId));
|
||||
return mChildrenLeashes.get(taskId);
|
||||
} else {
|
||||
throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user