1 /*
2  * Copyright (C) 2017 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.dialer.common.concurrent;
17 
18 import android.os.AsyncTask;
19 import com.android.dialer.common.LogUtil;
20 import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
21 import com.android.dialer.common.concurrent.Annotations.LightweightExecutor;
22 import com.android.dialer.common.concurrent.Annotations.NonUiParallel;
23 import com.android.dialer.common.concurrent.Annotations.NonUiSerial;
24 import com.android.dialer.common.concurrent.Annotations.Ui;
25 import com.android.dialer.common.concurrent.Annotations.UiParallel;
26 import com.android.dialer.common.concurrent.Annotations.UiSerial;
27 import com.google.common.util.concurrent.ListeningExecutorService;
28 import com.google.common.util.concurrent.MoreExecutors;
29 import dagger.Binds;
30 import dagger.Module;
31 import dagger.Provides;
32 import java.util.concurrent.ExecutorService;
33 import java.util.concurrent.Executors;
34 import java.util.concurrent.ScheduledExecutorService;
35 import java.util.concurrent.ThreadFactory;
36 import javax.inject.Singleton;
37 
38 /** Module which provides concurrency bindings. */
39 @Module
40 public abstract class DialerExecutorModule {
41 
42   @Binds
bindDialerExecutorFactory( DefaultDialerExecutorFactory defaultDialerExecutorFactory)43   abstract DialerExecutorFactory bindDialerExecutorFactory(
44       DefaultDialerExecutorFactory defaultDialerExecutorFactory);
45 
46   @Provides
47   @Singleton
48   @Ui
provideUiThreadExecutorService()49   static ListeningExecutorService provideUiThreadExecutorService() {
50     return new UiThreadExecutor();
51   }
52 
53   @Provides
54   @Singleton
55   @NonUiParallel
provideNonUiThreadPool()56   static ExecutorService provideNonUiThreadPool() {
57     return Executors.newFixedThreadPool(
58         5,
59         new ThreadFactory() {
60           @Override
61           public Thread newThread(Runnable runnable) {
62             LogUtil.i("DialerExecutorModule.newThread", "creating low priority thread");
63             Thread thread = new Thread(runnable, "DialerExecutors-LowPriority");
64             // Java thread priority 4 corresponds to Process.THREAD_PRIORITY_BACKGROUND (10)
65             thread.setPriority(4);
66             return thread;
67           }
68         });
69   }
70 
71   @Provides
72   @Singleton
73   @NonUiSerial
74   static ScheduledExecutorService provideNonUiSerialExecutorService() {
75     return Executors.newSingleThreadScheduledExecutor(
76         new ThreadFactory() {
77           @Override
78           public Thread newThread(Runnable runnable) {
79             LogUtil.i("NonUiTaskBuilder.newThread", "creating serial thread");
80             Thread thread = new Thread(runnable, "DialerExecutors-LowPriority-Serial");
81             // Java thread priority 4 corresponds to Process.THREAD_PRIORITY_BACKGROUND (10)
82             thread.setPriority(4);
83             return thread;
84           }
85         });
86   }
87 
88   @Provides
89   @UiParallel
90   static ExecutorService provideUiThreadPool() {
91     return (ExecutorService) AsyncTask.THREAD_POOL_EXECUTOR;
92   }
93 
94   @Provides
95   @Singleton
96   @UiSerial
97   static ScheduledExecutorService provideUiSerialExecutorService() {
98     return Executors.newSingleThreadScheduledExecutor(
99         new ThreadFactory() {
100           @Override
101           public Thread newThread(Runnable runnable) {
102             LogUtil.i("DialerExecutorModule.newThread", "creating serial thread");
103             Thread thread = new Thread(runnable, "DialerExecutors-HighPriority-Serial");
104             // Java thread priority 5 corresponds to Process.THREAD_PRIORITY_DEFAULT (0)
105             thread.setPriority(5);
106             return thread;
107           }
108         });
109   }
110 
111   @Provides
112   @Singleton
113   @LightweightExecutor
114   static ListeningExecutorService provideLightweightExecutor(@UiParallel ExecutorService delegate) {
115     return MoreExecutors.listeningDecorator(delegate);
116   }
117 
118   @Provides
119   @Singleton
120   @BackgroundExecutor
121   static ListeningExecutorService provideBackgroundExecutor(
122       @NonUiParallel ExecutorService delegate) {
123     return MoreExecutors.listeningDecorator(delegate);
124   }
125 }
126