summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java27
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java48
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java14
12 files changed, 178 insertions, 30 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 91ea436f81b6..3f8343a7abd3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -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;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
index 54e743f72cc6..ca4ef07eb1db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
@@ -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
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
index e344c3bea42b..33eec335bca3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
@@ -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);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 52ff21bc3172..fef9be36a35f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -110,6 +110,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 + " ";
pw.println(prefix + this);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 6e38e421d4b6..73e6cba43ec0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -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
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
index 86bf3ff1cea9..d2f42c39acd5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
@@ -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
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
index ddc85f758916..e03421dd58ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
@@ -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.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index f9ec88659eea..bfa14f3a705d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -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;
}
@@ -837,6 +849,24 @@ public class PipTaskOrganizer 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 (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;
mWaitForFixedRotation = true;
@@ -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);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 4cab6d336892..401dc9ae02e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -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;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 5b6c95eef561..e7a1c4cca07e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -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);
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index c5aab45f56fa..109f96e166d7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -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);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
index 8b36c9406b15..7b679580fa87 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
@@ -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);
}