• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.android.systemui.util.concurrency
17 
18 import android.os.Handler
19 import android.os.HandlerThread
20 import android.os.Looper
21 import android.os.Process
22 import android.view.Choreographer
23 import com.android.systemui.Dependency
24 import com.android.systemui.Flags
25 import com.android.systemui.dagger.SysUISingleton
26 import com.android.systemui.dagger.qualifiers.Background
27 import com.android.systemui.dagger.qualifiers.BroadcastRunning
28 import com.android.systemui.dagger.qualifiers.LongRunning
29 import com.android.systemui.dagger.qualifiers.Main
30 import com.android.systemui.dagger.qualifiers.NotifInflation
31 import dagger.Module
32 import dagger.Provides
33 import java.util.concurrent.Executor
34 import javax.inject.Named
35 import javax.inject.Qualifier
36 
37 @Qualifier
38 @MustBeDocumented
39 @Retention(AnnotationRetention.RUNTIME)
40 annotation class BackPanelUiThread
41 
42 /** Dagger Module for classes found within the concurrent package. */
43 @Module
44 object SysUIConcurrencyModule {
45     // Slow BG executor can potentially affect UI if UI is waiting for an updated state from this
46     // thread
47     private const val BG_SLOW_DISPATCH_THRESHOLD = 1000L
48     private const val BG_SLOW_DELIVERY_THRESHOLD = 1000L
49     private const val LONG_SLOW_DISPATCH_THRESHOLD = 2500L
50     private const val LONG_SLOW_DELIVERY_THRESHOLD = 2500L
51     private const val BROADCAST_SLOW_DISPATCH_THRESHOLD = 1000L
52     private const val BROADCAST_SLOW_DELIVERY_THRESHOLD = 1000L
53     private const val NOTIFICATION_INFLATION_SLOW_DISPATCH_THRESHOLD = 1000L
54     private const val NOTIFICATION_INFLATION_SLOW_DELIVERY_THRESHOLD = 1000L
55 
56     /** Background Looper */
57     @Provides
58     @SysUISingleton
59     @Background
provideBgLoopernull60     fun provideBgLooper(): Looper {
61         val thread = HandlerThread("SysUiBg", Process.THREAD_PRIORITY_BACKGROUND)
62         thread.start()
63         thread
64             .getLooper()
65             .setSlowLogThresholdMs(BG_SLOW_DISPATCH_THRESHOLD, BG_SLOW_DELIVERY_THRESHOLD)
66         return thread.getLooper()
67     }
68 
69     /** BroadcastRunning Looper (for sending and receiving broadcasts) */
70     @Provides
71     @SysUISingleton
72     @BroadcastRunning
provideBroadcastRunningLoopernull73     fun provideBroadcastRunningLooper(): Looper {
74         val thread = HandlerThread("BroadcastRunning", Process.THREAD_PRIORITY_BACKGROUND)
75         thread.start()
76         thread
77             .getLooper()
78             .setSlowLogThresholdMs(
79                 BROADCAST_SLOW_DISPATCH_THRESHOLD,
80                 BROADCAST_SLOW_DELIVERY_THRESHOLD
81             )
82         return thread.getLooper()
83     }
84 
85     /** Long running tasks Looper */
86     @Provides
87     @SysUISingleton
88     @LongRunning
provideLongRunningLoopernull89     fun provideLongRunningLooper(): Looper {
90         val thread = HandlerThread("SysUiLng", Process.THREAD_PRIORITY_BACKGROUND)
91         thread.start()
92         thread
93             .getLooper()
94             .setSlowLogThresholdMs(LONG_SLOW_DISPATCH_THRESHOLD, LONG_SLOW_DELIVERY_THRESHOLD)
95         return thread.getLooper()
96     }
97 
98     /** Notification inflation Looper */
99     @Provides
100     @SysUISingleton
101     @NotifInflation
provideNotifInflationLoopernull102     fun provideNotifInflationLooper(@Background bgLooper: Looper): Looper {
103         if (!Flags.dedicatedNotifInflationThread()) {
104             return bgLooper
105         }
106         val thread = HandlerThread("NotifInflation", Process.THREAD_PRIORITY_BACKGROUND)
107         thread.start()
108         val looper = thread.getLooper()
109         looper.setSlowLogThresholdMs(
110             NOTIFICATION_INFLATION_SLOW_DISPATCH_THRESHOLD,
111             NOTIFICATION_INFLATION_SLOW_DELIVERY_THRESHOLD
112         )
113         return looper
114     }
115 
116     @Provides
117     @SysUISingleton
118     @BackPanelUiThread
provideBackPanelUiThreadContextnull119     fun provideBackPanelUiThreadContext(
120         @Main mainLooper: Looper,
121         @Main mainHandler: Handler,
122         @Main mainExecutor: Executor
123     ): UiThreadContext {
124         return if (Flags.edgeBackGestureHandlerThread()) {
125             val thread =
126                 HandlerThread("BackPanelUiThread", Process.THREAD_PRIORITY_DISPLAY).apply {
127                     start()
128                     looper.setSlowLogThresholdMs(
129                         LONG_SLOW_DISPATCH_THRESHOLD,
130                         LONG_SLOW_DELIVERY_THRESHOLD
131                     )
132                 }
133             UiThreadContext(
134                 thread.looper,
135                 thread.threadHandler,
136                 thread.threadExecutor,
137                 thread.threadHandler.runWithScissors { Choreographer.getInstance() }
138             )
139         } else {
140             UiThreadContext(
141                 mainLooper,
142                 mainHandler,
143                 mainExecutor,
144                 mainHandler.runWithScissors { Choreographer.getInstance() }
145             )
146         }
147     }
148 
149     /**
150      * Background Handler.
151      *
152      * Prefer the Background Executor when possible.
153      */
154     @Provides
155     @Background
provideBgHandlernull156     fun provideBgHandler(@Background bgLooper: Looper): Handler = Handler(bgLooper)
157 
158     /** Provide a BroadcastRunning Executor (for sending and receiving broadcasts). */
159     @Provides
160     @SysUISingleton
161     @BroadcastRunning
162     fun provideBroadcastRunningExecutor(@BroadcastRunning looper: Looper): Executor =
163         ExecutorImpl(looper)
164 
165     /** Provide a Long running Executor. */
166     @Provides
167     @SysUISingleton
168     @LongRunning
169     fun provideLongRunningExecutor(@LongRunning looper: Looper): Executor = ExecutorImpl(looper)
170 
171     /** Provide a Long running Executor. */
172     @Provides
173     @SysUISingleton
174     @LongRunning
175     fun provideLongRunningDelayableExecutor(@LongRunning looper: Looper): DelayableExecutor =
176         ExecutorImpl(looper)
177 
178     /** Provide a Background-Thread Executor. */
179     @Provides
180     @SysUISingleton
181     @Background
182     fun provideBackgroundExecutor(@Background looper: Looper): Executor = ExecutorImpl(looper)
183 
184     /** Provide a Background-Thread Executor. */
185     @Provides
186     @SysUISingleton
187     @Background
188     fun provideBackgroundDelayableExecutor(@Background looper: Looper): DelayableExecutor =
189         ExecutorImpl(looper)
190 
191     /** Provide a Background-Thread Executor. */
192     @Provides
193     @SysUISingleton
194     @Background
195     fun provideBackgroundRepeatableExecutor(
196         @Background exec: DelayableExecutor
197     ): RepeatableExecutor = RepeatableExecutorImpl(exec)
198 
199     /** Provide a Main-Thread Executor. */
200     @Provides
201     @SysUISingleton
202     @Main
203     fun provideMainRepeatableExecutor(@Main exec: DelayableExecutor): RepeatableExecutor =
204         RepeatableExecutorImpl(exec)
205 
206     /**  */
207     @Provides
208     @Main
209     fun providesMainMessageRouter(@Main executor: DelayableExecutor): MessageRouter =
210         MessageRouterImpl(executor)
211 
212     /**  */
213     @Provides
214     @Background
215     fun providesBackgroundMessageRouter(@Background executor: DelayableExecutor): MessageRouter =
216         MessageRouterImpl(executor)
217 
218     /**  */
219     @Provides
220     @SysUISingleton
221     @Named(Dependency.TIME_TICK_HANDLER_NAME)
222     fun provideTimeTickHandler(): Handler {
223         val thread = HandlerThread("TimeTick")
224         thread.start()
225         return Handler(thread.getLooper())
226     }
227 
228     /**  */
229     @Provides
230     @SysUISingleton
231     @NotifInflation
provideNotifInflationExecutornull232     fun provideNotifInflationExecutor(@NotifInflation looper: Looper): Executor =
233         ExecutorImpl(looper)
234 }
235