1 /*
2  * Copyright (C) 2019 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.systemui.util.concurrency;
18 
19 import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
20 
21 import android.os.Handler;
22 import android.os.HandlerThread;
23 import android.os.Looper;
24 import android.os.Process;
25 
26 import com.android.systemui.dagger.SysUISingleton;
27 import com.android.systemui.dagger.qualifiers.Background;
28 import com.android.systemui.dagger.qualifiers.BroadcastRunning;
29 import com.android.systemui.dagger.qualifiers.LongRunning;
30 import com.android.systemui.dagger.qualifiers.Main;
31 
32 import dagger.Module;
33 import dagger.Provides;
34 
35 import java.util.concurrent.Executor;
36 
37 import javax.inject.Named;
38 
39 /**
40  * Dagger Module for classes found within the concurrent package.
41  */
42 @Module
43 public abstract class SysUIConcurrencyModule {
44 
45     // Slow BG executor can potentially affect UI if UI is waiting for an updated state from this
46     // thread
47     private static final Long BG_SLOW_DISPATCH_THRESHOLD = 1000L;
48     private static final Long BG_SLOW_DELIVERY_THRESHOLD = 1000L;
49     private static final Long LONG_SLOW_DISPATCH_THRESHOLD = 2500L;
50     private static final Long LONG_SLOW_DELIVERY_THRESHOLD = 2500L;
51     private static final Long BROADCAST_SLOW_DISPATCH_THRESHOLD = 1000L;
52     private static final Long BROADCAST_SLOW_DELIVERY_THRESHOLD = 1000L;
53 
54     /** Background Looper */
55     @Provides
56     @SysUISingleton
57     @Background
provideBgLooper()58     public static Looper provideBgLooper() {
59         HandlerThread thread = new HandlerThread("SysUiBg",
60                 Process.THREAD_PRIORITY_BACKGROUND);
61         thread.start();
62         thread.getLooper().setSlowLogThresholdMs(BG_SLOW_DISPATCH_THRESHOLD,
63                 BG_SLOW_DELIVERY_THRESHOLD);
64         return thread.getLooper();
65     }
66 
67     /** BroadcastRunning Looper (for sending and receiving broadcasts) */
68     @Provides
69     @SysUISingleton
70     @BroadcastRunning
provideBroadcastRunningLooper()71     public static Looper provideBroadcastRunningLooper() {
72         HandlerThread thread = new HandlerThread("BroadcastRunning",
73                 Process.THREAD_PRIORITY_BACKGROUND);
74         thread.start();
75         thread.getLooper().setSlowLogThresholdMs(BROADCAST_SLOW_DISPATCH_THRESHOLD,
76                 BROADCAST_SLOW_DELIVERY_THRESHOLD);
77         return thread.getLooper();
78     }
79 
80     /** Long running tasks Looper */
81     @Provides
82     @SysUISingleton
83     @LongRunning
provideLongRunningLooper()84     public static Looper provideLongRunningLooper() {
85         HandlerThread thread = new HandlerThread("SysUiLng",
86                 Process.THREAD_PRIORITY_BACKGROUND);
87         thread.start();
88         thread.getLooper().setSlowLogThresholdMs(LONG_SLOW_DISPATCH_THRESHOLD,
89                 LONG_SLOW_DELIVERY_THRESHOLD);
90         return thread.getLooper();
91     }
92 
93     /**
94      * Background Handler.
95      *
96      * Prefer the Background Executor when possible.
97      */
98     @Provides
99     @Background
provideBgHandler(@ackground Looper bgLooper)100     public static Handler provideBgHandler(@Background Looper bgLooper) {
101         return new Handler(bgLooper);
102     }
103 
104     /**
105      * Provide a Background-Thread Executor by default.
106      */
107     @Provides
108     @SysUISingleton
provideExecutor(@ackground Looper looper)109     public static Executor provideExecutor(@Background Looper looper) {
110         return new ExecutorImpl(looper);
111     }
112 
113     /**
114      * Provide a BroadcastRunning Executor (for sending and receiving broadcasts).
115      */
116     @Provides
117     @SysUISingleton
118     @BroadcastRunning
provideBroadcastRunningExecutor(@roadcastRunning Looper looper)119     public static Executor provideBroadcastRunningExecutor(@BroadcastRunning Looper looper) {
120         return new ExecutorImpl(looper);
121     }
122 
123     /**
124      * Provide a Long running Executor.
125      */
126     @Provides
127     @SysUISingleton
128     @LongRunning
provideLongRunningExecutor(@ongRunning Looper looper)129     public static Executor provideLongRunningExecutor(@LongRunning Looper looper) {
130         return new ExecutorImpl(looper);
131     }
132 
133     /**
134      * Provide a Long running Executor.
135      */
136     @Provides
137     @SysUISingleton
138     @LongRunning
provideLongRunningDelayableExecutor( @ongRunning Looper looper)139     public static DelayableExecutor provideLongRunningDelayableExecutor(
140             @LongRunning Looper looper) {
141         return new ExecutorImpl(looper);
142     }
143 
144     /**
145      * Provide a Background-Thread Executor.
146      */
147     @Provides
148     @SysUISingleton
149     @Background
provideBackgroundExecutor(@ackground Looper looper)150     public static Executor provideBackgroundExecutor(@Background Looper looper) {
151         return new ExecutorImpl(looper);
152     }
153 
154     /**
155      * Provide a Background-Thread Executor by default.
156      */
157     @Provides
158     @SysUISingleton
provideDelayableExecutor(@ackground Looper looper)159     public static DelayableExecutor provideDelayableExecutor(@Background Looper looper) {
160         return new ExecutorImpl(looper);
161     }
162 
163     /**
164      * Provide a Background-Thread Executor.
165      */
166     @Provides
167     @SysUISingleton
168     @Background
provideBackgroundDelayableExecutor(@ackground Looper looper)169     public static DelayableExecutor provideBackgroundDelayableExecutor(@Background Looper looper) {
170         return new ExecutorImpl(looper);
171     }
172 
173     /**
174      * Provide a Background-Thread Executor by default.
175      */
176     @Provides
177     @SysUISingleton
provideRepeatableExecutor(@ackground DelayableExecutor exec)178     public static RepeatableExecutor provideRepeatableExecutor(@Background DelayableExecutor exec) {
179         return new RepeatableExecutorImpl(exec);
180     }
181 
182     /**
183      * Provide a Background-Thread Executor.
184      */
185     @Provides
186     @SysUISingleton
187     @Background
provideBackgroundRepeatableExecutor( @ackground DelayableExecutor exec)188     public static RepeatableExecutor provideBackgroundRepeatableExecutor(
189             @Background DelayableExecutor exec) {
190         return new RepeatableExecutorImpl(exec);
191     }
192 
193     /**
194      * Provide a Main-Thread Executor.
195      */
196     @Provides
197     @SysUISingleton
198     @Main
provideMainRepeatableExecutor(@ain DelayableExecutor exec)199     public static RepeatableExecutor provideMainRepeatableExecutor(@Main DelayableExecutor exec) {
200         return new RepeatableExecutorImpl(exec);
201     }
202 
203     /** */
204     @Provides
205     @Main
providesMainMessageRouter( @ain DelayableExecutor executor)206     public static MessageRouter providesMainMessageRouter(
207             @Main DelayableExecutor executor) {
208         return new MessageRouterImpl(executor);
209     }
210 
211     /** */
212     @Provides
213     @Background
providesBackgroundMessageRouter( @ackground DelayableExecutor executor)214     public static MessageRouter providesBackgroundMessageRouter(
215             @Background DelayableExecutor executor) {
216         return new MessageRouterImpl(executor);
217     }
218 
219     /** */
220     @Provides
221     @SysUISingleton
222     @Named(TIME_TICK_HANDLER_NAME)
provideTimeTickHandler()223     public static Handler provideTimeTickHandler() {
224         HandlerThread thread = new HandlerThread("TimeTick");
225         thread.start();
226         return new Handler(thread.getLooper());
227     }
228 }
229