Loading core/java/android/window/PictureInPictureSurfaceTransaction.java +89 −29 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.window; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.Rect; import android.os.Parcel; import android.os.Parcelable; Loading @@ -34,9 +35,10 @@ import java.util.Objects; * @hide */ public final class PictureInPictureSurfaceTransaction implements Parcelable { private static final float NOT_SET = -1f; public final float mPositionX; public final float mPositionY; public final float mAlpha; public final PointF mPosition; public final float[] mFloat9; Loading @@ -45,33 +47,37 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { public final float mCornerRadius; private final Rect mWindowCrop = new Rect(); private final Rect mWindowCrop; public PictureInPictureSurfaceTransaction(Parcel in) { mPositionX = in.readFloat(); mPositionY = in.readFloat(); private PictureInPictureSurfaceTransaction(Parcel in) { mAlpha = in.readFloat(); mPosition = in.readTypedObject(PointF.CREATOR); mFloat9 = new float[9]; in.readFloatArray(mFloat9); mRotation = in.readFloat(); mCornerRadius = in.readFloat(); mWindowCrop.set(Objects.requireNonNull(in.readTypedObject(Rect.CREATOR))); mWindowCrop = in.readTypedObject(Rect.CREATOR); } public PictureInPictureSurfaceTransaction(float positionX, float positionY, float[] float9, float rotation, float cornerRadius, private PictureInPictureSurfaceTransaction(float alpha, @Nullable PointF position, @Nullable float[] float9, float rotation, float cornerRadius, @Nullable Rect windowCrop) { mPositionX = positionX; mPositionY = positionY; mAlpha = alpha; mPosition = position; if (float9 == null) { mFloat9 = new float[9]; Matrix.IDENTITY_MATRIX.getValues(mFloat9); mRotation = 0; } else { mFloat9 = Arrays.copyOf(float9, 9); mRotation = rotation; mCornerRadius = cornerRadius; if (windowCrop != null) { mWindowCrop.set(windowCrop); } mCornerRadius = cornerRadius; mWindowCrop = (windowCrop == null) ? null : new Rect(windowCrop); } public PictureInPictureSurfaceTransaction(PictureInPictureSurfaceTransaction other) { this(other.mPositionX, other.mPositionY, this(other.mAlpha, other.mPosition, other.mFloat9, other.mRotation, other.mCornerRadius, other.mWindowCrop); } Loading @@ -82,13 +88,18 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { return matrix; } /** @return {@code true} if this transaction contains setting corner radius. */ public boolean hasCornerRadiusSet() { return mCornerRadius > 0; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof PictureInPictureSurfaceTransaction)) return false; PictureInPictureSurfaceTransaction that = (PictureInPictureSurfaceTransaction) o; return Objects.equals(mPositionX, that.mPositionX) && Objects.equals(mPositionY, that.mPositionY) return Objects.equals(mAlpha, that.mAlpha) && Objects.equals(mPosition, that.mPosition) && Arrays.equals(mFloat9, that.mFloat9) && Objects.equals(mRotation, that.mRotation) && Objects.equals(mCornerRadius, that.mCornerRadius) Loading @@ -97,7 +108,7 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { @Override public int hashCode() { return Objects.hash(mPositionX, mPositionY, Arrays.hashCode(mFloat9), return Objects.hash(mAlpha, mPosition, Arrays.hashCode(mFloat9), mRotation, mCornerRadius, mWindowCrop); } Loading @@ -108,8 +119,8 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { @Override public void writeToParcel(Parcel out, int flags) { out.writeFloat(mPositionX); out.writeFloat(mPositionY); out.writeFloat(mAlpha); out.writeTypedObject(mPosition, 0 /* flags */); out.writeFloatArray(mFloat9); out.writeFloat(mRotation); out.writeFloat(mCornerRadius); Loading @@ -120,8 +131,8 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { public String toString() { final Matrix matrix = getMatrix(); return "PictureInPictureSurfaceTransaction(" + " posX=" + mPositionX + " posY=" + mPositionY + " alpha=" + mAlpha + " position=" + mPosition + " matrix=" + matrix.toShortString() + " rotation=" + mRotation + " cornerRadius=" + mCornerRadius Loading @@ -134,11 +145,20 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { @NonNull SurfaceControl surfaceControl, @NonNull SurfaceControl.Transaction tx) { final Matrix matrix = surfaceTransaction.getMatrix(); tx.setMatrix(surfaceControl, matrix, new float[9]) .setPosition(surfaceControl, surfaceTransaction.mPositionX, surfaceTransaction.mPositionY) .setWindowCrop(surfaceControl, surfaceTransaction.mWindowCrop) .setCornerRadius(surfaceControl, surfaceTransaction.mCornerRadius); tx.setMatrix(surfaceControl, matrix, new float[9]); if (surfaceTransaction.mPosition != null) { tx.setPosition(surfaceControl, surfaceTransaction.mPosition.x, surfaceTransaction.mPosition.y); } if (surfaceTransaction.mWindowCrop != null) { tx.setWindowCrop(surfaceControl, surfaceTransaction.mWindowCrop); } if (surfaceTransaction.hasCornerRadiusSet()) { tx.setCornerRadius(surfaceControl, surfaceTransaction.mCornerRadius); } if (surfaceTransaction.mAlpha != NOT_SET) { tx.setAlpha(surfaceControl, surfaceTransaction.mAlpha); } } public static final @android.annotation.NonNull Creator<PictureInPictureSurfaceTransaction> Loading @@ -151,4 +171,44 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { return new PictureInPictureSurfaceTransaction[size]; } }; public static class Builder { private float mAlpha = NOT_SET; private PointF mPosition; private float[] mFloat9; private float mRotation; private float mCornerRadius = NOT_SET; private Rect mWindowCrop; public Builder setAlpha(float alpha) { mAlpha = alpha; return this; } public Builder setPosition(float x, float y) { mPosition = new PointF(x, y); return this; } public Builder setTransform(@NonNull float[] float9, float rotation) { mFloat9 = Arrays.copyOf(float9, 9); mRotation = rotation; return this; } public Builder setCornerRadius(float cornerRadius) { mCornerRadius = cornerRadius; return this; } public Builder setWindowCrop(@NonNull Rect windowCrop) { mWindowCrop = new Rect(windowCrop); return this; } public PictureInPictureSurfaceTransaction build() { return new PictureInPictureSurfaceTransaction(mAlpha, mPosition, mFloat9, mRotation, mCornerRadius, mWindowCrop); } } } libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +4 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, static final int EXIT_REASON_ROOT_TASK_VANISHED = 6; static final int EXIT_REASON_SCREEN_LOCKED = 7; static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8; static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9; @IntDef(value = { EXIT_REASON_UNKNOWN, EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW, Loading @@ -112,6 +113,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, EXIT_REASON_ROOT_TASK_VANISHED, EXIT_REASON_SCREEN_LOCKED, EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP, EXIT_REASON_CHILD_TASK_ENTER_PIP, }) @Retention(RetentionPolicy.SOURCE) @interface ExitReason{} Loading Loading @@ -406,6 +408,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return "APP_FINISHED"; case EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW: return "APP_DOES_NOT_SUPPORT_MULTIWINDOW"; case EXIT_REASON_CHILD_TASK_ENTER_PIP: return "CHILD_TASK_ENTER_PIP"; default: return "unknown reason, reason int = " + exitReason; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +19 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED; import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME; Loading Loading @@ -629,8 +630,12 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, }); mShouldUpdateRecents = false; mSideStage.removeAllTasks(wct, childrenToTop == mSideStage); mMainStage.deactivate(wct, childrenToTop == mMainStage); // When the exit split-screen is caused by one of the task enters auto pip, // we want the tasks to be put to bottom instead of top, otherwise it will end up // a fullscreen plus a pinned task instead of pinned only at the end of the transition. final boolean fromEnteringPip = exitReason == EXIT_REASON_CHILD_TASK_ENTER_PIP; mSideStage.removeAllTasks(wct, !fromEnteringPip && childrenToTop == mSideStage); mMainStage.deactivate(wct, !fromEnteringPip && childrenToTop == mMainStage); mTaskOrganizer.applyTransaction(wct); mSyncQueue.runInSync(t -> t .setWindowCrop(mMainStage.mRootLeash, null) Loading Loading @@ -660,6 +665,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, case EXIT_REASON_DRAG_DIVIDER: // Either of the split apps have finished case EXIT_REASON_APP_FINISHED: // One of the children enters PiP case EXIT_REASON_CHILD_TASK_ENTER_PIP: return true; default: return false; Loading Loading @@ -749,6 +756,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } private void onStageChildTaskEnterPip(StageListenerImpl stageListener, int taskId) { exitSplitScreen(stageListener == mMainStageListener ? mMainStage : mSideStage, EXIT_REASON_CHILD_TASK_ENTER_PIP); } private void updateRecentTasksSplitPair() { if (!mShouldUpdateRecents) { return; Loading Loading @@ -1436,6 +1448,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present, visible); } @Override public void onChildTaskEnterPip(int taskId) { StageCoordinator.this.onStageChildTaskEnterPip(this, taskId); } @Override public void onRootTaskVanished() { reset(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +6 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS; Loading Loading @@ -73,6 +74,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { void onChildTaskStatusChanged(int taskId, boolean present, boolean visible); void onChildTaskEnterPip(int taskId); void onRootTaskVanished(); void onNoLongerSupportMultiWindow(); Loading Loading @@ -256,6 +259,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { mChildrenTaskInfo.remove(taskId); mChildrenLeashes.remove(taskId); mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible); if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) { mCallbacks.onChildTaskEnterPip(taskId); } if (ENABLE_SHELL_TRANSITIONS) { // Status is managed/synchronized by the transition lifecycle. return; Loading packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java +18 −8 Original line number Diff line number Diff line Loading @@ -53,8 +53,8 @@ public class PipSurfaceTransactionHelper { tx.setMatrix(leash, mTmpTransform, mTmpFloat9) .setPosition(leash, positionX, positionY) .setCornerRadius(leash, cornerRadius); return new PictureInPictureSurfaceTransaction( positionX, positionY, mTmpFloat9, 0 /* rotation */, cornerRadius, sourceBounds); return newPipSurfaceTransaction(positionX, positionY, mTmpFloat9, 0 /* rotation */, cornerRadius, sourceBounds); } public PictureInPictureSurfaceTransaction scale( Loading @@ -70,8 +70,8 @@ public class PipSurfaceTransactionHelper { tx.setMatrix(leash, mTmpTransform, mTmpFloat9) .setPosition(leash, positionX, positionY) .setCornerRadius(leash, cornerRadius); return new PictureInPictureSurfaceTransaction( positionX, positionY, mTmpFloat9, degree, cornerRadius, sourceBounds); return newPipSurfaceTransaction(positionX, positionY, mTmpFloat9, degree, cornerRadius, sourceBounds); } public PictureInPictureSurfaceTransaction scaleAndCrop( Loading @@ -93,8 +93,8 @@ public class PipSurfaceTransactionHelper { .setWindowCrop(leash, mTmpDestinationRect) .setPosition(leash, left, top) .setCornerRadius(leash, cornerRadius); return new PictureInPictureSurfaceTransaction( left, top, mTmpFloat9, 0 /* rotation */, cornerRadius, mTmpDestinationRect); return newPipSurfaceTransaction(left, top, mTmpFloat9, 0 /* rotation */, cornerRadius, mTmpDestinationRect); } public PictureInPictureSurfaceTransaction scaleAndRotate( Loading Loading @@ -125,8 +125,7 @@ public class PipSurfaceTransactionHelper { .setWindowCrop(leash, mTmpDestinationRect) .setPosition(leash, adjustedPositionX, adjustedPositionY) .setCornerRadius(leash, cornerRadius); return new PictureInPictureSurfaceTransaction( adjustedPositionX, adjustedPositionY, return newPipSurfaceTransaction(adjustedPositionX, adjustedPositionY, mTmpFloat9, degree, cornerRadius, mTmpDestinationRect); } Loading @@ -137,6 +136,17 @@ public class PipSurfaceTransactionHelper { return mCornerRadius * scale; } private static PictureInPictureSurfaceTransaction newPipSurfaceTransaction( float posX, float posY, float[] float9, float rotation, float cornerRadius, Rect windowCrop) { return new PictureInPictureSurfaceTransaction.Builder() .setPosition(posX, posY) .setTransform(float9, rotation) .setCornerRadius(cornerRadius) .setWindowCrop(windowCrop) .build(); } /** @return {@link SurfaceControl.Transaction} instance with vsync-id */ public static SurfaceControl.Transaction newSurfaceControlTransaction() { final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); Loading Loading
core/java/android/window/PictureInPictureSurfaceTransaction.java +89 −29 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.window; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.Rect; import android.os.Parcel; import android.os.Parcelable; Loading @@ -34,9 +35,10 @@ import java.util.Objects; * @hide */ public final class PictureInPictureSurfaceTransaction implements Parcelable { private static final float NOT_SET = -1f; public final float mPositionX; public final float mPositionY; public final float mAlpha; public final PointF mPosition; public final float[] mFloat9; Loading @@ -45,33 +47,37 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { public final float mCornerRadius; private final Rect mWindowCrop = new Rect(); private final Rect mWindowCrop; public PictureInPictureSurfaceTransaction(Parcel in) { mPositionX = in.readFloat(); mPositionY = in.readFloat(); private PictureInPictureSurfaceTransaction(Parcel in) { mAlpha = in.readFloat(); mPosition = in.readTypedObject(PointF.CREATOR); mFloat9 = new float[9]; in.readFloatArray(mFloat9); mRotation = in.readFloat(); mCornerRadius = in.readFloat(); mWindowCrop.set(Objects.requireNonNull(in.readTypedObject(Rect.CREATOR))); mWindowCrop = in.readTypedObject(Rect.CREATOR); } public PictureInPictureSurfaceTransaction(float positionX, float positionY, float[] float9, float rotation, float cornerRadius, private PictureInPictureSurfaceTransaction(float alpha, @Nullable PointF position, @Nullable float[] float9, float rotation, float cornerRadius, @Nullable Rect windowCrop) { mPositionX = positionX; mPositionY = positionY; mAlpha = alpha; mPosition = position; if (float9 == null) { mFloat9 = new float[9]; Matrix.IDENTITY_MATRIX.getValues(mFloat9); mRotation = 0; } else { mFloat9 = Arrays.copyOf(float9, 9); mRotation = rotation; mCornerRadius = cornerRadius; if (windowCrop != null) { mWindowCrop.set(windowCrop); } mCornerRadius = cornerRadius; mWindowCrop = (windowCrop == null) ? null : new Rect(windowCrop); } public PictureInPictureSurfaceTransaction(PictureInPictureSurfaceTransaction other) { this(other.mPositionX, other.mPositionY, this(other.mAlpha, other.mPosition, other.mFloat9, other.mRotation, other.mCornerRadius, other.mWindowCrop); } Loading @@ -82,13 +88,18 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { return matrix; } /** @return {@code true} if this transaction contains setting corner radius. */ public boolean hasCornerRadiusSet() { return mCornerRadius > 0; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof PictureInPictureSurfaceTransaction)) return false; PictureInPictureSurfaceTransaction that = (PictureInPictureSurfaceTransaction) o; return Objects.equals(mPositionX, that.mPositionX) && Objects.equals(mPositionY, that.mPositionY) return Objects.equals(mAlpha, that.mAlpha) && Objects.equals(mPosition, that.mPosition) && Arrays.equals(mFloat9, that.mFloat9) && Objects.equals(mRotation, that.mRotation) && Objects.equals(mCornerRadius, that.mCornerRadius) Loading @@ -97,7 +108,7 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { @Override public int hashCode() { return Objects.hash(mPositionX, mPositionY, Arrays.hashCode(mFloat9), return Objects.hash(mAlpha, mPosition, Arrays.hashCode(mFloat9), mRotation, mCornerRadius, mWindowCrop); } Loading @@ -108,8 +119,8 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { @Override public void writeToParcel(Parcel out, int flags) { out.writeFloat(mPositionX); out.writeFloat(mPositionY); out.writeFloat(mAlpha); out.writeTypedObject(mPosition, 0 /* flags */); out.writeFloatArray(mFloat9); out.writeFloat(mRotation); out.writeFloat(mCornerRadius); Loading @@ -120,8 +131,8 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { public String toString() { final Matrix matrix = getMatrix(); return "PictureInPictureSurfaceTransaction(" + " posX=" + mPositionX + " posY=" + mPositionY + " alpha=" + mAlpha + " position=" + mPosition + " matrix=" + matrix.toShortString() + " rotation=" + mRotation + " cornerRadius=" + mCornerRadius Loading @@ -134,11 +145,20 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { @NonNull SurfaceControl surfaceControl, @NonNull SurfaceControl.Transaction tx) { final Matrix matrix = surfaceTransaction.getMatrix(); tx.setMatrix(surfaceControl, matrix, new float[9]) .setPosition(surfaceControl, surfaceTransaction.mPositionX, surfaceTransaction.mPositionY) .setWindowCrop(surfaceControl, surfaceTransaction.mWindowCrop) .setCornerRadius(surfaceControl, surfaceTransaction.mCornerRadius); tx.setMatrix(surfaceControl, matrix, new float[9]); if (surfaceTransaction.mPosition != null) { tx.setPosition(surfaceControl, surfaceTransaction.mPosition.x, surfaceTransaction.mPosition.y); } if (surfaceTransaction.mWindowCrop != null) { tx.setWindowCrop(surfaceControl, surfaceTransaction.mWindowCrop); } if (surfaceTransaction.hasCornerRadiusSet()) { tx.setCornerRadius(surfaceControl, surfaceTransaction.mCornerRadius); } if (surfaceTransaction.mAlpha != NOT_SET) { tx.setAlpha(surfaceControl, surfaceTransaction.mAlpha); } } public static final @android.annotation.NonNull Creator<PictureInPictureSurfaceTransaction> Loading @@ -151,4 +171,44 @@ public final class PictureInPictureSurfaceTransaction implements Parcelable { return new PictureInPictureSurfaceTransaction[size]; } }; public static class Builder { private float mAlpha = NOT_SET; private PointF mPosition; private float[] mFloat9; private float mRotation; private float mCornerRadius = NOT_SET; private Rect mWindowCrop; public Builder setAlpha(float alpha) { mAlpha = alpha; return this; } public Builder setPosition(float x, float y) { mPosition = new PointF(x, y); return this; } public Builder setTransform(@NonNull float[] float9, float rotation) { mFloat9 = Arrays.copyOf(float9, 9); mRotation = rotation; return this; } public Builder setCornerRadius(float cornerRadius) { mCornerRadius = cornerRadius; return this; } public Builder setWindowCrop(@NonNull Rect windowCrop) { mWindowCrop = new Rect(windowCrop); return this; } public PictureInPictureSurfaceTransaction build() { return new PictureInPictureSurfaceTransaction(mAlpha, mPosition, mFloat9, mRotation, mCornerRadius, mWindowCrop); } } }
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +4 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, static final int EXIT_REASON_ROOT_TASK_VANISHED = 6; static final int EXIT_REASON_SCREEN_LOCKED = 7; static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8; static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9; @IntDef(value = { EXIT_REASON_UNKNOWN, EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW, Loading @@ -112,6 +113,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, EXIT_REASON_ROOT_TASK_VANISHED, EXIT_REASON_SCREEN_LOCKED, EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP, EXIT_REASON_CHILD_TASK_ENTER_PIP, }) @Retention(RetentionPolicy.SOURCE) @interface ExitReason{} Loading Loading @@ -406,6 +408,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return "APP_FINISHED"; case EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW: return "APP_DOES_NOT_SUPPORT_MULTIWINDOW"; case EXIT_REASON_CHILD_TASK_ENTER_PIP: return "CHILD_TASK_ENTER_PIP"; default: return "unknown reason, reason int = " + exitReason; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +19 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED; import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME; Loading Loading @@ -629,8 +630,12 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, }); mShouldUpdateRecents = false; mSideStage.removeAllTasks(wct, childrenToTop == mSideStage); mMainStage.deactivate(wct, childrenToTop == mMainStage); // When the exit split-screen is caused by one of the task enters auto pip, // we want the tasks to be put to bottom instead of top, otherwise it will end up // a fullscreen plus a pinned task instead of pinned only at the end of the transition. final boolean fromEnteringPip = exitReason == EXIT_REASON_CHILD_TASK_ENTER_PIP; mSideStage.removeAllTasks(wct, !fromEnteringPip && childrenToTop == mSideStage); mMainStage.deactivate(wct, !fromEnteringPip && childrenToTop == mMainStage); mTaskOrganizer.applyTransaction(wct); mSyncQueue.runInSync(t -> t .setWindowCrop(mMainStage.mRootLeash, null) Loading Loading @@ -660,6 +665,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, case EXIT_REASON_DRAG_DIVIDER: // Either of the split apps have finished case EXIT_REASON_APP_FINISHED: // One of the children enters PiP case EXIT_REASON_CHILD_TASK_ENTER_PIP: return true; default: return false; Loading Loading @@ -749,6 +756,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } private void onStageChildTaskEnterPip(StageListenerImpl stageListener, int taskId) { exitSplitScreen(stageListener == mMainStageListener ? mMainStage : mSideStage, EXIT_REASON_CHILD_TASK_ENTER_PIP); } private void updateRecentTasksSplitPair() { if (!mShouldUpdateRecents) { return; Loading Loading @@ -1436,6 +1448,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present, visible); } @Override public void onChildTaskEnterPip(int taskId) { StageCoordinator.this.onStageChildTaskEnterPip(this, taskId); } @Override public void onRootTaskVanished() { reset(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +6 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS; Loading Loading @@ -73,6 +74,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { void onChildTaskStatusChanged(int taskId, boolean present, boolean visible); void onChildTaskEnterPip(int taskId); void onRootTaskVanished(); void onNoLongerSupportMultiWindow(); Loading Loading @@ -256,6 +259,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { mChildrenTaskInfo.remove(taskId); mChildrenLeashes.remove(taskId); mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible); if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) { mCallbacks.onChildTaskEnterPip(taskId); } if (ENABLE_SHELL_TRANSITIONS) { // Status is managed/synchronized by the transition lifecycle. return; Loading
packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java +18 −8 Original line number Diff line number Diff line Loading @@ -53,8 +53,8 @@ public class PipSurfaceTransactionHelper { tx.setMatrix(leash, mTmpTransform, mTmpFloat9) .setPosition(leash, positionX, positionY) .setCornerRadius(leash, cornerRadius); return new PictureInPictureSurfaceTransaction( positionX, positionY, mTmpFloat9, 0 /* rotation */, cornerRadius, sourceBounds); return newPipSurfaceTransaction(positionX, positionY, mTmpFloat9, 0 /* rotation */, cornerRadius, sourceBounds); } public PictureInPictureSurfaceTransaction scale( Loading @@ -70,8 +70,8 @@ public class PipSurfaceTransactionHelper { tx.setMatrix(leash, mTmpTransform, mTmpFloat9) .setPosition(leash, positionX, positionY) .setCornerRadius(leash, cornerRadius); return new PictureInPictureSurfaceTransaction( positionX, positionY, mTmpFloat9, degree, cornerRadius, sourceBounds); return newPipSurfaceTransaction(positionX, positionY, mTmpFloat9, degree, cornerRadius, sourceBounds); } public PictureInPictureSurfaceTransaction scaleAndCrop( Loading @@ -93,8 +93,8 @@ public class PipSurfaceTransactionHelper { .setWindowCrop(leash, mTmpDestinationRect) .setPosition(leash, left, top) .setCornerRadius(leash, cornerRadius); return new PictureInPictureSurfaceTransaction( left, top, mTmpFloat9, 0 /* rotation */, cornerRadius, mTmpDestinationRect); return newPipSurfaceTransaction(left, top, mTmpFloat9, 0 /* rotation */, cornerRadius, mTmpDestinationRect); } public PictureInPictureSurfaceTransaction scaleAndRotate( Loading Loading @@ -125,8 +125,7 @@ public class PipSurfaceTransactionHelper { .setWindowCrop(leash, mTmpDestinationRect) .setPosition(leash, adjustedPositionX, adjustedPositionY) .setCornerRadius(leash, cornerRadius); return new PictureInPictureSurfaceTransaction( adjustedPositionX, adjustedPositionY, return newPipSurfaceTransaction(adjustedPositionX, adjustedPositionY, mTmpFloat9, degree, cornerRadius, mTmpDestinationRect); } Loading @@ -137,6 +136,17 @@ public class PipSurfaceTransactionHelper { return mCornerRadius * scale; } private static PictureInPictureSurfaceTransaction newPipSurfaceTransaction( float posX, float posY, float[] float9, float rotation, float cornerRadius, Rect windowCrop) { return new PictureInPictureSurfaceTransaction.Builder() .setPosition(posX, posY) .setTransform(float9, rotation) .setCornerRadius(cornerRadius) .setWindowCrop(windowCrop) .build(); } /** @return {@link SurfaceControl.Transaction} instance with vsync-id */ public static SurfaceControl.Transaction newSurfaceControlTransaction() { final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); Loading