1# Debugging in the Shell 2[Back to home](README.md) 3 4--- 5 6## Logging & ProtoLogs 7 8The interactions in the Shell can be pretty complicated, so having good logging is crucial to 9debugging problems that arise (especially in dogfood). The Shell uses the same efficient Protolog 10mechanism as WM Core, which can be enabled at runtime on debug devices. 11 12**TLDR** Don’t use Logs or Slogs except for error cases, Protologs are much more flexible, 13easy to add and easy to use 14 15### Adding a new ProtoLog 16Update `ShellProtoLogGroup` to include a new log group (ie. NEW_FEATURE) for the content you want to 17log. ProtoLog log calls mirror Log.v/d/e(), and take a format message and arguments: 18```java 19ProtoLog.v(NEW_FEATURE, "Test log w/ params: %d %s", 1, “a”) 20``` 21This code itself will not compile by itself, but the `protologtool` will preprocess the file when 22building to check the log state (is enabled) before printing the print format style log. 23 24**Notes** 25- ProtoLogs are only fully supported from soong builds (ie. via make/mp). In SysUI-studio it falls 26 back to log via Logcat 27- Non-text ProtoLogs are not currently supported with the Shell library (you can't view them with 28 traces in Winscope) 29 30### Kotlin 31Kotlin protologging is supported but not as optimized as in Java. 32 33The Protolog tool does not yet have support for Kotlin code ([b/168581922](https://b.corp.google.com/issues/168581922)). 34 35What this implies is that ProtoLogs are not pre-processed to extract the static strings out when used in Kotlin. So, 36there is no memory gain when using ProtoLogging in Kotlin. The logs will still be traced to Perfetto, but with a subtly 37worse performance due to the additional string interning that needs to be done at run time instead of at build time. 38 39### Enabling ProtoLog command line logging 40Run these commands to enable protologs (in logcat) for WM Core ([list of all core tags](/core/java/com/android/internal/protolog/ProtoLogGroup.java)): 41```shell 42adb shell wm logging enable-text TAG 43adb shell wm logging disable-text TAG 44``` 45 46And 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)): 47```shell 48# Note: prior to 25Q2, you may need to use: 49# adb shell dumpsys activity service SystemUIService WMShell protolog enable-text TAG 50adb shell wm shell protolog enable-text TAG 51adb shell wm shell protolog disable-text TAG 52``` 53 54### R8 optimizations & ProtoLog 55 56If the APK that the Shell library is included into has R8 optimizations enabled, then you may need 57to update the proguard flags to keep the generated protolog classes (ie. AOSP SystemUI's [proguard.flags](base/packages/SystemUI/proguard_common.flags)). 58 59## Winscope Tracing 60 61The Winscope tool is extremely useful in determining what is happening on-screen in both 62WindowManager and SurfaceFlinger. Follow [go/winscope](http://go/winscope-help) to learn how to 63use the tool. This trace will contain all the information about the windows/activities/surfaces on 64screen. 65 66## WindowManager/SurfaceFlinger/InputDispatcher information 67 68A quick way to view the WindowManager hierarchy without a winscope trace is via the wm dumps: 69```shell 70adb shell dumpsys activity containers 71# The output lists the containers in the hierarchy from top -> bottom in z-order 72``` 73 74To get more information about windows on the screen: 75```shell 76# All windows in WM 77adb shell dumpsys window -a 78# The windows are listed from top -> bottom in z-order 79 80# Visible windows only 81adb shell dumpsys window -a visible 82``` 83 84Likewise, the SurfaceFlinger hierarchy can be dumped for inspection by running: 85```shell 86adb shell dumpsys SurfaceFlinger 87# Search output for "Layer Hierarchy", the surfaces in the table are listed bottom -> top in z-order 88``` 89 90And the visible input windows can be dumped via: 91```shell 92adb shell dumpsys input 93# Search output for "Windows:", they are ordered top -> bottom in z-order 94``` 95 96## Tracing global SurfaceControl transaction updates 97 98While Winscope traces are very useful, it sometimes doesn't give you enough information about which 99part of the code is initiating the transaction updates. In such cases, it can be helpful to get 100stack traces when specific surface transaction calls are made (regardless of process), which is 101possible by enabling the following system properties for example: 102```shell 103# Enabling 104adb shell setprop persist.wm.debug.sc.tx.log_match_call setAlpha,setPosition # matches the name of the SurfaceControlTransaction methods 105adb shell setprop persist.wm.debug.sc.tx.log_match_name com.android.systemui # matches the name of the surface 106adb reboot 107adb logcat -s "SurfaceControlRegistry" 108 109# Disabling logging 110adb shell setprop persist.wm.debug.sc.tx.log_match_call \"\" 111adb shell setprop persist.wm.debug.sc.tx.log_match_name \"\" 112``` 113 114A reboot is required to enable the logging. Once enabled, reboot is not needed to update the 115properties. 116 117It is not necessary to set both `log_match_call` and `log_match_name`, but note logs can be quite 118noisy if unfiltered. 119 120### Tracing transaction merge & apply 121 122Tracing the method calls on SurfaceControl.Transaction tells you where a change is requested, but 123the changes are not actually committed until the transaction itself is applied. And because 124transactions can be passed across processes, or prepared in advance for later application (ie. 125when restoring state after a Transition), the ordering of the change logs is not always clear 126by itself. 127 128In such cases, you can also enable the "merge" and "apply" calls to get additional information 129about how/when transactions are respectively merged/applied: 130```shell 131# Enabling 132adb shell setprop persist.wm.debug.sc.tx.log_match_call setAlpha,merge,apply # apply will dump logs of each setAlpha or merge call on that tx 133adb reboot 134adb logcat -s "SurfaceControlRegistry" 135``` 136 137Using those logs, you can first look at where the desired change is called, note the transaction 138id, and then search the logs for where that transaction id is used. If it is merged into another 139transaction, you can continue the search using the merged transaction until you find the final 140transaction which is applied. 141 142## Tracing activity starts & finishes in the app process 143 144It's sometimes useful to know when to see a stack trace of when an activity starts in the app code 145or via a `WindowContainerTransaction` (ie. if you are repro'ing a bug related to activity starts). 146You can enable this system property to get this trace: 147```shell 148# Enabling 149adb shell setprop persist.wm.debug.start_activity true 150adb reboot 151adb logcat -s "Instrumentation" 152 153# Disabling 154adb shell setprop persist.wm.debug.start_activity \"\" 155adb reboot 156``` 157 158Likewise, to trace where a finish() call may be made in the app process, you can enable this system 159property: 160```shell 161# Enabling 162adb shell setprop persist.wm.debug.finish_activity true 163adb reboot 164adb logcat -s "Instrumentation" 165 166# Disabling 167adb shell setprop persist.wm.debug.finish_activity \"\" 168adb reboot 169``` 170 171## Tracing transition requests in the Shell 172 173To trace where a new WM transition is started in the Shell, you can enable this system property: 174```shell 175# Enabling 176adb shell setprop persist.wm.debug.start_shell_transition true 177adb reboot 178adb logcat -s "ShellTransitions" 179 180# Disabling 181adb shell setprop persist.wm.debug.start_shell_transition \"\" 182adb reboot 183``` 184 185 186## Dumps 187 188Because the Shell library is built as a part of SystemUI, dumping the state is currently done as a 189part of dumping the SystemUI service. Dumping the Shell specific data can be done by specifying the 190WMShell SysUI service: 191 192```shell 193# Note: prior to 25Q2, you may need to use: 194# adb shell dumpsys activity service SystemUIService WMShell dump 195adb shell wm shell dump 196``` 197 198If information should be added to the dump, either: 199- Update `WMShell` if you are dumping SysUI state 200- Inject `ShellCommandHandler` into your Shell class, and add a dump callback 201 202## Shell commands 203 204It can be useful to add additional shell commands to drive and test specific interactions. 205 206To add a new command for your feature, inject a `ShellCommandHandler` into your class and add a 207shell command handler in your controller. 208 209```shell 210# List all available commands 211# Note: prior to 25Q2, you may need to use: 212# adb shell dumpsys activity service SystemUIService WMShell help 213adb shell wm shell help 214 215# Run a specific command 216# Note: prior to 25Q2, you may need to use: 217# adb shell dumpsys activity service SystemUIService WMShell <cmd> <args> ... 218adb shell wm shell <cmd> <args> ... 219``` 220 221## Debugging in Android Studio 222 223If you are using the [go/sysui-studio](http://go/sysui-studio) project, then you can debug Shell 224code directly from Android Studio like any other app. 225