Merge "Proxy wm commands to shell to simplify command line usage" into main
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
index 514307f..78c8182 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
@@ -17,9 +17,9 @@
 package com.android.wm.shell;
 
 import com.android.internal.protolog.LegacyProtoLogImpl;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.protolog.common.ILogger;
 import com.android.internal.protolog.common.IProtoLog;
-import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellInit;
 
@@ -29,7 +29,7 @@
 /**
  * Controls the {@link ProtoLog} in WMShell via adb shell commands.
  *
- * Use with {@code adb shell dumpsys activity service SystemUIService WMShell protolog ...}.
+ * Use with {@code adb shell wm shell protolog ...}.
  */
 public class ProtoLogController implements ShellCommandHandler.ShellCommandActionHandler {
     private final ShellCommandHandler mShellCommandHandler;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIShellCommandHandler.java
index 4fb18e2..6bf0c2f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIShellCommandHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIShellCommandHandler.java
@@ -27,8 +27,7 @@
 /**
  * Handles the shell commands for the CompatUX.
  *
- * <p> Use with {@code adb shell dumpsys activity service SystemUIService WMShell compatui
- * &lt;command&gt;}.
+ * <p> Use with {@code adb shell wm shell compatui &lt;command&gt;}.
  */
 @WMSingleton
 public final class CompatUIShellCommandHandler implements
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxCommandHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxCommandHandler.kt
index 2d0a3f5..5048dd5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxCommandHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxCommandHandler.kt
@@ -31,8 +31,7 @@
 /**
  * Handles the shell commands for the CompatUI.
  *
- * <p> Use with [adb shell dumpsys activity service SystemUIService WMShell letterbox
- * &lt;command&gt;].
+ * <p> Use with [adb shell wm shell letterbox &lt;command&gt;].
  */
 @WMSingleton
 class LetterboxCommandHandler @Inject constructor(
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 72d1a76..09e627c 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
@@ -44,8 +44,10 @@
 
 And these commands to enable protologs (in logcat) for WM Shell ([list of all shell tags](/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java)):
 ```shell
-adb shell dumpsys activity service SystemUIService WMShell protolog enable-text TAG
-adb shell dumpsys activity service SystemUIService WMShell protolog enable-text TAG
+# Note: prior to 25Q2, you may need to use:
+#   adb shell dumpsys activity service SystemUIService WMShell protolog enable-text TAG
+adb shell wm shell protolog enable-text TAG
+adb shell wm shell protolog disable-text TAG
 ```
 
 ## Winscope Tracing
@@ -138,7 +140,9 @@
 WMShell SysUI service:
 
 ```shell
-adb shell dumpsys activity service SystemUIService WMShell
+# Note: prior to 25Q2, you may need to use:
+#   adb shell dumpsys activity service SystemUIService WMShell dump
+adb shell wm shell dump
 ```
 
 If information should be added to the dump, either:
@@ -154,10 +158,14 @@
 
 ```shell
 # List all available commands
-adb shell dumpsys activity service SystemUIService WMShell help
+# Note: prior to 25Q2, you may need to use:
+#   adb shell dumpsys activity service SystemUIService WMShell help
+adb shell wm shell help
 
 # Run a specific command
-adb shell dumpsys activity service SystemUIService WMShell <cmd> <args> ...
+# Note: prior to 25Q2, you may need to use:
+#   adb shell dumpsys activity service SystemUIService WMShell <cmd> <args> ...
+adb shell wm shell <cmd> <args> ...
 ```
 
 ## 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 30ff669..5e92010 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
@@ -71,15 +71,6 @@
 ## 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.
+on 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> ...
-```
-
-More detail can be found in [Debugging in the Shell](debugging.md) section.
\ No newline at end of file
+More detail can be found in [Debugging in the Shell](debugging.md#shell-commands) section.
\ No newline at end of file
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 aa9f15c..aeb65c0 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
@@ -28,7 +28,7 @@
 /**
  * An entry point into the shell for dumping shell internal state and running adb commands.
  *
- * Use with {@code adb shell dumpsys activity service SystemUIService WMShell ...}.
+ * Use with {@code adb shell wm shell <args>}.
  */
 public final class ShellCommandHandler {
     private static final String TAG = ShellCommandHandler.class.getSimpleName();
@@ -121,8 +121,6 @@
         }
         pw.println("  help");
         pw.println("      Print this help text.");
-        pw.println("  <no arguments provided>");
-        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 0202b6c..dfe42ee 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
@@ -46,6 +46,7 @@
 import com.android.wm.shell.common.ExternalInterfaceBinder;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.shared.annotations.ExternalThread;
+import com.android.wm.shell.sysui.ShellCommandHandler.ShellCommandActionHandler;
 
 import java.io.PrintWriter;
 import java.util.List;
@@ -112,6 +113,19 @@
         }
     };
 
+    private ShellCommandActionHandler mDumpCommandHandler = new ShellCommandActionHandler() {
+        @Override
+        public boolean onShellCommand(String[] args, PrintWriter pw) {
+            handleDump(pw);
+            return true;
+        }
+
+        @Override
+        public void printShellCommandHelp(PrintWriter pw, String prefix) {
+            pw.println(prefix + "Dump all Window Manager Shell internal state");
+        }
+    };
+
 
     public ShellController(Context context,
             ShellInit shellInit,
@@ -127,6 +141,7 @@
     }
 
     private void onInit() {
+        mShellCommandHandler.addCommandCallback("dump", mDumpCommandHandler, this);
         mShellCommandHandler.addDumpCallback(this::dump, this);
         mDisplayInsetsController.addInsetsChangedListener(
                 mContext.getDisplayId(), mInsetsChangeListener);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index abfb41b..8c9407b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -1756,6 +1756,10 @@
 
     @Override
     public boolean onShellCommand(String[] args, PrintWriter pw) {
+        if (args.length == 0) {
+            printShellCommandHelp(pw, "");
+            return false;
+        }
         switch (args[0]) {
             case "tracing": {
                 if (!android.tracing.Flags.perfettoTransitionTracing()) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt
index d2688a8..6113657 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt
@@ -45,6 +45,8 @@
 import com.android.systemui.settings.userTracker
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.commandQueue
+import com.android.systemui.statusbar.commandline.CommandRegistry
+import com.android.systemui.statusbar.commandline.commandRegistry
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.policy.configurationController
@@ -97,6 +99,7 @@
     @Mock private lateinit var mRecentTasks: RecentTasks
 
     private val mCommandQueue: CommandQueue = kosmos.commandQueue
+    private val mCommandRegistry: CommandRegistry = kosmos.commandRegistry
     private val mConfigurationController: ConfigurationController = kosmos.configurationController
     private val mKeyguardStateController: KeyguardStateController = kosmos.keyguardStateController
     private val mKeyguardUpdateMonitor: KeyguardUpdateMonitor = kosmos.keyguardUpdateMonitor
@@ -126,6 +129,7 @@
                 Optional.of(mDesktopMode),
                 Optional.of(mRecentTasks),
                 mCommandQueue,
+                mCommandRegistry,
                 mConfigurationController,
                 mKeyguardStateController,
                 mKeyguardUpdateMonitor,
@@ -137,7 +141,7 @@
                 mNoteTaskInitializer,
                 communalTransitionViewModel,
                 JavaAdapter(testScope.backgroundScope),
-                mSysUiMainExecutor
+                mSysUiMainExecutor,
             )
     }
 
@@ -162,7 +166,7 @@
         verify(mDesktopMode)
             .addVisibleTasksListener(
                 any(VisibleTasksListener::class.java),
-                any(Executor::class.java)
+                any(Executor::class.java),
             )
     }
 
@@ -190,7 +194,7 @@
             kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
                 from = KeyguardState.GLANCEABLE_HUB,
                 to = KeyguardState.OCCLUDED,
-                testScope
+                testScope,
             )
             kosmos.setCommunalAvailable(true)
             runCurrent()
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 0ec71c2..feaf1a6 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -56,6 +56,8 @@
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.commandline.Command;
+import com.android.systemui.statusbar.commandline.CommandRegistry;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.kotlin.JavaAdapter;
@@ -74,6 +76,7 @@
 import com.android.wm.shell.sysui.ShellInterface;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
@@ -122,6 +125,7 @@
     private final Optional<RecentTasks> mRecentTasksOptional;
 
     private final CommandQueue mCommandQueue;
+    private final CommandRegistry mCommandRegistry;
     private final ConfigurationController mConfigurationController;
     private final KeyguardStateController mKeyguardStateController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -177,6 +181,23 @@
     private boolean mIsSysUiStateValid;
     private WakefulnessLifecycle.Observer mWakefulnessObserver;
 
+    private final Command mShellCommand = new Command() {
+        @Override
+        public void execute(@NonNull PrintWriter pw, @NonNull List<String> args) {
+            final ArrayList<String> shellArgs = new ArrayList<>(args);
+            shellArgs.add(0, "WMShell");
+            Log.d(TAG, "Command with args: " + String.join(", ", shellArgs));
+            if (!mShell.handleCommand(shellArgs.toArray(new String[0]), pw)) {
+                pw.println("Invalid wm shell command: " + String.join(", ", args));
+            }
+        }
+
+        @Override
+        public void help(@NonNull PrintWriter pw) {
+            mShell.handleCommand(new String[] { "WMShell", "help" }, pw);
+        }
+    };
+
     @Inject
     public WMShell(
             Context context,
@@ -187,6 +208,7 @@
             Optional<DesktopMode> desktopMode,
             Optional<RecentTasks> recentTasks,
             CommandQueue commandQueue,
+            CommandRegistry commandRegistry,
             ConfigurationController configurationController,
             KeyguardStateController keyguardStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -202,6 +224,7 @@
         mContext = context;
         mShell = shell;
         mCommandQueue = commandQueue;
+        mCommandRegistry = commandRegistry;
         mConfigurationController = configurationController;
         mKeyguardStateController = keyguardStateController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -235,6 +258,8 @@
         mUserTracker.addCallback(mUserChangedCallback, mContext.getMainExecutor());
 
         mCommandQueue.addCallback(this);
+        mCommandRegistry.registerCommand("wmshell-passthrough", () -> mShellCommand);
+
         mPipOptional.ifPresent(this::initPip);
         mSplitScreenOptional.ifPresent(this::initSplitScreen);
         mOneHandedOptional.ifPresent(this::initOneHanded);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 1f162a2..b7ce050 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -33,6 +33,8 @@
 import com.android.internal.view.AppearanceRegion;
 import com.android.server.notification.NotificationDelegate;
 
+import java.io.FileDescriptor;
+
 public interface StatusBarManagerInternal {
     void setNotificationDelegate(NotificationDelegate delegate);
     /** Show a screen pinning request for a specific task. */
@@ -272,4 +274,8 @@
      * Called when requested to enter desktop from a focused app.
      */
     void moveFocusedTaskToDesktop(int displayId);
+
+
+    /** Passes through the given shell commands to SystemUI */
+    void passThroughShellCommand(String[] args, FileDescriptor fd);
 }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 48dd2eb..4ece470 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -363,11 +363,9 @@
     public void onDisplayChanged(int displayId) {}
 
     /**
-     * Private API used by NotificationManagerService.
+     * Private API used by NotificationManagerService and other system services.
      */
     private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() {
-        private boolean mNotificationLightOn;
-
         @Override
         public void setNotificationDelegate(NotificationDelegate delegate) {
             mNotificationDelegate = delegate;
@@ -993,6 +991,11 @@
         public void removeQsTile(ComponentName tile) {
             StatusBarManagerService.this.remTile(tile);
         }
+
+        @Override
+        public void passThroughShellCommand(String[] args, FileDescriptor fd) {
+            StatusBarManagerService.this.passThroughShellCommand(args, fd);
+        }
     };
 
     private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 44f5f51..20b01d0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -64,6 +64,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.function.Consumer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -1492,46 +1493,12 @@
     }
 
     private int runWmShellCommand(PrintWriter pw) {
-        String arg = getNextArg();
-
-        switch (arg) {
-            case "tracing":
-                return runWmShellTracing(pw);
-            case "help":
-            default:
-                return runHelp(pw);
-        }
-    }
-
-    private int runHelp(PrintWriter pw) {
-        pw.println("Window Manager Shell commands:");
-        pw.println("  help");
-        pw.println("    Print this help text.");
-        pw.println("  tracing <start/stop>");
-        pw.println("    Start/stop shell transition tracing.");
-
-        return 0;
-    }
-
-    private int runWmShellTracing(PrintWriter pw) {
-        String arg = getNextArg();
-
-        switch (arg) {
-            case "start":
-                mInternal.mTransitionTracer.startTrace(pw);
-                break;
-            case "stop":
-                mInternal.mTransitionTracer.stopTrace(pw);
-                break;
-            case "save-for-bugreport":
-                mInternal.mTransitionTracer.saveForBugreport(pw);
-                break;
-            default:
-                getErrPrintWriter()
-                        .println("Error: expected 'start' or 'stop', but got '" + arg + "'");
-                return -1;
-        }
-
+        final String[] args = peekRemainingArgs();
+        ArrayList<String> sbArgs = new ArrayList<>();
+        sbArgs.add("wmshell-passthrough");
+        sbArgs.addAll(Arrays.asList(args));
+        mInternal.mAtmService.getStatusBarManagerInternal().passThroughShellCommand(
+                sbArgs.toArray(new String[0]), getOutFileDescriptor());
         return 0;
     }
 
@@ -1622,6 +1589,9 @@
 
         pw.println("  reset [-d DISPLAY_ID]");
         pw.println("    Reset all override settings.");
+        pw.println("  shell <cmd> ...");
+        pw.println("    Runs a WMShell command.  To see a full list of available wmshell commands "
+                + "run 'adb shell wm shell help'");
         if (!IS_USER) {
             pw.println("  tracing (start | stop)");
             pw.println("    Start or stop window tracing.");