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