1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.example.tracing.demo 17 18 import com.example.tracing.demo.experiments.CancellableSharedFlow 19 import com.example.tracing.demo.experiments.CollectFlow 20 import com.example.tracing.demo.experiments.CombineDeferred 21 import com.example.tracing.demo.experiments.Experiment 22 import com.example.tracing.demo.experiments.LaunchNested 23 import com.example.tracing.demo.experiments.LaunchSequentially 24 import com.example.tracing.demo.experiments.LeakySharedFlow 25 import com.example.tracing.demo.experiments.SharedFlowUsage 26 import com.example.tracing.demo.experiments.startThreadWithLooper 27 import dagger.Binds 28 import dagger.Component 29 import dagger.Module 30 import dagger.Provides 31 import dagger.multibindings.ClassKey 32 import dagger.multibindings.IntoMap 33 import javax.inject.Provider 34 import javax.inject.Qualifier 35 import javax.inject.Singleton 36 import kotlin.annotation.AnnotationRetention.RUNTIME 37 import kotlinx.coroutines.CoroutineDispatcher 38 import kotlinx.coroutines.Dispatchers 39 import kotlinx.coroutines.android.asCoroutineDispatcher 40 41 @Qualifier @MustBeDocumented @Retention(RUNTIME) annotation class Main 42 43 @Qualifier @MustBeDocumented @Retention(RUNTIME) annotation class Default 44 45 @Qualifier @MustBeDocumented @Retention(RUNTIME) annotation class IO 46 47 @Qualifier @MustBeDocumented @Retention(RUNTIME) annotation class Unconfined 48 49 @Qualifier @MustBeDocumented @Retention(RUNTIME) annotation class FixedThreadA 50 51 @Qualifier @MustBeDocumented @Retention(RUNTIME) annotation class FixedThreadB 52 53 @Qualifier @MustBeDocumented @Retention(RUNTIME) annotation class FixedThreadC 54 55 @Qualifier @MustBeDocumented @Retention(RUNTIME) annotation class FixedThreadD 56 57 @Module 58 class ConcurrencyModule { 59 60 @Provides 61 @Singleton 62 @Default provideDefaultDispatchernull63 fun provideDefaultDispatcher(): CoroutineDispatcher { 64 return Dispatchers.Default 65 } 66 67 @Provides 68 @Singleton 69 @IO provideIODispatchernull70 fun provideIODispatcher(): CoroutineDispatcher { 71 return Dispatchers.IO 72 } 73 74 @Provides 75 @Singleton 76 @Unconfined provideUnconfinedDispatchernull77 fun provideUnconfinedDispatcher(): CoroutineDispatcher { 78 return Dispatchers.Unconfined 79 } 80 81 @Provides 82 @Singleton 83 @FixedThreadA provideDispatcherAnull84 fun provideDispatcherA(): CoroutineDispatcher { 85 return startThreadWithLooper("Thread:A").threadHandler.asCoroutineDispatcher() 86 } 87 88 @Provides 89 @Singleton 90 @FixedThreadB provideDispatcherBnull91 fun provideDispatcherB(): CoroutineDispatcher { 92 return startThreadWithLooper("Thread:B").threadHandler.asCoroutineDispatcher() 93 } 94 95 @Provides 96 @Singleton 97 @FixedThreadC provideDispatcherCnull98 fun provideDispatcherC(): CoroutineDispatcher { 99 return startThreadWithLooper("Thread:C").threadHandler.asCoroutineDispatcher() 100 } 101 102 @Provides 103 @Singleton 104 @FixedThreadD provideDispatcherDnull105 fun provideDispatcherD(): CoroutineDispatcher { 106 return startThreadWithLooper("Thread:D").threadHandler.asCoroutineDispatcher() 107 } 108 } 109 110 @Module 111 interface ExperimentModule { 112 @Binds 113 @IntoMap 114 @ClassKey(CollectFlow::class) bindCollectFlownull115 fun bindCollectFlow(service: CollectFlow): Experiment 116 117 @Binds 118 @IntoMap 119 @ClassKey(SharedFlowUsage::class) 120 fun bindSharedFlowUsage(service: SharedFlowUsage): Experiment 121 122 @Binds 123 @IntoMap 124 @ClassKey(LeakySharedFlow::class) 125 fun bindLeakySharedFlow(service: LeakySharedFlow): Experiment 126 127 @Binds 128 @IntoMap 129 @ClassKey(CancellableSharedFlow::class) 130 fun bindCancellableSharedFlow(service: CancellableSharedFlow): Experiment 131 132 @Binds 133 @IntoMap 134 @ClassKey(CombineDeferred::class) 135 fun bindCombineDeferred(service: CombineDeferred): Experiment 136 137 @Binds 138 @IntoMap 139 @ClassKey(LaunchNested::class) 140 fun bindLaunchNested(service: LaunchNested): Experiment 141 142 @Binds 143 @IntoMap 144 @ClassKey(LaunchSequentially::class) 145 fun bindLaunchSequentially(service: LaunchSequentially): Experiment 146 } 147 148 @Singleton 149 @Component(modules = [ConcurrencyModule::class, ExperimentModule::class]) 150 interface ApplicationComponent { 151 /** Returns [Experiment]s that should be used with the application. */ 152 @Singleton fun getAllExperiments(): Map<Class<*>, Provider<Experiment>> 153 } 154