diff options
| author | 2022-08-02 11:25:44 +0000 | |
|---|---|---|
| committer | 2022-09-08 15:53:06 +0000 | |
| commit | e6bf1d16cb104e2ec4aef84862aa3bd46cf9b6fe (patch) | |
| tree | 00a6ab168bdcb8d79cfe3d05eed841ff8f74551c | |
| parent | 915edab656a2fe3bc97e574ca93d7eaa41cc9d8d (diff) | |
Add TV splitscreen menu
Add a splitscreen menu for TV allowing to change the focused task, swap
the stages and exit the splitscreen mode by closing one of the stages.
Bug: 242179031
Test: Enter the splitscreen mode. Send the corresponding broadcast to open the menu (adb shell am
broadcast -a com.android.wm.shell.splitscreen.SHOW_MENU). Choose the needed action button and press it, open the menu again, etc. Press the back button on the
menu control to hide the menu window.
Change-Id: Iac17445414a190c91ccd407d67f0f8c29d6bd4bf
Merged-In: Iac17445414a190c91ccd407d67f0f8c29d6bd4bf
(cherry picked from commit 7ab2a40d0a48cc8d80a448893edf1293f8f6bb9c)
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java | 12 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java | 49 |
2 files changed, 56 insertions, 5 deletions
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 169e17b770f3..872916197854 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 @@ -213,14 +213,18 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, mShellController.addKeyguardChangeListener(this); if (mStageCoordinator == null) { // TODO: Multi-display - mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue, - mTaskOrganizer, mDisplayController, mDisplayImeController, - mDisplayInsetsController, mTransitions, mTransactionPool, mLogger, - mIconProvider, mMainExecutor, mRecentTasksOptional); + mStageCoordinator = createStageCoordinator(); } mDragAndDropController.setSplitScreenController(this); } + protected StageCoordinator createStageCoordinator() { + return new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue, + mTaskOrganizer, mDisplayController, mDisplayImeController, + mDisplayInsetsController, mTransitions, mTransactionPool, mLogger, + mIconProvider, mMainExecutor, mRecentTasksOptional); + } + @Override public Context getContext() { return mContext; 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 dcfe08d7a329..f8b40be6928a 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 @@ -69,6 +69,7 @@ import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; +import android.app.IActivityTaskManager; import android.app.PendingIntent; import android.app.WindowConfiguration; import android.content.Context; @@ -81,6 +82,7 @@ import android.os.Bundle; import android.os.Debug; import android.os.IBinder; import android.os.RemoteException; +import android.os.ServiceManager; import android.util.Log; import android.util.Slog; import android.view.Choreographer; @@ -244,7 +246,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } }; - StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue, + protected StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue, ShellTaskOrganizer taskOrganizer, DisplayController displayController, DisplayImeController displayImeController, DisplayInsetsController displayInsetsController, Transitions transitions, @@ -880,6 +882,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, WindowContainerTransaction wct, @ExitReason int exitReason) { if (!mMainStage.isActive() || mIsExiting) return; + onSplitScreenExit(); + mRecentTasks.ifPresent(recentTasks -> { // Notify recents if we are exiting in a way that breaks the pair, and disable further // updates to splits in the recents until we enter split again @@ -949,6 +953,47 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } /** + * Overridden by child classes. + */ + protected void onSplitScreenEnter() { + } + + /** + * Overridden by child classes. + */ + protected void onSplitScreenExit() { + } + + /** + * Exits the split screen by finishing one of the tasks. + */ + protected void exitStage(@SplitPosition int stageToClose) { + if (ENABLE_SHELL_TRANSITIONS) { + StageTaskListener stageToTop = mSideStagePosition == stageToClose + ? mMainStage + : mSideStage; + exitSplitScreen(stageToTop, EXIT_REASON_APP_FINISHED); + } else { + boolean toEnd = stageToClose == SPLIT_POSITION_BOTTOM_OR_RIGHT; + mSplitLayout.flingDividerToDismiss(toEnd, EXIT_REASON_APP_FINISHED); + } + } + + /** + * Grants focus to the main or the side stages. + */ + protected void grantFocusToStage(@SplitPosition int stageToFocus) { + IActivityTaskManager activityTaskManagerService = IActivityTaskManager.Stub.asInterface( + ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE)); + try { + activityTaskManagerService.setFocusedTask(getTaskId(stageToFocus)); + } catch (RemoteException | NullPointerException e) { + ProtoLog.e(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "%s: Unable to update focus on the chosen stage, %s", TAG, e); + } + } + + /** * Returns whether the split pair in the recent tasks list should be broken. */ private boolean shouldBreakPairedTaskInRecents(@ExitReason int exitReason) { @@ -995,6 +1040,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) { if (mMainStage.isActive()) return; + onSplitScreenEnter(); if (taskInfo != null) { setSideStagePosition(startPosition, wct); mSideStage.addTask(taskInfo, wct); @@ -1388,6 +1434,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } else if (isSideStage && hasChildren && !mMainStage.isActive()) { // TODO (b/238697912) : Add the validation to prevent entering non-recovered status + onSplitScreenEnter(); final WindowContainerTransaction wct = new WindowContainerTransaction(); mSplitLayout.init(); mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT); |