xref: /aosp_15_r20/frameworks/base/packages/SystemUI/docs/dagger.md (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker# Dagger 2 in SystemUI
2*d57664e9SAndroid Build Coastguard Worker*Dagger 2 is a dependency injection framework that compiles annotations to code
3*d57664e9SAndroid Build Coastguard Workerto create dependencies without reflection*
4*d57664e9SAndroid Build Coastguard Worker
5*d57664e9SAndroid Build Coastguard Worker## Recommended reading
6*d57664e9SAndroid Build Coastguard Worker
7*d57664e9SAndroid Build Coastguard WorkerGo read about Dagger 2.
8*d57664e9SAndroid Build Coastguard Worker
9*d57664e9SAndroid Build Coastguard Worker - [User's guide](https://google.github.io/dagger/users-guide)
10*d57664e9SAndroid Build Coastguard Worker
11*d57664e9SAndroid Build Coastguard Worker## State of the world
12*d57664e9SAndroid Build Coastguard Worker
13*d57664e9SAndroid Build Coastguard WorkerDagger 2 has been turned on for SystemUI and much of
14*d57664e9SAndroid Build Coastguard Worker[Dependency.java](../src/com/android/systemui/Dependency.java)
15*d57664e9SAndroid Build Coastguard Workerhas been converted to use Dagger. Since a lot of SystemUI depends on Dependency,
16*d57664e9SAndroid Build Coastguard Workerstubs have been added to Dependency to proxy any gets through to the instances
17*d57664e9SAndroid Build Coastguard Workerprovided by dagger, this will allow migration of SystemUI through a number of CLs.
18*d57664e9SAndroid Build Coastguard Worker
19*d57664e9SAndroid Build Coastguard Worker### How it works in SystemUI
20*d57664e9SAndroid Build Coastguard Worker
21*d57664e9SAndroid Build Coastguard WorkerThere are three high level "scopes" of concern in SystemUI. They all represent
22*d57664e9SAndroid Build Coastguard Workersingleton scopes, but serve different purposes.
23*d57664e9SAndroid Build Coastguard Worker
24*d57664e9SAndroid Build Coastguard Worker* `@Singleton` - Instances that are shared everywhere. There isn't a  lot of
25*d57664e9SAndroid Build Coastguard Worker   code in this scope. Things like the main thread, and Android Framework
26*d57664e9SAndroid Build Coastguard Worker   provided instances mostly.
27*d57664e9SAndroid Build Coastguard Worker* `@WMShell` - WindowManager related code in the SystemUI process. We don't
28*d57664e9SAndroid Build Coastguard Worker   want this code relying on the rest of SystemUI, and we don't want the rest
29*d57664e9SAndroid Build Coastguard Worker   of SystemUI peeking into its internals, so it runs in its own Subcomponent.
30*d57664e9SAndroid Build Coastguard Worker* `@SysUISingleton` - Most of what would be considered "SystemUI". Most feature
31*d57664e9SAndroid Build Coastguard Worker   work by SystemUI developers goes into this scope. Useful interfaces from
32*d57664e9SAndroid Build Coastguard Worker   WindowManager are made available inside this Subcomponent.
33*d57664e9SAndroid Build Coastguard Worker
34*d57664e9SAndroid Build Coastguard WorkerThe root dagger graph is created by an instance of `SystemUIInitializer`.
35*d57664e9SAndroid Build Coastguard WorkerSee [README.md](../README.md) for more details.
36*d57664e9SAndroid Build Coastguard WorkerFor the classes that we're using in Dependency and are switching to dagger, the
37*d57664e9SAndroid Build Coastguard Workerequivalent dagger version is using `@Singleton` and therefore only has one instance.
38*d57664e9SAndroid Build Coastguard WorkerTo have the single instance span all of SystemUI and be easily accessible for
39*d57664e9SAndroid Build Coastguard Workerother components, there is a single root `@Component` that exists that generates
40*d57664e9SAndroid Build Coastguard Workerthese. The component lives in
41*d57664e9SAndroid Build Coastguard Worker[ReferenceGlobalRootComponent.java](../src/com/android/systemui/dagger/ReferenceGlobalRootComponent.java).
42*d57664e9SAndroid Build Coastguard Worker
43*d57664e9SAndroid Build Coastguard Worker### Adding a new injectable object
44*d57664e9SAndroid Build Coastguard Worker
45*d57664e9SAndroid Build Coastguard WorkerFirst annotate the constructor with `@Inject`. Also annotate it with
46*d57664e9SAndroid Build Coastguard Worker`@SysUISingleton` if only one instance should be created.
47*d57664e9SAndroid Build Coastguard Worker
48*d57664e9SAndroid Build Coastguard Worker```kotlin
49*d57664e9SAndroid Build Coastguard Worker@SysUISingleton
50*d57664e9SAndroid Build Coastguard Workerclass FeatureStartable
51*d57664e9SAndroid Build Coastguard Worker@Inject
52*d57664e9SAndroid Build Coastguard Workerconstructor(
53*d57664e9SAndroid Build Coastguard Worker/* ... */
54*d57664e9SAndroid Build Coastguard Worker) {
55*d57664e9SAndroid Build Coastguard Worker    // ...
56*d57664e9SAndroid Build Coastguard Worker}
57*d57664e9SAndroid Build Coastguard Worker```
58*d57664e9SAndroid Build Coastguard Worker
59*d57664e9SAndroid Build Coastguard WorkerIf you have an interface class and an implementation class, Dagger needs to
60*d57664e9SAndroid Build Coastguard Workerknow how to map it. The simplest way to do this is to add an `@Binds` method
61*d57664e9SAndroid Build Coastguard Workerin a module. The type of the return value tells dagger which dependency it's
62*d57664e9SAndroid Build Coastguard Workerproviding:
63*d57664e9SAndroid Build Coastguard Worker
64*d57664e9SAndroid Build Coastguard Worker```kotlin
65*d57664e9SAndroid Build Coastguard Worker@Module
66*d57664e9SAndroid Build Coastguard Workerabstract class FeatureModule {
67*d57664e9SAndroid Build Coastguard Worker    @Binds
68*d57664e9SAndroid Build Coastguard Worker    abstract fun bindsFeature(impl: FeatureImpl): Feature
69*d57664e9SAndroid Build Coastguard Worker}
70*d57664e9SAndroid Build Coastguard Worker```
71*d57664e9SAndroid Build Coastguard Worker
72*d57664e9SAndroid Build Coastguard WorkerIf you have a class that you want to make injectable that has can not
73*d57664e9SAndroid Build Coastguard Workerbe easily constructed by Dagger, write a `@Provides` method for it:
74*d57664e9SAndroid Build Coastguard Worker
75*d57664e9SAndroid Build Coastguard Worker```kotlin
76*d57664e9SAndroid Build Coastguard Worker@Module
77*d57664e9SAndroid Build Coastguard Workerabstract class FeatureModule {
78*d57664e9SAndroid Build Coastguard Worker    @Module
79*d57664e9SAndroid Build Coastguard Worker    companion object {
80*d57664e9SAndroid Build Coastguard Worker        @Provides
81*d57664e9SAndroid Build Coastguard Worker        fun providesFeature(ctx: Context): Feature {
82*d57664e9SAndroid Build Coastguard Worker            return FeatureImpl.constructFromContext(ctx)
83*d57664e9SAndroid Build Coastguard Worker        }
84*d57664e9SAndroid Build Coastguard Worker    }
85*d57664e9SAndroid Build Coastguard Worker}
86*d57664e9SAndroid Build Coastguard Worker```
87*d57664e9SAndroid Build Coastguard Worker
88*d57664e9SAndroid Build Coastguard Worker### Module Organization
89*d57664e9SAndroid Build Coastguard Worker
90*d57664e9SAndroid Build Coastguard WorkerPlease define your modules on _at least_ per-package level. If the scope of a
91*d57664e9SAndroid Build Coastguard Workerpackage grows to encompass a great number of features, create per-feature
92*d57664e9SAndroid Build Coastguard Workermodules.
93*d57664e9SAndroid Build Coastguard Worker
94*d57664e9SAndroid Build Coastguard Worker**Do not create catch-all modules.** Those quickly grow unwieldy and
95*d57664e9SAndroid Build Coastguard Workerunmaintainable. Any that exist today should be refactored into obsolescence.
96*d57664e9SAndroid Build Coastguard Worker
97*d57664e9SAndroid Build Coastguard WorkerYou can then include your module in one of three places:
98*d57664e9SAndroid Build Coastguard Worker
99*d57664e9SAndroid Build Coastguard Worker1) Within another module that depends on it. Ideally, this creates a clean
100*d57664e9SAndroid Build Coastguard Worker   dependency graph between features and utilities.
101*d57664e9SAndroid Build Coastguard Worker2) For features that should exist in all versions of SystemUI (AOSP and
102*d57664e9SAndroid Build Coastguard Worker   any variants), include the module in
103*d57664e9SAndroid Build Coastguard Worker   [SystemUIModule.java](../src/com/android/systemui/dagger/SystemUIModule.java).
104*d57664e9SAndroid Build Coastguard Worker3) For features that should exist only in AOSP, include the module in
105*d57664e9SAndroid Build Coastguard Worker   [ReferenceSystemUIModule.java](../src/com/android/systemui/dagger/ReferenceSystemUIModule.java).
106*d57664e9SAndroid Build Coastguard Worker   Similarly, if you are working on a custom version of SystemUI and have code
107*d57664e9SAndroid Build Coastguard Worker   specific to your version, include it in a module specific to your version.
108*d57664e9SAndroid Build Coastguard Worker
109*d57664e9SAndroid Build Coastguard Worker### Using injection with Fragments
110*d57664e9SAndroid Build Coastguard Worker
111*d57664e9SAndroid Build Coastguard WorkerFragments are created as part of the FragmentManager, so injectable Fragments need to be registered
112*d57664e9SAndroid Build Coastguard Workerso the manager knows how to create them. This is done via
113*d57664e9SAndroid Build Coastguard Worker[FragmentService#addFragmentInstantiationProvider](../src/com/android/systemui/fragments/FragmentService.java).
114*d57664e9SAndroid Build Coastguard WorkerPass it the class of your fragment and a `Provider` for your fragment at some time before your
115*d57664e9SAndroid Build Coastguard WorkerFragment is accessed.
116*d57664e9SAndroid Build Coastguard Worker
117*d57664e9SAndroid Build Coastguard WorkerWhen you need to create your fragment (i.e. for the add or replace transaction),
118*d57664e9SAndroid Build Coastguard Workerthen the FragmentHostManager can do this for you.
119*d57664e9SAndroid Build Coastguard Worker
120*d57664e9SAndroid Build Coastguard Worker```java
121*d57664e9SAndroid Build Coastguard WorkerFragmentHostManager.get(view).create(NavigationBarFragment.class);
122*d57664e9SAndroid Build Coastguard Worker```
123*d57664e9SAndroid Build Coastguard Worker
124*d57664e9SAndroid Build Coastguard Worker## Updating Dagger2
125*d57664e9SAndroid Build Coastguard Worker
126*d57664e9SAndroid Build Coastguard WorkerWe depend on the Dagger source found in external/dagger2. We should automatically pick up on updates
127*d57664e9SAndroid Build Coastguard Workerwhen that repository is updated.
128*d57664e9SAndroid Build Coastguard Worker
129*d57664e9SAndroid Build Coastguard Worker## TODO List
130*d57664e9SAndroid Build Coastguard Worker
131*d57664e9SAndroid Build Coastguard Worker - Eliminate usages of Dependency#get: http://b/hotlists/3940788
132