summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ivan Makarov <ivanmakarov@google.com> 2022-08-02 11:25:44 +0000
committer Ivan Makarov <ivanmakarov@google.com> 2022-09-08 15:53:06 +0000
commite6bf1d16cb104e2ec4aef84862aa3bd46cf9b6fe (patch)
tree00a6ab168bdcb8d79cfe3d05eed841ff8f74551c
parent915edab656a2fe3bc97e574ca93d7eaa41cc9d8d (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.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java49
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);