From 4331d6ff423215f08ccac548d2afa6f9abf1c9e1 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Thu, 11 Aug 2022 13:22:59 -0700 Subject: [PATCH] Add split screen API to start two split apps with intents Fixes: 239824922 Test: See the video in the other change of this topic Change-Id: I9fade744e5dac2683d87bda5079453b8efbb977e --- .../wm/shell/splitscreen/ISplitScreen.aidl | 19 +++++++- .../splitscreen/SplitScreenController.java | 45 +++++++++++++++++++ .../shell/splitscreen/StageCoordinator.java | 41 +++++++++++++++-- 3 files changed, 99 insertions(+), 6 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl index 5533ad56d17c1..56aa742b8626f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl @@ -95,7 +95,7 @@ interface ISplitScreen { */ oneway void startShortcutAndTask(in ShortcutInfo shortcutInfo, in Bundle options1, int taskId, in Bundle options2, int splitPosition, float splitRatio, - in RemoteTransition remoteTransition, in InstanceId instanceId) = 17; + in RemoteTransition remoteTransition, in InstanceId instanceId) = 17; /** * Version of startTasks using legacy transition system. @@ -118,6 +118,21 @@ interface ISplitScreen { in Bundle options1, int taskId, in Bundle options2, int splitPosition, float splitRatio, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 15; + /** + * Start a pair of intents using legacy transition system. + */ + oneway void startIntentsWithLegacyTransition(in PendingIntent pendingIntent1, + in Bundle options1, in PendingIntent pendingIntent2, in Bundle options2, + int splitPosition, float splitRatio, in RemoteAnimationAdapter adapter, + in InstanceId instanceId) = 18; + + /** + * Start a pair of intents in one transition. + */ + oneway void startIntents(in PendingIntent pendingIntent1, in Bundle options1, + in PendingIntent pendingIntent2, in Bundle options2, int splitPosition, + float splitRatio, in RemoteTransition remoteTransition, in InstanceId instanceId) = 19; + /** * Blocking call that notifies and gets additional split-screen targets when entering * recents (for example: the dividerBar). @@ -132,4 +147,4 @@ interface ISplitScreen { */ RemoteAnimationTarget[] onStartingSplitLegacy(in RemoteAnimationTarget[] appTargets) = 14; } -// Last id = 17 +// Last id = 19 \ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index cdc8cdd2c28d7..1774dd5e3b6f1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -548,6 +548,24 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, options2, splitPosition, splitRatio, remoteTransition, instanceId); } + private void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, + @Nullable Bundle options1, PendingIntent pendingIntent2, + @Nullable Bundle options2, @SplitPosition int splitPosition, + float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { + Intent fillInIntent1 = null; + Intent fillInIntent2 = null; + if (launchSameComponentAdjacently(pendingIntent1, pendingIntent2) + && supportMultiInstancesSplit(pendingIntent1.getIntent().getComponent())) { + fillInIntent1 = new Intent(); + fillInIntent1.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); + fillInIntent2 = new Intent(); + fillInIntent2.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); + } + mStageCoordinator.startIntentsWithLegacyTransition(pendingIntent1, fillInIntent1, options1, + pendingIntent2, fillInIntent2, options2, splitPosition, splitRatio, adapter, + instanceId); + } + @Override public void startIntent(PendingIntent intent, @Nullable Intent fillInIntent, @SplitPosition int position, @Nullable Bundle options) { @@ -621,6 +639,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return Objects.equals(launchingActivity, pairedActivity); } + private boolean launchSameComponentAdjacently(PendingIntent pendingIntent1, + PendingIntent pendingIntent2) { + return Objects.equals(pendingIntent1.getIntent().getComponent(), + pendingIntent2.getIntent().getComponent()); + } + @VisibleForTesting /** Returns {@code true} if the component supports multi-instances split. */ boolean supportMultiInstancesSplit(@Nullable ComponentName launching) { @@ -985,6 +1009,27 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, instanceId)); } + @Override + public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, + @Nullable Bundle options1, PendingIntent pendingIntent2, @Nullable Bundle options2, + @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, + InstanceId instanceId) { + executeRemoteCallWithTaskPermission(mController, "startIntentsWithLegacyTransition", + (controller) -> + controller.startIntentsWithLegacyTransition( + pendingIntent1, options1, pendingIntent2, options2, splitPosition, + splitRatio, adapter, instanceId) + ); + } + + @Override + public void startIntents(PendingIntent pendingIntent1, @Nullable Bundle options1, + PendingIntent pendingIntent2, @Nullable Bundle options2, + @SplitPosition int splitPosition, float splitRatio, + @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { + // TODO(b/259368992): To be implemented. + } + @Override public void startShortcut(String packageName, String shortcutId, int position, @Nullable Bundle options, UserHandle user, InstanceId instanceId) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index c2ab7ef7e7bff..b9a9d64a4c797 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -588,8 +588,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, /** Starts a pair of tasks using legacy transition. */ void startTasksWithLegacyTransition(int taskId1, @Nullable Bundle options1, int taskId2, @Nullable Bundle options2, @SplitPosition int splitPosition, - float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (options1 == null) options1 = new Bundle(); addActivityOptions(options1, mSideStage); @@ -599,7 +598,20 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, instanceId); } - /** Starts a pair of intent and task using legacy transition. */ + /** Starts a pair of intents using legacy transition. */ + void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, Intent fillInIntent1, + @Nullable Bundle options1, PendingIntent pendingIntent2, Intent fillInIntent2, + @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, + RemoteAnimationAdapter adapter, InstanceId instanceId) { + final WindowContainerTransaction wct = new WindowContainerTransaction(); + if (options1 == null) options1 = new Bundle(); + addActivityOptions(options1, mSideStage); + wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1); + + startWithLegacyTransition(wct, pendingIntent2, fillInIntent2, options2, splitPosition, + splitRatio, adapter, instanceId); + } + void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, @@ -627,12 +639,29 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, instanceId); } + private void startWithLegacyTransition(WindowContainerTransaction wct, + @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent, + @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio, + RemoteAnimationAdapter adapter, InstanceId instanceId) { + startWithLegacyTransition(wct, INVALID_TASK_ID, mainPendingIntent, mainFillInIntent, + mainOptions, sidePosition, splitRatio, adapter, instanceId); + } + + private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId, + @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio, + RemoteAnimationAdapter adapter, InstanceId instanceId) { + startWithLegacyTransition(wct, mainTaskId, null /* mainPendingIntent */, + null /* mainFillInIntent */, mainOptions, sidePosition, splitRatio, adapter, + instanceId); + } + /** * @param wct transaction to start the first task * @param instanceId if {@code null}, will not log. Otherwise it will be used in * {@link SplitscreenEventLogger#logEnter(float, int, int, int, int, boolean)} */ private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId, + @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent, @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { // Init divider first to make divider leash for remote animation target. @@ -701,7 +730,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (mainOptions == null) mainOptions = new Bundle(); addActivityOptions(mainOptions, mMainStage); updateWindowBounds(mSplitLayout, wct); - wct.startTask(mainTaskId, mainOptions); + if (mainTaskId == INVALID_TASK_ID) { + wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, mainOptions); + } else { + wct.startTask(mainTaskId, mainOptions); + } wct.reorder(mRootTaskInfo.token, true); wct.setForceTranslucent(mRootTaskInfo.token, false);