5/ Fix inverted dependency for ShellCommandHandler
- Instead of ShellCommandHandler referencing the controllers that it needs to dump/call on, invert it so that controllers register a dump/command callback when they are initialized Test: atest WMShellUnitTests Test: atest SystemUITests Test: adb shell dumpsys activity service SystemUIservice WMShell Test: adb shell dumpsys activity service SystemUIservice WMShell splitscreen <cmd> Test: adb shell dumpsys activity service SystemUIservice WMShell help Bug: 238217847 Change-Id: I673e5f7dd11ed7af326d52da8e793356169f1d8f
This commit is contained in:
@@ -55,6 +55,7 @@ import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.compatui.CompatUIController;
|
||||
import com.android.wm.shell.recents.RecentTasksController;
|
||||
import com.android.wm.shell.startingsurface.StartingWindowController;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.unfold.UnfoldAnimationController;
|
||||
|
||||
@@ -72,6 +73,7 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public class ShellTaskOrganizer extends TaskOrganizer implements
|
||||
CompatUIController.CompatUICallback {
|
||||
private static final String TAG = "ShellTaskOrganizer";
|
||||
|
||||
// Intentionally using negative numbers here so the positive numbers can be used
|
||||
// for task id specific listeners that will be added later.
|
||||
@@ -90,8 +92,6 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
|
||||
})
|
||||
public @interface TaskListenerType {}
|
||||
|
||||
private static final String TAG = "ShellTaskOrganizer";
|
||||
|
||||
/**
|
||||
* Callbacks for when the tasks change in the system.
|
||||
*/
|
||||
@@ -177,6 +177,9 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
|
||||
@Nullable
|
||||
private final CompatUIController mCompatUI;
|
||||
|
||||
@NonNull
|
||||
private final ShellCommandHandler mShellCommandHandler;
|
||||
|
||||
@Nullable
|
||||
private final Optional<RecentTasksController> mRecentTasks;
|
||||
|
||||
@@ -187,29 +190,33 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
|
||||
private RunningTaskInfo mLastFocusedTaskInfo;
|
||||
|
||||
public ShellTaskOrganizer(ShellExecutor mainExecutor) {
|
||||
this(null /* shellInit */, null /* taskOrganizerController */, null /* compatUI */,
|
||||
this(null /* shellInit */, null /* shellCommandHandler */,
|
||||
null /* taskOrganizerController */, null /* compatUI */,
|
||||
Optional.empty() /* unfoldAnimationController */,
|
||||
Optional.empty() /* recentTasksController */,
|
||||
mainExecutor);
|
||||
}
|
||||
|
||||
public ShellTaskOrganizer(ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
@Nullable CompatUIController compatUI,
|
||||
Optional<UnfoldAnimationController> unfoldAnimationController,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
ShellExecutor mainExecutor) {
|
||||
this(shellInit, null /* taskOrganizerController */, compatUI,
|
||||
this(shellInit, shellCommandHandler, null /* taskOrganizerController */, compatUI,
|
||||
unfoldAnimationController, recentTasks, mainExecutor);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected ShellTaskOrganizer(ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ITaskOrganizerController taskOrganizerController,
|
||||
@Nullable CompatUIController compatUI,
|
||||
Optional<UnfoldAnimationController> unfoldAnimationController,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
ShellExecutor mainExecutor) {
|
||||
super(taskOrganizerController, mainExecutor);
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mCompatUI = compatUI;
|
||||
mRecentTasks = recentTasks;
|
||||
mUnfoldAnimationController = unfoldAnimationController.orElse(null);
|
||||
@@ -219,6 +226,7 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
|
||||
}
|
||||
|
||||
private void onInit() {
|
||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||
if (mCompatUI != null) {
|
||||
mCompatUI.setCompatUICallback(this);
|
||||
}
|
||||
|
||||
@@ -174,13 +174,14 @@ public abstract class WMShellBaseModule {
|
||||
@Provides
|
||||
static ShellTaskOrganizer provideShellTaskOrganizer(
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
CompatUIController compatUI,
|
||||
Optional<UnfoldAnimationController> unfoldAnimationController,
|
||||
Optional<RecentTasksController> recentTasksOptional,
|
||||
@ShellMainThread ShellExecutor mainExecutor
|
||||
) {
|
||||
return new ShellTaskOrganizer(shellInit, compatUI, unfoldAnimationController,
|
||||
recentTasksOptional, mainExecutor);
|
||||
return new ShellTaskOrganizer(shellInit, shellCommandHandler, compatUI,
|
||||
unfoldAnimationController, recentTasksOptional, mainExecutor);
|
||||
}
|
||||
|
||||
@WMSingleton
|
||||
@@ -188,6 +189,7 @@ public abstract class WMShellBaseModule {
|
||||
static KidsModeTaskOrganizer provideKidsModeTaskOrganizer(
|
||||
Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
SyncTransactionQueue syncTransactionQueue,
|
||||
DisplayController displayController,
|
||||
DisplayInsetsController displayInsetsController,
|
||||
@@ -196,9 +198,9 @@ public abstract class WMShellBaseModule {
|
||||
@ShellMainThread ShellExecutor mainExecutor,
|
||||
@ShellMainThread Handler mainHandler
|
||||
) {
|
||||
return new KidsModeTaskOrganizer(context, shellInit, syncTransactionQueue,
|
||||
displayController, displayInsetsController, unfoldAnimationController,
|
||||
recentTasksOptional, mainExecutor, mainHandler);
|
||||
return new KidsModeTaskOrganizer(context, shellInit, shellCommandHandler,
|
||||
syncTransactionQueue, displayController, displayInsetsController,
|
||||
unfoldAnimationController, recentTasksOptional, mainExecutor, mainHandler);
|
||||
}
|
||||
|
||||
@WMSingleton
|
||||
@@ -388,12 +390,13 @@ public abstract class WMShellBaseModule {
|
||||
@Provides
|
||||
static Optional<HideDisplayCutoutController> provideHideDisplayCutoutController(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
DisplayController displayController,
|
||||
@ShellMainThread ShellExecutor mainExecutor) {
|
||||
return Optional.ofNullable(
|
||||
HideDisplayCutoutController.create(context, shellInit, shellController,
|
||||
displayController, mainExecutor));
|
||||
HideDisplayCutoutController.create(context, shellInit, shellCommandHandler,
|
||||
shellController, displayController, mainExecutor));
|
||||
}
|
||||
|
||||
//
|
||||
@@ -471,12 +474,13 @@ public abstract class WMShellBaseModule {
|
||||
static Optional<RecentTasksController> provideRecentTasksController(
|
||||
Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
TaskStackListenerImpl taskStackListener,
|
||||
@ShellMainThread ShellExecutor mainExecutor
|
||||
) {
|
||||
return Optional.ofNullable(
|
||||
RecentTasksController.create(context, shellInit, taskStackListener,
|
||||
mainExecutor));
|
||||
RecentTasksController.create(context, shellInit, shellCommandHandler,
|
||||
taskStackListener, mainExecutor));
|
||||
}
|
||||
|
||||
//
|
||||
@@ -654,8 +658,9 @@ public abstract class WMShellBaseModule {
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static ShellController provideShellController(ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
@ShellMainThread ShellExecutor mainExecutor) {
|
||||
return new ShellController(shellInit, mainExecutor);
|
||||
return new ShellController(shellInit, shellCommandHandler, mainExecutor);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -681,12 +686,15 @@ public abstract class WMShellBaseModule {
|
||||
KidsModeTaskOrganizer kidsModeTaskOrganizer,
|
||||
Optional<BubbleController> bubblesOptional,
|
||||
Optional<SplitScreenController> splitScreenOptional,
|
||||
Optional<Pip> pipOptional,
|
||||
Optional<PipTouchHandler> pipTouchHandlerOptional,
|
||||
FullscreenTaskListener fullscreenTaskListener,
|
||||
Optional<UnfoldAnimationController> unfoldAnimationController,
|
||||
Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
|
||||
Optional<FreeformComponents> freeformComponents,
|
||||
Optional<RecentTasksController> recentTasksOptional,
|
||||
Optional<OneHandedController> oneHandedControllerOptional,
|
||||
Optional<HideDisplayCutoutController> hideDisplayCutoutControllerOptional,
|
||||
ActivityEmbeddingController activityEmbeddingOptional,
|
||||
Transitions transitions,
|
||||
StartingWindowController startingWindow,
|
||||
@@ -702,18 +710,7 @@ public abstract class WMShellBaseModule {
|
||||
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static ShellCommandHandler provideShellCommandHandlerImpl(
|
||||
ShellController shellController,
|
||||
ShellTaskOrganizer shellTaskOrganizer,
|
||||
KidsModeTaskOrganizer kidsModeTaskOrganizer,
|
||||
Optional<SplitScreenController> splitScreenOptional,
|
||||
Optional<Pip> pipOptional,
|
||||
Optional<OneHandedController> oneHandedOptional,
|
||||
Optional<HideDisplayCutoutController> hideDisplayCutout,
|
||||
Optional<RecentTasksController> recentTasksOptional,
|
||||
@ShellMainThread ShellExecutor mainExecutor) {
|
||||
return new ShellCommandHandler(shellController, shellTaskOrganizer,
|
||||
kidsModeTaskOrganizer, splitScreenOptional, pipOptional, oneHandedOptional,
|
||||
hideDisplayCutout, recentTasksOptional, mainExecutor);
|
||||
static ShellCommandHandler provideShellCommandHandler() {
|
||||
return new ShellCommandHandler();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ import com.android.wm.shell.pip.phone.PipMotionHelper;
|
||||
import com.android.wm.shell.pip.phone.PipTouchHandler;
|
||||
import com.android.wm.shell.recents.RecentTasksController;
|
||||
import com.android.wm.shell.splitscreen.SplitScreenController;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.transition.SplitscreenPipMixedHandler;
|
||||
@@ -249,6 +250,7 @@ public abstract class WMShellModule {
|
||||
@DynamicOverride
|
||||
static OneHandedController provideOneHandedController(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
WindowManager windowManager,
|
||||
DisplayController displayController,
|
||||
@@ -258,9 +260,9 @@ public abstract class WMShellModule {
|
||||
InteractionJankMonitor jankMonitor,
|
||||
@ShellMainThread ShellExecutor mainExecutor,
|
||||
@ShellMainThread Handler mainHandler) {
|
||||
return OneHandedController.create(context, shellInit, shellController, windowManager,
|
||||
displayController, displayLayout, taskStackListener, jankMonitor, uiEventLogger,
|
||||
mainExecutor, mainHandler);
|
||||
return OneHandedController.create(context, shellInit, shellCommandHandler, shellController,
|
||||
windowManager, displayController, displayLayout, taskStackListener, jankMonitor,
|
||||
uiEventLogger, mainExecutor, mainHandler);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -273,6 +275,7 @@ public abstract class WMShellModule {
|
||||
static SplitScreenController provideSplitScreenController(
|
||||
Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
ShellTaskOrganizer shellTaskOrganizer,
|
||||
SyncTransactionQueue syncQueue,
|
||||
@@ -286,10 +289,10 @@ public abstract class WMShellModule {
|
||||
IconProvider iconProvider,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
@ShellMainThread ShellExecutor mainExecutor) {
|
||||
return new SplitScreenController(context, shellInit, shellController, shellTaskOrganizer,
|
||||
syncQueue, rootTaskDisplayAreaOrganizer, displayController, displayImeController,
|
||||
displayInsetsController, dragAndDropController, transitions, transactionPool,
|
||||
iconProvider, recentTasks, mainExecutor);
|
||||
return new SplitScreenController(context, shellInit, shellCommandHandler, shellController,
|
||||
shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer, displayController,
|
||||
displayImeController, displayInsetsController, dragAndDropController, transitions,
|
||||
transactionPool, iconProvider, recentTasks, mainExecutor);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -298,20 +301,29 @@ public abstract class WMShellModule {
|
||||
|
||||
@WMSingleton
|
||||
@Provides
|
||||
static Optional<Pip> providePip(Context context, ShellInit shellInit,
|
||||
ShellController shellController, DisplayController displayController,
|
||||
PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
|
||||
PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState,
|
||||
PipMotionHelper pipMotionHelper, PipMediaController pipMediaController,
|
||||
PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
|
||||
static Optional<Pip> providePip(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
DisplayController displayController,
|
||||
PipAppOpsListener pipAppOpsListener,
|
||||
PipBoundsAlgorithm pipBoundsAlgorithm,
|
||||
PipKeepClearAlgorithm pipKeepClearAlgorithm,
|
||||
PipBoundsState pipBoundsState,
|
||||
PipMotionHelper pipMotionHelper,
|
||||
PipMediaController pipMediaController,
|
||||
PhonePipMenuController phonePipMenuController,
|
||||
PipTaskOrganizer pipTaskOrganizer,
|
||||
PipTransitionState pipTransitionState,
|
||||
PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
|
||||
PipTouchHandler pipTouchHandler,
|
||||
PipTransitionController pipTransitionController,
|
||||
WindowManagerShellWrapper windowManagerShellWrapper,
|
||||
TaskStackListenerImpl taskStackListener,
|
||||
PipParamsChangedForwarder pipParamsChangedForwarder,
|
||||
Optional<OneHandedController> oneHandedController,
|
||||
@ShellMainThread ShellExecutor mainExecutor) {
|
||||
return Optional.ofNullable(PipController.create(context, shellInit, shellController,
|
||||
return Optional.ofNullable(PipController.create(
|
||||
context, shellInit, shellCommandHandler, shellController,
|
||||
displayController, pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm,
|
||||
pipBoundsState, pipMotionHelper, pipMediaController, phonePipMenuController,
|
||||
pipTaskOrganizer, pipTransitionState, pipTouchHandler, pipTransitionController,
|
||||
|
||||
@@ -59,9 +59,9 @@ WMShell SysUI service:
|
||||
adb shell dumpsys activity service SystemUIService WMShell
|
||||
```
|
||||
|
||||
If information should be added to the dump, make updates to:
|
||||
- `WMShell` if you are dumping SysUI state
|
||||
- `ShellCommandHandler` if you are dumping Shell state
|
||||
If information should be added to the dump, either:
|
||||
- Update `WMShell` if you are dumping SysUI state
|
||||
- Inject `ShellCommandHandler` into your Shell class, and add a dump callback
|
||||
|
||||
## Debugging in Android Studio
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ interfaces provided by the Shell and the rest of SystemUI.
|
||||
|
||||
More detail can be found in [go/wm-sysui-dagger](http://go/wm-sysui-dagger).
|
||||
|
||||
## Interfaces to Shell components
|
||||
## Interfaces from SysUI to Shell components
|
||||
|
||||
Within the same process, the WM Shell components can be running on a different thread than the main
|
||||
SysUI thread (disabled on certain products). This introduces challenges where we have to be
|
||||
@@ -54,12 +54,30 @@ For example, you might have:
|
||||
Adding an interface to a Shell component may seem like a lot of boiler plate, but is currently
|
||||
necessary to maintain proper threading and logic isolation.
|
||||
|
||||
## Configuration changes & other SysUI events
|
||||
## Listening for Configuration changes & other SysUI events
|
||||
|
||||
Aside from direct calls into Shell controllers for exposed features, the Shell also receives
|
||||
Aside from direct calls into Shell controllers for exposed features, the Shell also receives
|
||||
common event callbacks from SysUI via the `ShellController`. This includes things like:
|
||||
|
||||
- Configuration changes
|
||||
- TODO: Shell init
|
||||
- TODO: Shell command
|
||||
- TODO: Keyguard events
|
||||
- Keyguard events
|
||||
- Shell init
|
||||
- Shell dumps & commands
|
||||
|
||||
For other events which are specific to the Shell feature, then you can add callback methods on
|
||||
the Shell feature interface. Any such calls should <u>**never**</u> be synchronous calls as
|
||||
they will need to post to the Shell main thread to run.
|
||||
|
||||
## Shell commands & Dumps
|
||||
|
||||
Since the Shell library is a part of the SysUI process, it relies on SysUI to trigger commands
|
||||
on individual Shell components, or to dump individual shell components.
|
||||
|
||||
```shell
|
||||
# Dump everything
|
||||
adb shell dumpsys activity service SystemUIService WMShell
|
||||
|
||||
# Run a specific command
|
||||
adb shell dumpsys activity service SystemUIService WMShell help
|
||||
adb shell dumpsys activity service SystemUIService WMShell <cmd> <args> ...
|
||||
```
|
||||
@@ -27,6 +27,7 @@ import androidx.annotation.VisibleForTesting;
|
||||
import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.sysui.ConfigurationChangeListener;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
|
||||
@@ -39,6 +40,7 @@ public class HideDisplayCutoutController implements ConfigurationChangeListener
|
||||
private static final String TAG = "HideDisplayCutoutController";
|
||||
|
||||
private final Context mContext;
|
||||
private final ShellCommandHandler mShellCommandHandler;
|
||||
private final ShellController mShellController;
|
||||
private final HideDisplayCutoutOrganizer mOrganizer;
|
||||
@VisibleForTesting
|
||||
@@ -51,6 +53,7 @@ public class HideDisplayCutoutController implements ConfigurationChangeListener
|
||||
@Nullable
|
||||
public static HideDisplayCutoutController create(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
DisplayController displayController,
|
||||
ShellExecutor mainExecutor) {
|
||||
@@ -63,20 +66,24 @@ public class HideDisplayCutoutController implements ConfigurationChangeListener
|
||||
|
||||
HideDisplayCutoutOrganizer organizer =
|
||||
new HideDisplayCutoutOrganizer(context, displayController, mainExecutor);
|
||||
return new HideDisplayCutoutController(context, shellInit, shellController, organizer);
|
||||
return new HideDisplayCutoutController(context, shellInit, shellCommandHandler,
|
||||
shellController, organizer);
|
||||
}
|
||||
|
||||
HideDisplayCutoutController(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
HideDisplayCutoutOrganizer organizer) {
|
||||
mContext = context;
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mShellController = shellController;
|
||||
mOrganizer = organizer;
|
||||
shellInit.addInitCallback(this::onInit, this);
|
||||
}
|
||||
|
||||
private void onInit() {
|
||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||
updateStatus();
|
||||
mShellController.addConfigurationChangeListener(this);
|
||||
}
|
||||
@@ -105,11 +112,11 @@ public class HideDisplayCutoutController implements ConfigurationChangeListener
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
public void dump(@NonNull PrintWriter pw) {
|
||||
final String prefix = " ";
|
||||
public void dump(@NonNull PrintWriter pw, String prefix) {
|
||||
final String innerPrefix = " ";
|
||||
pw.print(TAG);
|
||||
pw.println(" states: ");
|
||||
pw.print(prefix);
|
||||
pw.print(innerPrefix);
|
||||
pw.print("mEnabled=");
|
||||
pw.println(mEnabled);
|
||||
mOrganizer.dump(pw);
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.android.wm.shell.common.DisplayLayout;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.recents.RecentTasksController;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.unfold.UnfoldAnimationController;
|
||||
|
||||
@@ -73,6 +74,7 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer {
|
||||
|
||||
private final Handler mMainHandler;
|
||||
private final Context mContext;
|
||||
private final ShellCommandHandler mShellCommandHandler;
|
||||
private final SyncTransactionQueue mSyncQueue;
|
||||
private final DisplayController mDisplayController;
|
||||
private final DisplayInsetsController mDisplayInsetsController;
|
||||
@@ -141,6 +143,8 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer {
|
||||
@VisibleForTesting
|
||||
KidsModeTaskOrganizer(
|
||||
Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ITaskOrganizerController taskOrganizerController,
|
||||
SyncTransactionQueue syncTransactionQueue,
|
||||
DisplayController displayController,
|
||||
@@ -150,19 +154,23 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer {
|
||||
KidsModeSettingsObserver kidsModeSettingsObserver,
|
||||
ShellExecutor mainExecutor,
|
||||
Handler mainHandler) {
|
||||
super(/* shellInit= */ null, taskOrganizerController, /* compatUI= */ null,
|
||||
unfoldAnimationController, recentTasks, mainExecutor);
|
||||
// Note: we don't call super with the shell init because we will be initializing manually
|
||||
super(/* shellInit= */ null, /* shellCommandHandler= */ null, taskOrganizerController,
|
||||
/* compatUI= */ null, unfoldAnimationController, recentTasks, mainExecutor);
|
||||
mContext = context;
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mMainHandler = mainHandler;
|
||||
mSyncQueue = syncTransactionQueue;
|
||||
mDisplayController = displayController;
|
||||
mDisplayInsetsController = displayInsetsController;
|
||||
mKidsModeSettingsObserver = kidsModeSettingsObserver;
|
||||
shellInit.addInitCallback(this::onInit, this);
|
||||
}
|
||||
|
||||
public KidsModeTaskOrganizer(
|
||||
Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
SyncTransactionQueue syncTransactionQueue,
|
||||
DisplayController displayController,
|
||||
DisplayInsetsController displayInsetsController,
|
||||
@@ -171,9 +179,10 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer {
|
||||
ShellExecutor mainExecutor,
|
||||
Handler mainHandler) {
|
||||
// Note: we don't call super with the shell init because we will be initializing manually
|
||||
super(/* shellInit= */ null, /* compatUI= */ null, unfoldAnimationController, recentTasks,
|
||||
mainExecutor);
|
||||
super(/* shellInit= */ null, /* taskOrganizerController= */ null, /* compatUI= */ null,
|
||||
unfoldAnimationController, recentTasks, mainExecutor);
|
||||
mContext = context;
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mMainHandler = mainHandler;
|
||||
mSyncQueue = syncTransactionQueue;
|
||||
mDisplayController = displayController;
|
||||
@@ -185,6 +194,9 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer {
|
||||
* Initializes kids mode status.
|
||||
*/
|
||||
public void onInit() {
|
||||
if (mShellCommandHandler != null) {
|
||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||
}
|
||||
if (mKidsModeSettingsObserver == null) {
|
||||
mKidsModeSettingsObserver = new KidsModeSettingsObserver(mMainHandler, mContext);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import com.android.wm.shell.common.TaskStackListenerImpl;
|
||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||
import com.android.wm.shell.sysui.ConfigurationChangeListener;
|
||||
import com.android.wm.shell.sysui.KeyguardChangeListener;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
|
||||
@@ -86,6 +87,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private final ShellCommandHandler mShellCommandHandler;
|
||||
private final ShellController mShellController;
|
||||
private final AccessibilityManager mAccessibilityManager;
|
||||
private final DisplayController mDisplayController;
|
||||
@@ -194,7 +196,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
||||
* Creates {@link OneHandedController}, returns {@code null} if the feature is not supported.
|
||||
*/
|
||||
public static OneHandedController create(Context context,
|
||||
ShellInit shellInit, ShellController shellController, WindowManager windowManager,
|
||||
ShellInit shellInit, ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController, WindowManager windowManager,
|
||||
DisplayController displayController, DisplayLayout displayLayout,
|
||||
TaskStackListenerImpl taskStackListener,
|
||||
InteractionJankMonitor jankMonitor, UiEventLogger uiEventLogger,
|
||||
@@ -214,15 +217,16 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
||||
context, displayLayout, settingsUtil, animationController, tutorialHandler,
|
||||
jankMonitor, mainExecutor);
|
||||
OneHandedUiEventLogger oneHandedUiEventsLogger = new OneHandedUiEventLogger(uiEventLogger);
|
||||
return new OneHandedController(context, shellInit, shellController, displayController,
|
||||
organizer, touchHandler, tutorialHandler, settingsUtil, accessibilityUtil,
|
||||
timeoutHandler, oneHandedState, oneHandedUiEventsLogger, taskStackListener,
|
||||
mainExecutor, mainHandler);
|
||||
return new OneHandedController(context, shellInit, shellCommandHandler, shellController,
|
||||
displayController, organizer, touchHandler, tutorialHandler, settingsUtil,
|
||||
accessibilityUtil, timeoutHandler, oneHandedState, oneHandedUiEventsLogger,
|
||||
taskStackListener, mainExecutor, mainHandler);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
OneHandedController(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
DisplayController displayController,
|
||||
OneHandedDisplayAreaOrganizer displayAreaOrganizer,
|
||||
@@ -237,6 +241,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
||||
ShellExecutor mainExecutor,
|
||||
Handler mainHandler) {
|
||||
mContext = context;
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mShellController = shellController;
|
||||
mOneHandedSettingsUtil = settingsUtil;
|
||||
mOneHandedAccessibilityUtil = oneHandedAccessibilityUtil;
|
||||
@@ -274,6 +279,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
||||
}
|
||||
|
||||
private void onInit() {
|
||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||
mDisplayController.addDisplayWindowListener(mDisplaysChangedListener);
|
||||
mDisplayController.addDisplayChangingController(this);
|
||||
setupCallback();
|
||||
@@ -629,7 +635,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>,
|
||||
updateOneHandedEnabled();
|
||||
}
|
||||
|
||||
public void dump(@NonNull PrintWriter pw) {
|
||||
public void dump(@NonNull PrintWriter pw, String prefix) {
|
||||
final String innerPrefix = " ";
|
||||
pw.println();
|
||||
pw.println(TAG);
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.graphics.Rect;
|
||||
|
||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -99,12 +98,4 @@ public interface Pip {
|
||||
* view hierarchy or destroyed.
|
||||
*/
|
||||
default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { }
|
||||
|
||||
/**
|
||||
* Dump the current state and information if need.
|
||||
*
|
||||
* @param pw The stream to dump information to.
|
||||
*/
|
||||
default void dump(PrintWriter pw) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ import com.android.wm.shell.pip.PipUtils;
|
||||
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||
import com.android.wm.shell.sysui.ConfigurationChangeListener;
|
||||
import com.android.wm.shell.sysui.KeyguardChangeListener;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
@@ -123,6 +124,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
private TaskStackListenerImpl mTaskStackListener;
|
||||
private PipParamsChangedForwarder mPipParamsChangedForwarder;
|
||||
private Optional<OneHandedController> mOneHandedController;
|
||||
private final ShellCommandHandler mShellCommandHandler;
|
||||
private final ShellController mShellController;
|
||||
protected final PipImpl mImpl;
|
||||
|
||||
@@ -297,6 +299,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
@Nullable
|
||||
public static Pip create(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
DisplayController displayController,
|
||||
PipAppOpsListener pipAppOpsListener,
|
||||
@@ -321,10 +324,10 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
return null;
|
||||
}
|
||||
|
||||
return new PipController(context, shellInit, shellController, displayController,
|
||||
pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState,
|
||||
pipMotionHelper, pipMediaController, phonePipMenuController, pipTaskOrganizer,
|
||||
pipTransitionState, pipTouchHandler, pipTransitionController,
|
||||
return new PipController(context, shellInit, shellCommandHandler, shellController,
|
||||
displayController, pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm,
|
||||
pipBoundsState, pipMotionHelper, pipMediaController, phonePipMenuController,
|
||||
pipTaskOrganizer, pipTransitionState, pipTouchHandler, pipTransitionController,
|
||||
windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder,
|
||||
oneHandedController, mainExecutor)
|
||||
.mImpl;
|
||||
@@ -332,6 +335,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
|
||||
protected PipController(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
DisplayController displayController,
|
||||
PipAppOpsListener pipAppOpsListener,
|
||||
@@ -358,6 +362,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
}
|
||||
|
||||
mContext = context;
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mShellController = shellController;
|
||||
mImpl = new PipImpl();
|
||||
mWindowManagerShellWrapper = windowManagerShellWrapper;
|
||||
@@ -385,6 +390,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
}
|
||||
|
||||
private void onInit() {
|
||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||
mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(),
|
||||
INPUT_CONSUMER_PIP, mMainExecutor);
|
||||
mPipTransitionController.registerPipTransitionCallback(this);
|
||||
@@ -914,7 +920,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
return true;
|
||||
}
|
||||
|
||||
private void dump(PrintWriter pw) {
|
||||
private void dump(PrintWriter pw, String prefix) {
|
||||
final String innerPrefix = " ";
|
||||
pw.println(TAG);
|
||||
mMenuController.dump(pw, innerPrefix);
|
||||
@@ -1002,18 +1008,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb
|
||||
PipController.this.showPictureInPictureMenu();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw) {
|
||||
try {
|
||||
mMainExecutor.executeBlocking(() -> {
|
||||
PipController.this.dump(pw);
|
||||
});
|
||||
} catch (InterruptedException e) {
|
||||
ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
|
||||
"%s: Failed to dump PipController in 2s", TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.android.wm.shell.common.TaskStackListenerImpl;
|
||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||
import com.android.wm.shell.common.annotations.ShellMainThread;
|
||||
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
||||
import com.android.wm.shell.util.SplitBounds;
|
||||
@@ -62,6 +63,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
||||
private static final String TAG = RecentTasksController.class.getSimpleName();
|
||||
|
||||
private final Context mContext;
|
||||
private final ShellCommandHandler mShellCommandHandler;
|
||||
private final ShellExecutor mMainExecutor;
|
||||
private final TaskStackListenerImpl mTaskStackListener;
|
||||
private final RecentTasks mImpl = new RecentTasksImpl();
|
||||
@@ -87,20 +89,24 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
||||
public static RecentTasksController create(
|
||||
Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
TaskStackListenerImpl taskStackListener,
|
||||
@ShellMainThread ShellExecutor mainExecutor
|
||||
) {
|
||||
if (!context.getResources().getBoolean(com.android.internal.R.bool.config_hasRecents)) {
|
||||
return null;
|
||||
}
|
||||
return new RecentTasksController(context, shellInit, taskStackListener, mainExecutor);
|
||||
return new RecentTasksController(context, shellInit, shellCommandHandler, taskStackListener,
|
||||
mainExecutor);
|
||||
}
|
||||
|
||||
RecentTasksController(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
TaskStackListenerImpl taskStackListener,
|
||||
ShellExecutor mainExecutor) {
|
||||
mContext = context;
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mIsDesktopMode = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
|
||||
mTaskStackListener = taskStackListener;
|
||||
mMainExecutor = mainExecutor;
|
||||
@@ -112,6 +118,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
||||
}
|
||||
|
||||
private void onInit() {
|
||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||
mTaskStackListener.addListener(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||
import com.android.wm.shell.recents.RecentTasksController;
|
||||
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
|
||||
import com.android.wm.shell.sysui.KeyguardChangeListener;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
@@ -131,6 +132,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface ExitReason{}
|
||||
|
||||
private final ShellCommandHandler mShellCommandHandler;
|
||||
private final ShellController mShellController;
|
||||
private final ShellTaskOrganizer mTaskOrganizer;
|
||||
private final SyncTransactionQueue mSyncQueue;
|
||||
@@ -147,6 +149,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
private final SplitscreenEventLogger mLogger;
|
||||
private final IconProvider mIconProvider;
|
||||
private final Optional<RecentTasksController> mRecentTasksOptional;
|
||||
private final SplitScreenShellCommandHandler mSplitScreenShellCommandHandler;
|
||||
|
||||
private StageCoordinator mStageCoordinator;
|
||||
// Only used for the legacy recents animation from splitscreen to allow the tasks to be animated
|
||||
@@ -155,6 +158,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
|
||||
public SplitScreenController(Context context,
|
||||
ShellInit shellInit,
|
||||
ShellCommandHandler shellCommandHandler,
|
||||
ShellController shellController,
|
||||
ShellTaskOrganizer shellTaskOrganizer,
|
||||
SyncTransactionQueue syncQueue,
|
||||
@@ -168,6 +172,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
IconProvider iconProvider,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
ShellExecutor mainExecutor) {
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mShellController = shellController;
|
||||
mTaskOrganizer = shellTaskOrganizer;
|
||||
mSyncQueue = syncQueue;
|
||||
@@ -183,6 +188,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
mLogger = new SplitscreenEventLogger();
|
||||
mIconProvider = iconProvider;
|
||||
mRecentTasksOptional = recentTasks;
|
||||
mSplitScreenShellCommandHandler = new SplitScreenShellCommandHandler(this);
|
||||
// TODO(b/238217847): Temporarily add this check here until we can remove the dynamic
|
||||
// override for this controller from the base module
|
||||
if (ActivityTaskManager.supportsSplitScreenMultiWindow(context)) {
|
||||
@@ -200,6 +206,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void onInit() {
|
||||
mShellCommandHandler.addDumpCallback(this::dump, this);
|
||||
mShellCommandHandler.addCommandCallback("splitscreen", mSplitScreenShellCommandHandler,
|
||||
this);
|
||||
mShellController.addKeyguardChangeListener(this);
|
||||
if (mStageCoordinator == null) {
|
||||
// TODO: Multi-display
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.wm.shell.splitscreen;
|
||||
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Handles the shell commands for the SplitscreenController.
|
||||
*/
|
||||
public class SplitScreenShellCommandHandler implements
|
||||
ShellCommandHandler.ShellCommandActionHandler {
|
||||
|
||||
private final SplitScreenController mController;
|
||||
|
||||
public SplitScreenShellCommandHandler(SplitScreenController controller) {
|
||||
mController = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShellCommand(String[] args, PrintWriter pw) {
|
||||
switch (args[0]) {
|
||||
case "moveToSideStage":
|
||||
return runMoveToSideStage(args, pw);
|
||||
case "removeFromSideStage":
|
||||
return runRemoveFromSideStage(args, pw);
|
||||
case "setSideStagePosition":
|
||||
return runSetSideStagePosition(args, pw);
|
||||
default:
|
||||
pw.println("Invalid command: " + args[0]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean runMoveToSideStage(String[] args, PrintWriter pw) {
|
||||
if (args.length < 3) {
|
||||
// First argument is the action name.
|
||||
pw.println("Error: task id should be provided as arguments");
|
||||
return false;
|
||||
}
|
||||
final int taskId = new Integer(args[1]);
|
||||
final int sideStagePosition = args.length > 3
|
||||
? new Integer(args[2]) : SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||
mController.moveToSideStage(taskId, sideStagePosition);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean runRemoveFromSideStage(String[] args, PrintWriter pw) {
|
||||
if (args.length < 2) {
|
||||
// First argument is the action name.
|
||||
pw.println("Error: task id should be provided as arguments");
|
||||
return false;
|
||||
}
|
||||
final int taskId = new Integer(args[1]);
|
||||
mController.removeFromSideStage(taskId);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean runSetSideStagePosition(String[] args, PrintWriter pw) {
|
||||
if (args.length < 2) {
|
||||
// First argument is the action name.
|
||||
pw.println("Error: side stage position should be provided as arguments");
|
||||
return false;
|
||||
}
|
||||
final int position = new Integer(args[1]);
|
||||
mController.setSideStagePosition(position);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printShellCommandHelp(PrintWriter pw, String prefix) {
|
||||
pw.println(prefix + "moveToSideStage <taskId> <SideStagePosition>");
|
||||
pw.println(prefix + " Move a task with given id in split-screen mode.");
|
||||
pw.println(prefix + "removeFromSideStage <taskId>");
|
||||
pw.println(prefix + " Remove a task with given id in split-screen mode.");
|
||||
pw.println(prefix + "setSideStagePosition <SideStagePosition>");
|
||||
pw.println(prefix + " Sets the position of the side-stage.");
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,14 @@
|
||||
|
||||
package com.android.wm.shell.sysui;
|
||||
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_INIT;
|
||||
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
|
||||
import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
|
||||
import com.android.wm.shell.onehanded.OneHandedController;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
import com.android.wm.shell.recents.RecentTasksController;
|
||||
import com.android.wm.shell.splitscreen.SplitScreenController;
|
||||
import com.android.internal.protolog.common.ProtoLog;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Optional;
|
||||
import java.util.Arrays;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* An entry point into the shell for dumping shell internal state and running adb commands.
|
||||
@@ -38,52 +33,61 @@ import java.util.Optional;
|
||||
public final class ShellCommandHandler {
|
||||
private static final String TAG = ShellCommandHandler.class.getSimpleName();
|
||||
|
||||
private final Optional<SplitScreenController> mSplitScreenOptional;
|
||||
private final Optional<Pip> mPipOptional;
|
||||
private final Optional<OneHandedController> mOneHandedOptional;
|
||||
private final Optional<HideDisplayCutoutController> mHideDisplayCutout;
|
||||
private final Optional<RecentTasksController> mRecentTasks;
|
||||
private final ShellTaskOrganizer mShellTaskOrganizer;
|
||||
private final KidsModeTaskOrganizer mKidsModeTaskOrganizer;
|
||||
// We're using a TreeMap to keep them sorted by command name
|
||||
private final TreeMap<String, BiConsumer<PrintWriter, String>> mDumpables = new TreeMap<>();
|
||||
private final TreeMap<String, ShellCommandActionHandler> mCommands = new TreeMap<>();
|
||||
|
||||
public ShellCommandHandler(
|
||||
ShellController shellController,
|
||||
ShellTaskOrganizer shellTaskOrganizer,
|
||||
KidsModeTaskOrganizer kidsModeTaskOrganizer,
|
||||
Optional<SplitScreenController> splitScreenOptional,
|
||||
Optional<Pip> pipOptional,
|
||||
Optional<OneHandedController> oneHandedOptional,
|
||||
Optional<HideDisplayCutoutController> hideDisplayCutout,
|
||||
Optional<RecentTasksController> recentTasks,
|
||||
ShellExecutor mainExecutor) {
|
||||
mShellTaskOrganizer = shellTaskOrganizer;
|
||||
mKidsModeTaskOrganizer = kidsModeTaskOrganizer;
|
||||
mRecentTasks = recentTasks;
|
||||
mSplitScreenOptional = splitScreenOptional;
|
||||
mPipOptional = pipOptional;
|
||||
mOneHandedOptional = oneHandedOptional;
|
||||
mHideDisplayCutout = hideDisplayCutout;
|
||||
// TODO(238217847): To be removed once the command handler dependencies are inverted
|
||||
shellController.setShellCommandHandler(this);
|
||||
public interface ShellCommandActionHandler {
|
||||
/**
|
||||
* Handles the given command.
|
||||
*
|
||||
* @param args the arguments starting with the action name, then the action arguments
|
||||
* @param pw the write to print output to
|
||||
*/
|
||||
boolean onShellCommand(String[] args, PrintWriter pw);
|
||||
|
||||
/**
|
||||
* Prints the help for this class of commands. Implementations do not need to print the
|
||||
* command class.
|
||||
*/
|
||||
void printShellCommandHelp(PrintWriter pw, String prefix);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a callback to run when the Shell is being dumped.
|
||||
*
|
||||
* @param callback the callback to be made when Shell is dumped, takes the print writer and
|
||||
* a prefix
|
||||
* @param instance used for debugging only
|
||||
*/
|
||||
public <T> void addDumpCallback(BiConsumer<PrintWriter, String> callback, T instance) {
|
||||
mDumpables.put(instance.getClass().getSimpleName(), callback);
|
||||
ProtoLog.v(WM_SHELL_INIT, "Adding dump callback for %s",
|
||||
instance.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an action callback to be invoked when the user runs that particular command from adb.
|
||||
*
|
||||
* @param commandClass the top level class of command to invoke
|
||||
* @param actions the interface to callback when an action of this class is invoked
|
||||
* @param instance used for debugging only
|
||||
*/
|
||||
public <T> void addCommandCallback(String commandClass, ShellCommandActionHandler actions,
|
||||
T instance) {
|
||||
mCommands.put(commandClass, actions);
|
||||
ProtoLog.v(WM_SHELL_INIT, "Adding command class %s for %s", commandClass,
|
||||
instance.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
/** Dumps WM Shell internal state. */
|
||||
public void dump(PrintWriter pw) {
|
||||
mShellTaskOrganizer.dump(pw, "");
|
||||
pw.println();
|
||||
pw.println();
|
||||
mPipOptional.ifPresent(pip -> pip.dump(pw));
|
||||
mOneHandedOptional.ifPresent(oneHanded -> oneHanded.dump(pw));
|
||||
mHideDisplayCutout.ifPresent(hideDisplayCutout -> hideDisplayCutout.dump(pw));
|
||||
pw.println();
|
||||
pw.println();
|
||||
mSplitScreenOptional.ifPresent(splitScreen -> splitScreen.dump(pw, ""));
|
||||
pw.println();
|
||||
pw.println();
|
||||
mRecentTasks.ifPresent(recentTasks -> recentTasks.dump(pw, ""));
|
||||
pw.println();
|
||||
pw.println();
|
||||
mKidsModeTaskOrganizer.dump(pw, "");
|
||||
for (String key : mDumpables.keySet()) {
|
||||
final BiConsumer<PrintWriter, String> r = mDumpables.get(key);
|
||||
r.accept(pw, "");
|
||||
pw.println();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,72 +97,32 @@ public final class ShellCommandHandler {
|
||||
// Argument at position 0 is "WMShell".
|
||||
return false;
|
||||
}
|
||||
switch (args[1]) {
|
||||
case "moveToSideStage":
|
||||
return runMoveToSideStage(args, pw);
|
||||
case "removeFromSideStage":
|
||||
return runRemoveFromSideStage(args, pw);
|
||||
case "setSideStagePosition":
|
||||
return runSetSideStagePosition(args, pw);
|
||||
case "help":
|
||||
return runHelp(pw);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean runMoveToSideStage(String[] args, PrintWriter pw) {
|
||||
if (args.length < 3) {
|
||||
// First arguments are "WMShell" and command name.
|
||||
pw.println("Error: task id should be provided as arguments");
|
||||
final String cmdClass = args[1];
|
||||
if (cmdClass.toLowerCase().equals("help")) {
|
||||
return runHelp(pw);
|
||||
}
|
||||
if (!mCommands.containsKey(cmdClass)) {
|
||||
return false;
|
||||
}
|
||||
final int taskId = new Integer(args[2]);
|
||||
final int sideStagePosition = args.length > 3
|
||||
? new Integer(args[3]) : SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||
mSplitScreenOptional.ifPresent(split -> split.moveToSideStage(taskId, sideStagePosition));
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean runRemoveFromSideStage(String[] args, PrintWriter pw) {
|
||||
if (args.length < 3) {
|
||||
// First arguments are "WMShell" and command name.
|
||||
pw.println("Error: task id should be provided as arguments");
|
||||
return false;
|
||||
}
|
||||
final int taskId = new Integer(args[2]);
|
||||
mSplitScreenOptional.ifPresent(split -> split.removeFromSideStage(taskId));
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean runSetSideStagePosition(String[] args, PrintWriter pw) {
|
||||
if (args.length < 3) {
|
||||
// First arguments are "WMShell" and command name.
|
||||
pw.println("Error: side stage position should be provided as arguments");
|
||||
return false;
|
||||
}
|
||||
final int position = new Integer(args[2]);
|
||||
mSplitScreenOptional.ifPresent(split -> split.setSideStagePosition(position));
|
||||
// Only pass the actions onwards as arguments to the callback
|
||||
final ShellCommandActionHandler actions = mCommands.get(args[1]);
|
||||
final String[] cmdClassArgs = Arrays.copyOfRange(args, 2, args.length);
|
||||
actions.onShellCommand(cmdClassArgs, pw);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean runHelp(PrintWriter pw) {
|
||||
pw.println("Window Manager Shell commands:");
|
||||
for (String commandClass : mCommands.keySet()) {
|
||||
pw.println(" " + commandClass);
|
||||
mCommands.get(commandClass).printShellCommandHelp(pw, " ");
|
||||
}
|
||||
pw.println(" help");
|
||||
pw.println(" Print this help text.");
|
||||
pw.println(" <no arguments provided>");
|
||||
pw.println(" Dump Window Manager Shell internal state");
|
||||
pw.println(" pair <taskId1> <taskId2>");
|
||||
pw.println(" unpair <taskId>");
|
||||
pw.println(" Pairs/unpairs tasks with given ids.");
|
||||
pw.println(" moveToSideStage <taskId> <SideStagePosition>");
|
||||
pw.println(" Move a task with given id in split-screen mode.");
|
||||
pw.println(" removeFromSideStage <taskId>");
|
||||
pw.println(" Remove a task with given id in split-screen mode.");
|
||||
pw.println(" setSideStageOutline <true/false>");
|
||||
pw.println(" Enable/Disable outline on the side-stage.");
|
||||
pw.println(" setSideStagePosition <SideStagePosition>");
|
||||
pw.println(" Sets the position of the side-stage.");
|
||||
pw.println(" Dump all Window Manager Shell internal state");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,11 +45,10 @@ public class ShellController {
|
||||
private static final String TAG = ShellController.class.getSimpleName();
|
||||
|
||||
private final ShellInit mShellInit;
|
||||
private final ShellCommandHandler mShellCommandHandler;
|
||||
private final ShellExecutor mMainExecutor;
|
||||
private final ShellInterfaceImpl mImpl = new ShellInterfaceImpl();
|
||||
|
||||
private ShellCommandHandler mShellCommandHandler;
|
||||
|
||||
private final CopyOnWriteArrayList<ConfigurationChangeListener> mConfigChangeListeners =
|
||||
new CopyOnWriteArrayList<>();
|
||||
private final CopyOnWriteArrayList<KeyguardChangeListener> mKeyguardChangeListeners =
|
||||
@@ -57,8 +56,10 @@ public class ShellController {
|
||||
private Configuration mLastConfiguration;
|
||||
|
||||
|
||||
public ShellController(ShellInit shellInit, ShellExecutor mainExecutor) {
|
||||
public ShellController(ShellInit shellInit, ShellCommandHandler shellCommandHandler,
|
||||
ShellExecutor mainExecutor) {
|
||||
mShellInit = shellInit;
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
mMainExecutor = mainExecutor;
|
||||
}
|
||||
|
||||
@@ -69,15 +70,6 @@ public class ShellController {
|
||||
return mImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command handler to call back to.
|
||||
* TODO(238217847): This is only exposed this way until we can remove the dependencies from the
|
||||
* command handler to other classes.
|
||||
*/
|
||||
public void setShellCommandHandler(ShellCommandHandler shellCommandHandler) {
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new configuration listener. The configuration change callbacks are not made in any
|
||||
* particular order.
|
||||
|
||||
@@ -59,6 +59,7 @@ import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.compatui.CompatUIController;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -85,10 +86,12 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
|
||||
@Mock
|
||||
private CompatUIController mCompatUI;
|
||||
@Mock
|
||||
private ShellInit mShellInit;
|
||||
private ShellExecutor mTestExecutor;
|
||||
@Mock
|
||||
private ShellCommandHandler mShellCommandHandler;
|
||||
|
||||
ShellTaskOrganizer mOrganizer;
|
||||
private final ShellExecutor mTestExecutor = mock(ShellExecutor.class);
|
||||
private ShellTaskOrganizer mOrganizer;
|
||||
private ShellInit mShellInit;
|
||||
|
||||
private class TrackingTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
final ArrayList<RunningTaskInfo> appeared = new ArrayList<>();
|
||||
@@ -132,8 +135,11 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
|
||||
doReturn(ParceledListSlice.<TaskAppearedInfo>emptyList())
|
||||
.when(mTaskOrganizerController).registerTaskOrganizer(any());
|
||||
} catch (RemoteException e) {}
|
||||
mOrganizer = spy(new ShellTaskOrganizer(mShellInit, mTaskOrganizerController,
|
||||
mCompatUI, Optional.empty(), Optional.empty(), mTestExecutor));
|
||||
mShellInit = spy(new ShellInit(mTestExecutor));
|
||||
mOrganizer = spy(new ShellTaskOrganizer(mShellInit, mShellCommandHandler,
|
||||
mTaskOrganizerController, mCompatUI, Optional.empty(), Optional.empty(),
|
||||
mTestExecutor));
|
||||
mShellInit.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -142,9 +148,12 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterOrganizer_sendRegisterTaskOrganizer() throws RemoteException {
|
||||
mOrganizer.registerOrganizer();
|
||||
public void instantiate_addDumpCallback() {
|
||||
verify(mShellCommandHandler, times(1)).addDumpCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInit_sendRegisterTaskOrganizer() throws RemoteException {
|
||||
verify(mTaskOrganizerController).registerTaskOrganizer(any(ITaskOrganizer.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import androidx.test.platform.app.InstrumentationRegistry;
|
||||
|
||||
import com.android.wm.shell.ShellTestCase;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
|
||||
@@ -48,6 +49,8 @@ public class HideDisplayCutoutControllerTest extends ShellTestCase {
|
||||
private TestableContext mContext = new TestableContext(
|
||||
InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
|
||||
|
||||
@Mock
|
||||
private ShellCommandHandler mShellCommandHandler;
|
||||
@Mock
|
||||
private ShellController mShellController;
|
||||
@Mock
|
||||
@@ -60,8 +63,8 @@ public class HideDisplayCutoutControllerTest extends ShellTestCase {
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mShellInit = spy(new ShellInit(mock(ShellExecutor.class)));
|
||||
mHideDisplayCutoutController = new HideDisplayCutoutController(
|
||||
mContext, mShellInit, mShellController, mMockDisplayAreaOrganizer);
|
||||
mHideDisplayCutoutController = new HideDisplayCutoutController(mContext, mShellInit,
|
||||
mShellCommandHandler, mShellController, mMockDisplayAreaOrganizer);
|
||||
mShellInit.init();
|
||||
}
|
||||
|
||||
@@ -70,6 +73,11 @@ public class HideDisplayCutoutControllerTest extends ShellTestCase {
|
||||
verify(mShellInit, times(1)).addInitCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiateController_registerDumpCallback() {
|
||||
verify(mShellCommandHandler, times(1)).addDumpCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiateController_registerConfigChangeListener() {
|
||||
verify(mShellController, times(1)).addConfigurationChangeListener(any());
|
||||
|
||||
@@ -49,6 +49,7 @@ import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.DisplayInsetsController;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -74,6 +75,7 @@ public class KidsModeTaskOrganizerTest extends ShellTestCase {
|
||||
@Mock private WindowContainerTransaction mTransaction;
|
||||
@Mock private KidsModeSettingsObserver mObserver;
|
||||
@Mock private ShellInit mShellInit;
|
||||
@Mock private ShellCommandHandler mShellCommandHandler;
|
||||
@Mock private DisplayInsetsController mDisplayInsetsController;
|
||||
|
||||
KidsModeTaskOrganizer mOrganizer;
|
||||
@@ -87,13 +89,19 @@ public class KidsModeTaskOrganizerTest extends ShellTestCase {
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
// NOTE: KidsModeTaskOrganizer should have a null CompatUIController.
|
||||
mOrganizer = spy(new KidsModeTaskOrganizer(mContext, mTaskOrganizerController,
|
||||
mSyncTransactionQueue, mDisplayController, mDisplayInsetsController,
|
||||
Optional.empty(), Optional.empty(), mObserver, mTestExecutor, mHandler));
|
||||
mOrganizer = spy(new KidsModeTaskOrganizer(mContext, mShellInit, mShellCommandHandler,
|
||||
mTaskOrganizerController, mSyncTransactionQueue, mDisplayController,
|
||||
mDisplayInsetsController, Optional.empty(), Optional.empty(), mObserver,
|
||||
mTestExecutor, mHandler));
|
||||
doReturn(mTransaction).when(mOrganizer).getWindowContainerTransaction();
|
||||
doReturn(new InsetsState()).when(mDisplayController).getInsetsState(DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiateController_addInitCallback() {
|
||||
verify(mShellInit, times(1)).addInitCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKidsModeOn() {
|
||||
doReturn(true).when(mObserver).isEnabled();
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.DisplayLayout;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.TaskStackListenerImpl;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
|
||||
@@ -69,6 +70,8 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
OneHandedState mSpiedTransitionState;
|
||||
ShellInit mShellInit;
|
||||
|
||||
@Mock
|
||||
ShellCommandHandler mMockShellCommandHandler;
|
||||
@Mock
|
||||
ShellController mMockShellController;
|
||||
@Mock
|
||||
@@ -129,6 +132,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
mSpiedOneHandedController = spy(new OneHandedController(
|
||||
mContext,
|
||||
mShellInit,
|
||||
mMockShellCommandHandler,
|
||||
mMockShellController,
|
||||
mMockDisplayController,
|
||||
mMockDisplayAreaOrganizer,
|
||||
@@ -151,6 +155,11 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
verify(mShellInit, times(1)).addInitCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiateController_registerDumpCallback() {
|
||||
verify(mMockShellCommandHandler, times(1)).addDumpCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testControllerRegistersConfigChangeListener() {
|
||||
verify(mMockShellController, times(1)).addConfigurationChangeListener(any());
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.DisplayLayout;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.TaskStackListenerImpl;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
|
||||
@@ -64,6 +65,8 @@ public class OneHandedStateTest extends OneHandedTestCase {
|
||||
@Mock
|
||||
ShellInit mMockShellInit;
|
||||
@Mock
|
||||
ShellCommandHandler mMockShellCommandHandler;
|
||||
@Mock
|
||||
ShellController mMockShellController;
|
||||
@Mock
|
||||
DisplayController mMockDisplayController;
|
||||
@@ -115,6 +118,7 @@ public class OneHandedStateTest extends OneHandedTestCase {
|
||||
mSpiedOneHandedController = spy(new OneHandedController(
|
||||
mContext,
|
||||
mMockShellInit,
|
||||
mMockShellCommandHandler,
|
||||
mMockShellController,
|
||||
mMockDisplayController,
|
||||
mMockDisplayAreaOrganizer,
|
||||
|
||||
@@ -55,6 +55,7 @@ import com.android.wm.shell.pip.PipSnapAlgorithm;
|
||||
import com.android.wm.shell.pip.PipTaskOrganizer;
|
||||
import com.android.wm.shell.pip.PipTransitionController;
|
||||
import com.android.wm.shell.pip.PipTransitionState;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
|
||||
@@ -77,6 +78,7 @@ public class PipControllerTest extends ShellTestCase {
|
||||
private PipController mPipController;
|
||||
private ShellInit mShellInit;
|
||||
|
||||
@Mock private ShellCommandHandler mMockShellCommandHandler;
|
||||
@Mock private ShellController mMockShellController;
|
||||
@Mock private DisplayController mMockDisplayController;
|
||||
@Mock private PhonePipMenuController mMockPhonePipMenuController;
|
||||
@@ -108,9 +110,9 @@ public class PipControllerTest extends ShellTestCase {
|
||||
return null;
|
||||
}).when(mMockExecutor).execute(any());
|
||||
mShellInit = spy(new ShellInit(mMockExecutor));
|
||||
mPipController = new PipController(mContext, mShellInit, mMockShellController,
|
||||
mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
|
||||
mMockPipKeepClearAlgorithm,
|
||||
mPipController = new PipController(mContext, mShellInit, mMockShellCommandHandler,
|
||||
mMockShellController, mMockDisplayController, mMockPipAppOpsListener,
|
||||
mMockPipBoundsAlgorithm, mMockPipKeepClearAlgorithm,
|
||||
mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
|
||||
mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTransitionState,
|
||||
mMockPipTouchHandler, mMockPipTransitionController, mMockWindowManagerShellWrapper,
|
||||
@@ -126,6 +128,11 @@ public class PipControllerTest extends ShellTestCase {
|
||||
verify(mShellInit, times(1)).addInitCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiateController_registerDumpCallback() {
|
||||
verify(mMockShellCommandHandler, times(1)).addDumpCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiatePipController_registerConfigChangeListener() {
|
||||
verify(mMockShellController, times(1)).addConfigurationChangeListener(any());
|
||||
@@ -159,9 +166,9 @@ public class PipControllerTest extends ShellTestCase {
|
||||
when(spyContext.getPackageManager()).thenReturn(mockPackageManager);
|
||||
|
||||
ShellInit shellInit = new ShellInit(mMockExecutor);
|
||||
assertNull(PipController.create(spyContext, shellInit, mMockShellController,
|
||||
mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
|
||||
mMockPipKeepClearAlgorithm,
|
||||
assertNull(PipController.create(spyContext, shellInit, mMockShellCommandHandler,
|
||||
mMockShellController, mMockDisplayController, mMockPipAppOpsListener,
|
||||
mMockPipBoundsAlgorithm, mMockPipKeepClearAlgorithm,
|
||||
mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
|
||||
mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTransitionState,
|
||||
mMockPipTouchHandler, mMockPipTransitionController, mMockWindowManagerShellWrapper,
|
||||
|
||||
@@ -23,7 +23,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
@@ -48,6 +50,7 @@ import com.android.wm.shell.ShellTestCase;
|
||||
import com.android.wm.shell.TestShellExecutor;
|
||||
import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.TaskStackListenerImpl;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
||||
import com.android.wm.shell.util.SplitBounds;
|
||||
@@ -73,21 +76,35 @@ public class RecentTasksControllerTest extends ShellTestCase {
|
||||
@Mock
|
||||
private TaskStackListenerImpl mTaskStackListener;
|
||||
@Mock
|
||||
private ShellInit mShellInit;
|
||||
private ShellCommandHandler mShellCommandHandler;
|
||||
|
||||
private ShellTaskOrganizer mShellTaskOrganizer;
|
||||
private RecentTasksController mRecentTasksController;
|
||||
private ShellInit mShellInit;
|
||||
private ShellExecutor mMainExecutor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mMainExecutor = new TestShellExecutor();
|
||||
when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
|
||||
mShellInit = spy(new ShellInit(mMainExecutor));
|
||||
mRecentTasksController = spy(new RecentTasksController(mContext, mShellInit,
|
||||
mTaskStackListener, mMainExecutor));
|
||||
mShellTaskOrganizer = new ShellTaskOrganizer(mShellInit,
|
||||
mShellCommandHandler, mTaskStackListener, mMainExecutor));
|
||||
mShellTaskOrganizer = new ShellTaskOrganizer(mShellInit, mShellCommandHandler,
|
||||
null /* sizeCompatUI */, Optional.empty(), Optional.of(mRecentTasksController),
|
||||
mMainExecutor);
|
||||
mShellInit.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiateController_addInitCallback() {
|
||||
verify(mShellInit, times(1)).addInitCallback(any(), isA(RecentTasksController.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiateController_addDumpCallback() {
|
||||
verify(mShellCommandHandler, times(1)).addDumpCallback(any(),
|
||||
isA(RecentTasksController.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -53,6 +54,7 @@ import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
import com.android.wm.shell.common.TransactionPool;
|
||||
import com.android.wm.shell.draganddrop.DragAndDropController;
|
||||
import com.android.wm.shell.recents.RecentTasksController;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
@@ -72,8 +74,9 @@ import java.util.Optional;
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SplitScreenControllerTests extends ShellTestCase {
|
||||
|
||||
@Mock ShellController mShellController;
|
||||
@Mock ShellInit mShellInit;
|
||||
@Mock ShellController mShellController;
|
||||
@Mock ShellCommandHandler mShellCommandHandler;
|
||||
@Mock ShellTaskOrganizer mTaskOrganizer;
|
||||
@Mock SyncTransactionQueue mSyncQueue;
|
||||
@Mock RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
|
||||
@@ -93,9 +96,10 @@ public class SplitScreenControllerTests extends ShellTestCase {
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mSplitScreenController = spy(new SplitScreenController(mContext, mShellInit,
|
||||
mShellController, mTaskOrganizer, mSyncQueue, mRootTDAOrganizer, mDisplayController,
|
||||
mDisplayImeController, mDisplayInsetsController, mDragAndDropController,
|
||||
mTransitions, mTransactionPool, mIconProvider, mRecentTasks, mMainExecutor));
|
||||
mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue,
|
||||
mRootTDAOrganizer, mDisplayController, mDisplayImeController,
|
||||
mDisplayInsetsController, mDragAndDropController, mTransitions, mTransactionPool,
|
||||
mIconProvider, mRecentTasks, mMainExecutor));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,8 +107,25 @@ public class SplitScreenControllerTests extends ShellTestCase {
|
||||
verify(mShellInit, times(1)).addInitCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiateController_registerDumpCallback() {
|
||||
doReturn(mMainExecutor).when(mTaskOrganizer).getExecutor();
|
||||
when(mDisplayController.getDisplayLayout(anyInt())).thenReturn(new DisplayLayout());
|
||||
mSplitScreenController.onInit();
|
||||
verify(mShellCommandHandler, times(1)).addDumpCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instantiateController_registerCommandCallback() {
|
||||
doReturn(mMainExecutor).when(mTaskOrganizer).getExecutor();
|
||||
when(mDisplayController.getDisplayLayout(anyInt())).thenReturn(new DisplayLayout());
|
||||
mSplitScreenController.onInit();
|
||||
verify(mShellCommandHandler, times(1)).addCommandCallback(eq("splitscreen"), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testControllerRegistersKeyguardChangeListener() {
|
||||
doReturn(mMainExecutor).when(mTaskOrganizer).getExecutor();
|
||||
when(mDisplayController.getDisplayLayout(anyInt())).thenReturn(new DisplayLayout());
|
||||
mSplitScreenController.onInit();
|
||||
verify(mShellController, times(1)).addKeyguardChangeListener(any());
|
||||
|
||||
@@ -45,6 +45,8 @@ public class ShellControllerTest extends ShellTestCase {
|
||||
@Mock
|
||||
private ShellInit mShellInit;
|
||||
@Mock
|
||||
private ShellCommandHandler mShellCommandHandler;
|
||||
@Mock
|
||||
private ShellExecutor mExecutor;
|
||||
|
||||
private ShellController mController;
|
||||
@@ -56,7 +58,7 @@ public class ShellControllerTest extends ShellTestCase {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mKeyguardChangeListener = new TestKeyguardChangeListener();
|
||||
mConfigChangeListener = new TestConfigurationChangeListener();
|
||||
mController = new ShellController(mShellInit, mExecutor);
|
||||
mController = new ShellController(mShellInit, mShellCommandHandler, mExecutor);
|
||||
mController.onConfigurationChanged(getConfigurationCopy());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user