• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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