1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.wm.shell.splitscreen; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.app.ActivityManager; 23 import android.graphics.Rect; 24 import android.os.Bundle; 25 import android.window.RemoteTransition; 26 27 import com.android.internal.logging.InstanceId; 28 import com.android.wm.shell.shared.annotations.ExternalThread; 29 import com.android.wm.shell.shared.split.SplitScreenConstants.PersistentSnapPosition; 30 import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition; 31 32 import java.util.concurrent.Executor; 33 34 /** 35 * Interface to engage split-screen feature. 36 * TODO: Figure out which of these are actually needed outside of the Shell 37 */ 38 @ExternalThread 39 public interface SplitScreen { 40 /** 41 * Stage type isn't specified normally meaning to use what ever the default is. 42 * E.g. exit split-screen and launch the app in fullscreen. 43 */ 44 int STAGE_TYPE_UNDEFINED = -1; 45 /** 46 * The main stage type. 47 * @see StageTaskListener 48 */ 49 int STAGE_TYPE_MAIN = 0; 50 51 /** 52 * The side stage type. 53 * @see StageTaskListener 54 */ 55 int STAGE_TYPE_SIDE = 1; 56 57 /** 58 * Position independent stage identifier for a given Stage 59 */ 60 int STAGE_TYPE_A = 2; 61 /** 62 * Position independent stage identifier for a given Stage 63 */ 64 int STAGE_TYPE_B = 3; 65 /** 66 * Position independent stage identifier for a given Stage 67 */ 68 int STAGE_TYPE_C = 4; 69 70 @IntDef(prefix = { "STAGE_TYPE_" }, value = { 71 STAGE_TYPE_UNDEFINED, 72 STAGE_TYPE_MAIN, 73 STAGE_TYPE_SIDE, 74 // Used for flexible split 75 STAGE_TYPE_A, 76 STAGE_TYPE_B, 77 STAGE_TYPE_C 78 }) 79 @interface StageType {} 80 81 /** Callback interface for listening to changes in a split-screen stage. */ 82 interface SplitScreenListener { onStagePositionChanged(@tageType int stage, @SplitPosition int position)83 default void onStagePositionChanged(@StageType int stage, @SplitPosition int position) {} onTaskStageChanged(int taskId, @StageType int stage, boolean visible)84 default void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {} onSplitBoundsChanged(Rect rootBounds, Rect mainBounds, Rect sideBounds)85 default void onSplitBoundsChanged(Rect rootBounds, Rect mainBounds, Rect sideBounds) {} onSplitVisibilityChanged(boolean visible)86 default void onSplitVisibilityChanged(boolean visible) {} 87 } 88 89 /** 90 * Callback interface for listening to requests to enter split select. Used for desktop -> split 91 */ 92 interface SplitSelectListener { onRequestEnterSplitSelect(ActivityManager.RunningTaskInfo taskInfo, int splitPosition, Rect taskBounds)93 default boolean onRequestEnterSplitSelect(ActivityManager.RunningTaskInfo taskInfo, 94 int splitPosition, Rect taskBounds) { 95 return false; 96 } 97 } 98 99 /** Launches a pair of tasks into splitscreen */ startTasks(int taskId1, @Nullable Bundle options1, int taskId2, @Nullable Bundle options2, @SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, InstanceId instanceId)100 void startTasks(int taskId1, @Nullable Bundle options1, int taskId2, 101 @Nullable Bundle options2, @SplitPosition int splitPosition, 102 @PersistentSnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, 103 InstanceId instanceId); 104 105 /** Registers listener that gets split screen callback. */ registerSplitScreenListener(@onNull SplitScreenListener listener, @NonNull Executor executor)106 void registerSplitScreenListener(@NonNull SplitScreenListener listener, 107 @NonNull Executor executor); 108 109 /** Unregisters listener that gets split screen callback. */ unregisterSplitScreenListener(@onNull SplitScreenListener listener)110 void unregisterSplitScreenListener(@NonNull SplitScreenListener listener); 111 112 interface SplitInvocationListener { 113 /** 114 * Called whenever shell starts or stops the split screen animation 115 * @param animationRunning if {@code true} the animation has begun, if {@code false} the 116 * animation has finished 117 */ onSplitAnimationInvoked(boolean animationRunning)118 default void onSplitAnimationInvoked(boolean animationRunning) { } 119 } 120 121 /** 122 * Registers a {@link SplitInvocationListener} to notify when the animation to enter split 123 * screen has started and stopped 124 * 125 * @param executor callbacks to the listener will be executed on this executor 126 */ registerSplitAnimationListener(@onNull SplitInvocationListener listener, @NonNull Executor executor)127 void registerSplitAnimationListener(@NonNull SplitInvocationListener listener, 128 @NonNull Executor executor); 129 130 /** Called when device starts going to sleep (screen off). */ onStartedGoingToSleep()131 void onStartedGoingToSleep(); 132 133 /** Called when device wakes up. */ onStartedWakingUp()134 void onStartedWakingUp(); 135 136 /** Called when requested to go to fullscreen from the current active split app. */ goToFullscreenFromSplit()137 void goToFullscreenFromSplit(); 138 139 /** Called when splitscreen focused app is changed. */ setSplitscreenFocus(boolean leftOrTop)140 void setSplitscreenFocus(boolean leftOrTop); 141 142 /** Get a string representation of a stage type */ stageTypeToString(@tageType int stage)143 static String stageTypeToString(@StageType int stage) { 144 switch (stage) { 145 case STAGE_TYPE_UNDEFINED: return "UNDEFINED"; 146 case STAGE_TYPE_MAIN: return "MAIN"; 147 case STAGE_TYPE_SIDE: return "SIDE"; 148 case STAGE_TYPE_A: return "STAGE_A"; 149 case STAGE_TYPE_B: return "STAGE_B"; 150 case STAGE_TYPE_C: return "STAGE_C"; 151 default: return "UNKNOWN(" + stage + ")"; 152 } 153 } 154 } 155