1 /*
2  * Copyright (C) 2023 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 
17 package com.android.intentresolver.inject
18 
19 import android.os.Handler
20 import android.os.HandlerThread
21 import android.os.Looper
22 import android.os.Process
23 import dagger.Module
24 import dagger.Provides
25 import dagger.hilt.InstallIn
26 import dagger.hilt.components.SingletonComponent
27 import javax.inject.Singleton
28 import kotlinx.coroutines.CoroutineDispatcher
29 import kotlinx.coroutines.CoroutineScope
30 import kotlinx.coroutines.Dispatchers
31 import kotlinx.coroutines.SupervisorJob
32 
33 // thread
34 private const val BROADCAST_SLOW_DISPATCH_THRESHOLD = 1000L
35 private const val BROADCAST_SLOW_DELIVERY_THRESHOLD = 1000L
36 
37 @Module
38 @InstallIn(SingletonComponent::class)
39 object ConcurrencyModule {
40 
mainDispatchernull41     @Provides @Main fun mainDispatcher(): CoroutineDispatcher = Dispatchers.Main.immediate
42 
43     /** Injectable alternative to [MainScope()][kotlinx.coroutines.MainScope] */
44     @Provides
45     @Singleton
46     @Main
47     fun mainCoroutineScope(@Main mainDispatcher: CoroutineDispatcher) =
48         CoroutineScope(SupervisorJob() + mainDispatcher)
49 
50     @Provides @Background fun backgroundDispatcher(): CoroutineDispatcher = Dispatchers.IO
51 
52     @Provides
53     @Singleton
54     @Broadcast
55     fun provideBroadcastLooper(): Looper {
56         val thread = HandlerThread("BroadcastReceiver", Process.THREAD_PRIORITY_BACKGROUND)
57         thread.start()
58         thread.looper.setSlowLogThresholdMs(
59             BROADCAST_SLOW_DISPATCH_THRESHOLD,
60             BROADCAST_SLOW_DELIVERY_THRESHOLD
61         )
62         return thread.looper
63     }
64 
65     /** Provide a BroadcastReceiver Executor (for sending and receiving broadcasts). */
66     @Provides
67     @Singleton
68     @Broadcast
provideBroadcastHandlernull69     fun provideBroadcastHandler(@Broadcast looper: Looper): Handler {
70         return Handler(looper)
71     }
72 }
73