1# Shell & SystemUI
2
3---
4
5## Setup
6
7The SystemUI of various products depend on and build against the WM Shell library. To ensure
8that we don't inadvertently build dependencies between the Shell library and one particular
9product (ie. handheld SysUI), we deliberately separate the initialization of the WM Shell
10component from the SysUI component when set up through Dagger.
11
12**TLDR**  Initialize everything as needed in the WM component scope and export only well
13defined interfaces to SysUI.
14
15## Initialization
16
17There are more details in the Dagger docs, but the general overview of the SysUI/Shell
18initialization flow is such:
19
201) SysUI Global scope is initialize (see `GlobalModule` and its included modules)
212) WM Shell scope is initialized, for example
22   1) On phones: `WMComponent` includes `WMShellModule` which includes `WMShellBaseModule`
23      (common to all SysUI)
24   2) On TVs: `TvWMComponent` includes `TvWMShellModule` which includes `WMShellBaseModule`
25   3) etc.
263) SysUI explicitly passes interfaces provided from the `WMComponent` to `SysUIComponent` via
27   the `SysUIComponent#Builder`, then builds the SysUI scoped components
284) `WMShell` is the SystemUI “service” (in the SysUI scope) that initializes with the app after the
29SystemUI part of the dependency graph has been created. It contains the binding code between the
30interfaces provided by the Shell and the rest of SystemUI.
315) SysUI can inject the interfaces into its own components
32
33More detail can be found in [go/wm-sysui-dagger](http://go/wm-sysui-dagger).
34
35## Interfaces from SysUI to Shell components
36
37Within the same process, the WM Shell components can be running on a different thread than the main
38SysUI thread (disabled on certain products).  This introduces challenges where we have to be
39careful about how SysUI calls into the Shell and vice versa.
40
41As a result, we enforce explicit interfaces between SysUI and Shell components, and the
42implementations of the interfaces on each side need to post to the right thread before it calls
43into other code.
44
45For example, you might have:
461) (Shell) ShellFeature interface to be used from SysUI
472) (Shell) ShellFeatureController handles logic, implements ShellFeature interface and posts to
48   main Shell thread
493) SysUI application init injects Optional<ShellFeature> as an interface to SysUI to call
504) (SysUI) SysUIFeature depends on ShellFeature interface
515) (SysUI) SysUIFeature injects Optional<ShellFeature>, and sets up a callback for the Shell to
52   call, and the callback posts to the main SysUI thread
53
54Adding an interface to a Shell component may seem like a lot of boiler plate, but is currently
55necessary to maintain proper threading and logic isolation.
56
57## Listening for Configuration changes & other SysUI events
58
59Aside from direct calls into Shell controllers for exposed features, the Shell also receives
60common event callbacks from SysUI via the `ShellController`.  This includes things like:
61
62- Configuration changes
63- Keyguard events
64- Shell init
65- Shell dumps & commands
66
67For other events which are specific to the Shell feature, then you can add callback methods on
68the Shell feature interface.  Any such calls should <u>**never**</u> be synchronous calls as
69they will need to post to the Shell main thread to run.
70
71## Shell commands & Dumps
72
73Since the Shell library is a part of the SysUI process, it relies on SysUI to trigger commands
74on individual Shell components, or to dump individual shell components.
75
76```shell
77# Dump everything
78adb shell dumpsys activity service SystemUIService WMShell
79
80# Run a specific command
81adb shell dumpsys activity service SystemUIService WMShell help
82adb shell dumpsys activity service SystemUIService WMShell <cmd> <args> ...
83```