Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl +2 −3 Original line number Diff line number Diff line Loading @@ -97,9 +97,8 @@ interface ISplitScreen { * Start a pair of intent and task using legacy transition system. */ oneway void startIntentAndTaskWithLegacyTransition(in PendingIntent pendingIntent, in Intent fillInIntent, int taskId, boolean intentFirst, in Bundle mainOptions, in Bundle sideOptions, int sidePosition, float splitRatio, in RemoteAnimationAdapter adapter) = 12; in Intent fillInIntent, int taskId, in Bundle mainOptions,in Bundle sideOptions, int sidePosition, float splitRatio, in RemoteAnimationAdapter adapter) = 12; /** * Blocking call that notifies and gets additional split-screen targets when entering Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +4 −5 Original line number Diff line number Diff line Loading @@ -645,14 +645,13 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, @Override public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent, int taskId, boolean intentFirst, Bundle mainOptions, Bundle sideOptions, int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { Intent fillInIntent, int taskId, Bundle mainOptions, Bundle sideOptions, int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { executeRemoteCallWithTaskPermission(mController, "startIntentAndTaskWithLegacyTransition", (controller) -> controller.mStageCoordinator.startIntentAndTaskWithLegacyTransition( pendingIntent, fillInIntent, taskId, intentFirst, mainOptions, sideOptions, sidePosition, splitRatio, adapter)); pendingIntent, fillInIntent, taskId, mainOptions, sideOptions, sidePosition, splitRatio, adapter)); } @Override Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +21 −109 Original line number Diff line number Diff line Loading @@ -373,115 +373,23 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, void startTasksWithLegacyTransition(int mainTaskId, @Nullable Bundle mainOptions, int sideTaskId, @Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { // Init divider first to make divider leash for remote animation target. mSplitLayout.init(); // Set false to avoid record new bounds with old task still on top; mShouldUpdateRecents = false; final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction evictWct = new WindowContainerTransaction(); prepareEvictChildTasks(SPLIT_POSITION_TOP_OR_LEFT, evictWct); prepareEvictChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, evictWct); // Need to add another wrapper here in shell so that we can inject the divider bar // and also manage the process elevation via setRunningRemote IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() { @Override public void onAnimationStart(@WindowManager.TransitionOldType int transit, RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, final IRemoteAnimationFinishedCallback finishedCallback) { mIsDividerRemoteAnimating = true; RemoteAnimationTarget[] augmentedNonApps = new RemoteAnimationTarget[nonApps.length + 1]; for (int i = 0; i < nonApps.length; ++i) { augmentedNonApps[i] = nonApps[i]; } augmentedNonApps[augmentedNonApps.length - 1] = getDividerBarLegacyTarget(); IRemoteAnimationFinishedCallback wrapCallback = new IRemoteAnimationFinishedCallback.Stub() { @Override public void onAnimationFinished() throws RemoteException { mIsDividerRemoteAnimating = false; mShouldUpdateRecents = true; mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); finishedCallback.onAnimationFinished(); } }; try { try { ActivityTaskManager.getService().setRunningRemoteTransitionDelegate( adapter.getCallingApplication()); } catch (SecurityException e) { Slog.e(TAG, "Unable to boost animation thread. This should only happen" + " during unit tests"); } adapter.getRunner().onAnimationStart(transit, apps, wallpapers, augmentedNonApps, wrapCallback); } catch (RemoteException e) { Slog.e(TAG, "Error starting remote animation", e); } } @Override public void onAnimationCancelled() { mIsDividerRemoteAnimating = false; mShouldUpdateRecents = true; mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); try { adapter.getRunner().onAnimationCancelled(); } catch (RemoteException e) { Slog.e(TAG, "Error starting remote animation", e); } } }; RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter( wrapper, adapter.getDuration(), adapter.getStatusBarTransitionDelay()); if (mainOptions == null) { mainOptions = ActivityOptions.makeRemoteAnimation(wrappedAdapter).toBundle(); } else { ActivityOptions mainActivityOptions = ActivityOptions.fromBundle(mainOptions); mainActivityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter)); mainOptions = mainActivityOptions.toBundle(); } sideOptions = sideOptions != null ? sideOptions : new Bundle(); setSideStagePosition(sidePosition, wct); mSplitLayout.setDivideRatio(splitRatio); if (mMainStage.isActive()) { mMainStage.moveToTop(getMainStageBounds(), wct); } else { // Build a request WCT that will launch both apps such that task 0 is on the main stage // while task 1 is on the side stage. mMainStage.activate(getMainStageBounds(), wct, false /* reparent */); } mSideStage.moveToTop(getSideStageBounds(), wct); // Make sure the launch options will put tasks in the corresponding split roots addActivityOptions(mainOptions, mMainStage); addActivityOptions(sideOptions, mSideStage); // Add task launch requests wct.startTask(mainTaskId, mainOptions); wct.startTask(sideTaskId, sideOptions); // Using legacy transitions, so we can't use blast sync since it conflicts. mTaskOrganizer.applyTransaction(wct); mSyncQueue.runInSync(t -> updateSurfaceBounds(mSplitLayout, t)); startWithLegacyTransition(mainTaskId, sideTaskId, null /* pendingIntent */, null /* fillInIntent */, mainOptions, sideOptions, sidePosition, splitRatio, adapter); } /** Start an intent and a task ordered by {@code intentFirst}. */ void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent, int taskId, boolean intentFirst, @Nullable Bundle mainOptions, @Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { // TODO: try pulling the first chunk of this method into a method so that it can be shared // with startTasksWithLegacyTransition. So far attempts to do so result in failure in split. int taskId, @Nullable Bundle mainOptions, @Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { startWithLegacyTransition(taskId, INVALID_TASK_ID, pendingIntent, fillInIntent, mainOptions, sideOptions, sidePosition, splitRatio, adapter); } private void startWithLegacyTransition(int mainTaskId, int sideTaskId, @Nullable PendingIntent pendingIntent, @Nullable Intent fillInIntent, @Nullable Bundle mainOptions, @Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { // Init divider first to make divider leash for remote animation target. mSplitLayout.init(); // Set false to avoid record new bounds with old task still on top; Loading @@ -499,6 +407,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, final IRemoteAnimationFinishedCallback finishedCallback) { mIsDividerRemoteAnimating = true; RemoteAnimationTarget[] augmentedNonApps = new RemoteAnimationTarget[nonApps.length + 1]; for (int i = 0; i < nonApps.length; ++i) { Loading @@ -510,6 +419,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, new IRemoteAnimationFinishedCallback.Stub() { @Override public void onAnimationFinished() throws RemoteException { mIsDividerRemoteAnimating = false; mShouldUpdateRecents = true; mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); Loading @@ -533,6 +443,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Override public void onAnimationCancelled() { mIsDividerRemoteAnimating = false; mShouldUpdateRecents = true; mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); Loading Loading @@ -572,16 +483,17 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, addActivityOptions(sideOptions, mSideStage); // Add task launch requests if (intentFirst) { wct.sendPendingIntent(pendingIntent, fillInIntent, mainOptions); wct.startTask(taskId, sideOptions); } else { wct.startTask(taskId, mainOptions); if (pendingIntent != null && fillInIntent != null) { wct.startTask(mainTaskId, mainOptions); wct.sendPendingIntent(pendingIntent, fillInIntent, sideOptions); } else { wct.startTask(mainTaskId, mainOptions); wct.startTask(sideTaskId, sideOptions); } // Using legacy transitions, so we can't use blast sync since it conflicts. mTaskOrganizer.applyTransaction(wct); mSyncQueue.runInSync(t -> updateSurfaceBounds(mSplitLayout, t)); } /** Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl +2 −3 Original line number Diff line number Diff line Loading @@ -97,9 +97,8 @@ interface ISplitScreen { * Start a pair of intent and task using legacy transition system. */ oneway void startIntentAndTaskWithLegacyTransition(in PendingIntent pendingIntent, in Intent fillInIntent, int taskId, boolean intentFirst, in Bundle mainOptions, in Bundle sideOptions, int sidePosition, float splitRatio, in RemoteAnimationAdapter adapter) = 12; in Intent fillInIntent, int taskId, in Bundle mainOptions,in Bundle sideOptions, int sidePosition, float splitRatio, in RemoteAnimationAdapter adapter) = 12; /** * Blocking call that notifies and gets additional split-screen targets when entering Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +4 −5 Original line number Diff line number Diff line Loading @@ -645,14 +645,13 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, @Override public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent, int taskId, boolean intentFirst, Bundle mainOptions, Bundle sideOptions, int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { Intent fillInIntent, int taskId, Bundle mainOptions, Bundle sideOptions, int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { executeRemoteCallWithTaskPermission(mController, "startIntentAndTaskWithLegacyTransition", (controller) -> controller.mStageCoordinator.startIntentAndTaskWithLegacyTransition( pendingIntent, fillInIntent, taskId, intentFirst, mainOptions, sideOptions, sidePosition, splitRatio, adapter)); pendingIntent, fillInIntent, taskId, mainOptions, sideOptions, sidePosition, splitRatio, adapter)); } @Override Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +21 −109 Original line number Diff line number Diff line Loading @@ -373,115 +373,23 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, void startTasksWithLegacyTransition(int mainTaskId, @Nullable Bundle mainOptions, int sideTaskId, @Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { // Init divider first to make divider leash for remote animation target. mSplitLayout.init(); // Set false to avoid record new bounds with old task still on top; mShouldUpdateRecents = false; final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction evictWct = new WindowContainerTransaction(); prepareEvictChildTasks(SPLIT_POSITION_TOP_OR_LEFT, evictWct); prepareEvictChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, evictWct); // Need to add another wrapper here in shell so that we can inject the divider bar // and also manage the process elevation via setRunningRemote IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() { @Override public void onAnimationStart(@WindowManager.TransitionOldType int transit, RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, final IRemoteAnimationFinishedCallback finishedCallback) { mIsDividerRemoteAnimating = true; RemoteAnimationTarget[] augmentedNonApps = new RemoteAnimationTarget[nonApps.length + 1]; for (int i = 0; i < nonApps.length; ++i) { augmentedNonApps[i] = nonApps[i]; } augmentedNonApps[augmentedNonApps.length - 1] = getDividerBarLegacyTarget(); IRemoteAnimationFinishedCallback wrapCallback = new IRemoteAnimationFinishedCallback.Stub() { @Override public void onAnimationFinished() throws RemoteException { mIsDividerRemoteAnimating = false; mShouldUpdateRecents = true; mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); finishedCallback.onAnimationFinished(); } }; try { try { ActivityTaskManager.getService().setRunningRemoteTransitionDelegate( adapter.getCallingApplication()); } catch (SecurityException e) { Slog.e(TAG, "Unable to boost animation thread. This should only happen" + " during unit tests"); } adapter.getRunner().onAnimationStart(transit, apps, wallpapers, augmentedNonApps, wrapCallback); } catch (RemoteException e) { Slog.e(TAG, "Error starting remote animation", e); } } @Override public void onAnimationCancelled() { mIsDividerRemoteAnimating = false; mShouldUpdateRecents = true; mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); try { adapter.getRunner().onAnimationCancelled(); } catch (RemoteException e) { Slog.e(TAG, "Error starting remote animation", e); } } }; RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter( wrapper, adapter.getDuration(), adapter.getStatusBarTransitionDelay()); if (mainOptions == null) { mainOptions = ActivityOptions.makeRemoteAnimation(wrappedAdapter).toBundle(); } else { ActivityOptions mainActivityOptions = ActivityOptions.fromBundle(mainOptions); mainActivityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter)); mainOptions = mainActivityOptions.toBundle(); } sideOptions = sideOptions != null ? sideOptions : new Bundle(); setSideStagePosition(sidePosition, wct); mSplitLayout.setDivideRatio(splitRatio); if (mMainStage.isActive()) { mMainStage.moveToTop(getMainStageBounds(), wct); } else { // Build a request WCT that will launch both apps such that task 0 is on the main stage // while task 1 is on the side stage. mMainStage.activate(getMainStageBounds(), wct, false /* reparent */); } mSideStage.moveToTop(getSideStageBounds(), wct); // Make sure the launch options will put tasks in the corresponding split roots addActivityOptions(mainOptions, mMainStage); addActivityOptions(sideOptions, mSideStage); // Add task launch requests wct.startTask(mainTaskId, mainOptions); wct.startTask(sideTaskId, sideOptions); // Using legacy transitions, so we can't use blast sync since it conflicts. mTaskOrganizer.applyTransaction(wct); mSyncQueue.runInSync(t -> updateSurfaceBounds(mSplitLayout, t)); startWithLegacyTransition(mainTaskId, sideTaskId, null /* pendingIntent */, null /* fillInIntent */, mainOptions, sideOptions, sidePosition, splitRatio, adapter); } /** Start an intent and a task ordered by {@code intentFirst}. */ void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent, int taskId, boolean intentFirst, @Nullable Bundle mainOptions, @Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { // TODO: try pulling the first chunk of this method into a method so that it can be shared // with startTasksWithLegacyTransition. So far attempts to do so result in failure in split. int taskId, @Nullable Bundle mainOptions, @Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { startWithLegacyTransition(taskId, INVALID_TASK_ID, pendingIntent, fillInIntent, mainOptions, sideOptions, sidePosition, splitRatio, adapter); } private void startWithLegacyTransition(int mainTaskId, int sideTaskId, @Nullable PendingIntent pendingIntent, @Nullable Intent fillInIntent, @Nullable Bundle mainOptions, @Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) { // Init divider first to make divider leash for remote animation target. mSplitLayout.init(); // Set false to avoid record new bounds with old task still on top; Loading @@ -499,6 +407,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, final IRemoteAnimationFinishedCallback finishedCallback) { mIsDividerRemoteAnimating = true; RemoteAnimationTarget[] augmentedNonApps = new RemoteAnimationTarget[nonApps.length + 1]; for (int i = 0; i < nonApps.length; ++i) { Loading @@ -510,6 +419,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, new IRemoteAnimationFinishedCallback.Stub() { @Override public void onAnimationFinished() throws RemoteException { mIsDividerRemoteAnimating = false; mShouldUpdateRecents = true; mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); Loading @@ -533,6 +443,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Override public void onAnimationCancelled() { mIsDividerRemoteAnimating = false; mShouldUpdateRecents = true; mSyncQueue.queue(evictWct); mSyncQueue.runInSync(t -> setDividerVisibility(true, t)); Loading Loading @@ -572,16 +483,17 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, addActivityOptions(sideOptions, mSideStage); // Add task launch requests if (intentFirst) { wct.sendPendingIntent(pendingIntent, fillInIntent, mainOptions); wct.startTask(taskId, sideOptions); } else { wct.startTask(taskId, mainOptions); if (pendingIntent != null && fillInIntent != null) { wct.startTask(mainTaskId, mainOptions); wct.sendPendingIntent(pendingIntent, fillInIntent, sideOptions); } else { wct.startTask(mainTaskId, mainOptions); wct.startTask(sideTaskId, sideOptions); } // Using legacy transitions, so we can't use blast sync since it conflicts. mTaskOrganizer.applyTransaction(wct); mSyncQueue.runInSync(t -> updateSurfaceBounds(mSplitLayout, t)); } /** Loading