diff options
| author | 2022-07-09 03:18:35 +0000 | |
|---|---|---|
| committer | 2022-08-07 04:41:40 +0000 | |
| commit | 38caa7a7df7b3b26973093276045c7b36dacea7c (patch) | |
| tree | f27adf2cee687986ab3d1e2a887c9bdb935b315b | |
| parent | 8df4942e0d04577cce5267e01227f77bd68c18dd (diff) | |
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
24 files changed, 433 insertions, 235 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java index 5cba3b4ec130..6ae0f9ba0485 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -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); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java index 1896e89ebb85..bbaf51f7c54c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java @@ -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(); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index c7642fee87fb..1e4599ef0d51 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -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, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md index 52f0c4222b64..99922fbc2d95 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md @@ -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 diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md index 0dd50b1bee68..d6302e640ba7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md @@ -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
\ No newline at end of file +- 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> ... +```
\ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java index 8d6e58909c32..32125fa44148 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java @@ -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); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java index 73b9b89e6993..2fdd12185551 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java @@ -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); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index 15361bb6ef29..9149204b94ce 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -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); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java index 38631ce26cd1..93172f82edd1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java @@ -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) { - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 50d9420885a7..f839363b2da8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -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); - } - } } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java index 3d1a7e98e20d..7b42350b1365 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java @@ -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); } 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 de7e7bd1c506..a55e968aaa96 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 @@ -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 diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenShellCommandHandler.java new file mode 100644 index 000000000000..681d9647d154 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenShellCommandHandler.java @@ -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."); + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java index f4fc0c4c36bc..2e6ddc363906 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java @@ -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; - - 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); + // 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 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"); - return false; + final String cmdClass = args[1]; + if (cmdClass.toLowerCase().equals("help")) { + return runHelp(pw); } - 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"); + if (!mCommands.containsKey(cmdClass)) { 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; } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java index f1f317f65ba9..52ffb46bb39c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java @@ -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; } @@ -70,15 +71,6 @@ public class ShellController { } /** - * 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. */ diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java index 7517e8ab6826..f865649b6bbc 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java @@ -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)); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java index 6a8e4a55b7f3..6c301bbbc7f1 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java @@ -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; @@ -49,6 +50,8 @@ public class HideDisplayCutoutControllerTest extends ShellTestCase { InstrumentationRegistry.getInstrumentation().getTargetContext(), null); @Mock + private ShellCommandHandler mShellCommandHandler; + @Mock private ShellController mShellController; @Mock private HideDisplayCutoutOrganizer mMockDisplayAreaOrganizer; @@ -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(); } @@ -71,6 +74,11 @@ public class HideDisplayCutoutControllerTest extends ShellTestCase { } @Test + public void instantiateController_registerDumpCallback() { + verify(mShellCommandHandler, times(1)).addDumpCallback(any(), any()); + } + + @Test public void instantiateController_registerConfigChangeListener() { verify(mShellController, times(1)).addConfigurationChangeListener(any()); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java index a919ad0b4765..ecfb427dbced 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java @@ -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,14 +89,20 @@ 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(); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index b84cecc0875a..90645ce4747d 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -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; @@ -70,6 +71,8 @@ public class OneHandedControllerTest extends OneHandedTestCase { ShellInit mShellInit; @Mock + ShellCommandHandler mMockShellCommandHandler; + @Mock ShellController mMockShellController; @Mock DisplayLayout mMockDisplayLayout; @@ -129,6 +132,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { mSpiedOneHandedController = spy(new OneHandedController( mContext, mShellInit, + mMockShellCommandHandler, mMockShellController, mMockDisplayController, mMockDisplayAreaOrganizer, @@ -152,6 +156,11 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test + public void instantiateController_registerDumpCallback() { + verify(mMockShellCommandHandler, times(1)).addDumpCallback(any(), any()); + } + + @Test public void testControllerRegistersConfigChangeListener() { verify(mMockShellController, times(1)).addConfigurationChangeListener(any()); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java index 9f72567a134f..a39bdf04bf56 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java @@ -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, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java index 117e4ce07b31..56e32e241271 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java @@ -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, @@ -127,6 +129,11 @@ public class PipControllerTest extends ShellTestCase { } @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, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java index d406a4ed3fd7..81bb609cc711 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java @@ -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 diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java index 10788f9df32f..eee2a1bcb147 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java @@ -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 @@ -104,7 +108,24 @@ public class SplitScreenControllerTests extends ShellTestCase { } @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()); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java index 02311bab2e4d..39e58ffcf9c7 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java @@ -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()); } |