diff options
Diffstat (limited to 'java/com/android/dialer/common')
5 files changed, 159 insertions, 71 deletions
diff --git a/java/com/android/dialer/common/concurrent/Annotations.java b/java/com/android/dialer/common/concurrent/Annotations.java new file mode 100644 index 000000000..eb956c31e --- /dev/null +++ b/java/com/android/dialer/common/concurrent/Annotations.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +package com.android.dialer.common.concurrent; + +import javax.inject.Qualifier; + +/** Annotations for dagger concurrency bindings. */ +public class Annotations { + + /** Annotation for retrieving the non-UI thread pool. */ + @Qualifier + public @interface NonUiParallel {} + + /** Annotation for retrieving the non-UI serial executor. */ + @Qualifier + public @interface NonUiSerial {} + + /** Annotation for retrieving the UI thread pool. */ + @Qualifier + public @interface UiParallel {} + + /** Annotation for retrieving the UI serial executor. */ + @Qualifier + public @interface UiSerial {} +} diff --git a/java/com/android/dialer/common/concurrent/DefaultDialerExecutorFactory.java b/java/com/android/dialer/common/concurrent/DefaultDialerExecutorFactory.java index a87bbceb4..ab01654aa 100644 --- a/java/com/android/dialer/common/concurrent/DefaultDialerExecutorFactory.java +++ b/java/com/android/dialer/common/concurrent/DefaultDialerExecutorFactory.java @@ -17,29 +17,43 @@ package com.android.dialer.common.concurrent; import android.app.FragmentManager; -import android.os.AsyncTask; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.Annotations.NonUiParallel; +import com.android.dialer.common.concurrent.Annotations.NonUiSerial; +import com.android.dialer.common.concurrent.Annotations.UiParallel; +import com.android.dialer.common.concurrent.Annotations.UiSerial; import com.android.dialer.common.concurrent.DialerExecutor.Builder; import com.android.dialer.common.concurrent.DialerExecutor.FailureListener; import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener; import com.android.dialer.common.concurrent.DialerExecutor.Worker; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import javax.inject.Inject; /** The production {@link DialerExecutorFactory}. */ public class DefaultDialerExecutorFactory implements DialerExecutorFactory { + private final ExecutorService nonUiThreadPool; + private final ScheduledExecutorService nonUiSerialExecutor; + private final Executor uiThreadPool; + private final ScheduledExecutorService uiSerialExecutor; @Inject - public DefaultDialerExecutorFactory() {} + DefaultDialerExecutorFactory( + @NonUiParallel ExecutorService nonUiThreadPool, + @NonUiSerial ScheduledExecutorService nonUiSerialExecutor, + @UiParallel Executor uiThreadPool, + @UiSerial ScheduledExecutorService uiSerialExecutor) { + this.nonUiThreadPool = nonUiThreadPool; + this.nonUiSerialExecutor = nonUiSerialExecutor; + this.uiThreadPool = uiThreadPool; + this.uiSerialExecutor = uiSerialExecutor; + } @Override @NonNull @@ -48,14 +62,18 @@ public class DefaultDialerExecutorFactory implements DialerExecutorFactory { @NonNull String taskId, @NonNull Worker<InputT, OutputT> worker) { return new UiTaskBuilder<>( - Assert.isNotNull(fragmentManager), Assert.isNotNull(taskId), Assert.isNotNull(worker)); + Assert.isNotNull(fragmentManager), + Assert.isNotNull(taskId), + Assert.isNotNull(worker), + uiSerialExecutor, + uiThreadPool); } @Override @NonNull public <InputT, OutputT> DialerExecutor.Builder<InputT, OutputT> createNonUiTaskBuilder( @NonNull Worker<InputT, OutputT> worker) { - return new NonUiTaskBuilder<>(Assert.isNotNull(worker)); + return new NonUiTaskBuilder<>(Assert.isNotNull(worker), nonUiSerialExecutor, nonUiThreadPool); } private abstract static class BaseTaskBuilder<InputT, OutputT> @@ -96,34 +114,11 @@ public class DefaultDialerExecutorFactory implements DialerExecutorFactory { /** Convenience class for use by {@link DialerExecutorFactory} implementations. */ public static class UiTaskBuilder<InputT, OutputT> extends BaseTaskBuilder<InputT, OutputT> { - private static final ScheduledExecutorService defaultSerialExecutorService = - Executors.newSingleThreadScheduledExecutor( - new ThreadFactory() { - @Override - public Thread newThread(Runnable runnable) { - LogUtil.i("UiTaskBuilder.newThread", "creating serial thread"); - Thread thread = new Thread(runnable, "UiTaskBuilder-Serial"); - thread.setPriority(5); // Corresponds to Process.THREAD_PRIORITY_DEFAULT - return thread; - } - }); - - private static final Executor defaultParallelExecutorService = AsyncTask.THREAD_POOL_EXECUTOR; - private final FragmentManager fragmentManager; private final String id; private DialerUiTaskFragment<InputT, OutputT> dialerUiTaskFragment; - UiTaskBuilder(FragmentManager fragmentManager, String id, Worker<InputT, OutputT> worker) { - this( - fragmentManager, - id, - worker, - defaultSerialExecutorService, - defaultParallelExecutorService); - } - public UiTaskBuilder( FragmentManager fragmentManager, String id, @@ -153,24 +148,6 @@ public class DefaultDialerExecutorFactory implements DialerExecutorFactory { /** Convenience class for use by {@link DialerExecutorFactory} implementations. */ public static class NonUiTaskBuilder<InputT, OutputT> extends BaseTaskBuilder<InputT, OutputT> { - private static final ScheduledExecutorService defaultSerialExecutorService = - Executors.newSingleThreadScheduledExecutor( - new ThreadFactory() { - @Override - public Thread newThread(Runnable runnable) { - LogUtil.i("NonUiTaskBuilder.newThread", "creating serial thread"); - Thread thread = new Thread(runnable, "NonUiTaskBuilder-Serial"); - thread.setPriority(4); // Corresponds to Process.THREAD_PRIORITY_BACKGROUND - return thread; - } - }); - - private static final Executor defaultParallelExecutor = - DialerExecutors.getLowPriorityThreadPool(); - - NonUiTaskBuilder(Worker<InputT, OutputT> worker) { - this(worker, defaultSerialExecutorService, defaultParallelExecutor); - } public NonUiTaskBuilder( Worker<InputT, OutputT> worker, diff --git a/java/com/android/dialer/common/concurrent/DialerExecutorComponent.java b/java/com/android/dialer/common/concurrent/DialerExecutorComponent.java index 25033251f..346fdda56 100644 --- a/java/com/android/dialer/common/concurrent/DialerExecutorComponent.java +++ b/java/com/android/dialer/common/concurrent/DialerExecutorComponent.java @@ -17,8 +17,10 @@ package com.android.dialer.common.concurrent; import android.content.Context; +import com.android.dialer.common.concurrent.Annotations.NonUiParallel; import com.android.dialer.inject.HasRootComponent; import dagger.Subcomponent; +import java.util.concurrent.ExecutorService; /** Dagger component which provides a {@link DialerExecutorFactory}. */ @Subcomponent @@ -26,6 +28,9 @@ public abstract class DialerExecutorComponent { public abstract DialerExecutorFactory dialerExecutorFactory(); + @NonUiParallel + public abstract ExecutorService lowPriorityThreadPool(); + public static DialerExecutorComponent get(Context context) { return ((DialerExecutorComponent.HasComponent) ((HasRootComponent) context.getApplicationContext()).component()) diff --git a/java/com/android/dialer/common/concurrent/DialerExecutorModule.java b/java/com/android/dialer/common/concurrent/DialerExecutorModule.java index 281f88c15..68910fb7a 100644 --- a/java/com/android/dialer/common/concurrent/DialerExecutorModule.java +++ b/java/com/android/dialer/common/concurrent/DialerExecutorModule.java @@ -15,14 +15,85 @@ */ package com.android.dialer.common.concurrent; +import android.os.AsyncTask; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.Annotations.NonUiParallel; +import com.android.dialer.common.concurrent.Annotations.NonUiSerial; +import com.android.dialer.common.concurrent.Annotations.UiParallel; +import com.android.dialer.common.concurrent.Annotations.UiSerial; import dagger.Binds; import dagger.Module; +import dagger.Provides; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import javax.inject.Singleton; -/** Module which binds the production {@link DialerExecutorFactory}. */ +/** Module which provides concurrency bindings. */ @Module public abstract class DialerExecutorModule { @Binds abstract DialerExecutorFactory bindDialerExecutorFactory( DefaultDialerExecutorFactory defaultDialerExecutorFactory); + + @Provides + @Singleton + @NonUiParallel + static ExecutorService provideNonUiThreadPool() { + return Executors.newFixedThreadPool( + 5, + new ThreadFactory() { + @Override + public Thread newThread(Runnable runnable) { + LogUtil.i("DialerExecutorModule.newThread", "creating low priority thread"); + Thread thread = new Thread(runnable, "DialerExecutors-LowPriority"); + // Java thread priority 4 corresponds to Process.THREAD_PRIORITY_BACKGROUND (10) + thread.setPriority(4); + return thread; + } + }); + } + + @Provides + @Singleton + @NonUiSerial + static ScheduledExecutorService provideNonUiSerialExecutorService() { + return Executors.newSingleThreadScheduledExecutor( + new ThreadFactory() { + @Override + public Thread newThread(Runnable runnable) { + LogUtil.i("NonUiTaskBuilder.newThread", "creating serial thread"); + Thread thread = new Thread(runnable, "DialerExecutors-LowPriority-Serial"); + // Java thread priority 4 corresponds to Process.THREAD_PRIORITY_BACKGROUND (10) + thread.setPriority(4); + return thread; + } + }); + } + + @Provides + @UiParallel + static Executor provideUiThreadPool() { + return AsyncTask.THREAD_POOL_EXECUTOR; + } + + @Provides + @Singleton + @UiSerial + static ScheduledExecutorService provideUiSerialExecutorService() { + return Executors.newSingleThreadScheduledExecutor( + new ThreadFactory() { + @Override + public Thread newThread(Runnable runnable) { + LogUtil.i("DialerExecutorModule.newThread", "creating serial thread"); + Thread thread = new Thread(runnable, "DialerExecutors-HighPriority-Serial"); + // Java thread priority 5 corresponds to Process.THREAD_PRIORITY_DEFAULT (0) + thread.setPriority(5); + return thread; + } + }); + } } diff --git a/java/com/android/dialer/common/concurrent/DialerExecutors.java b/java/com/android/dialer/common/concurrent/DialerExecutors.java index 850c28cdd..4d8331fb6 100644 --- a/java/com/android/dialer/common/concurrent/DialerExecutors.java +++ b/java/com/android/dialer/common/concurrent/DialerExecutors.java @@ -17,13 +17,11 @@ package com.android.dialer.common.concurrent; import android.app.FragmentManager; +import android.content.Context; import android.support.annotation.NonNull; import com.android.dialer.common.Assert; -import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DialerExecutor.Worker; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; /** * Factory methods for creating {@link DialerExecutor} objects for doing background work. @@ -118,44 +116,43 @@ import java.util.concurrent.ThreadFactory; */ public final class DialerExecutors { - /** @see DialerExecutorFactory#createUiTaskBuilder(FragmentManager, String, Worker) */ + /** + * @param context any valid context object from which the application context can be retrieved + * @see DialerExecutorFactory#createUiTaskBuilder(FragmentManager, String, Worker) + */ @NonNull public static <InputT, OutputT> DialerExecutor.Builder<InputT, OutputT> createUiTaskBuilder( + @NonNull Context context, @NonNull FragmentManager fragmentManager, @NonNull String taskId, @NonNull Worker<InputT, OutputT> worker) { - return new DefaultDialerExecutorFactory() + return DialerExecutorComponent.get(Assert.isNotNull(context)) + .dialerExecutorFactory() .createUiTaskBuilder( Assert.isNotNull(fragmentManager), Assert.isNotNull(taskId), Assert.isNotNull(worker)); } - /** @see DialerExecutorFactory#createNonUiTaskBuilder(Worker) */ + /** + * @param context any valid context object from which the application context can be retrieved + * @see DialerExecutorFactory#createNonUiTaskBuilder(Worker) + */ @NonNull public static <InputT, OutputT> DialerExecutor.Builder<InputT, OutputT> createNonUiTaskBuilder( - @NonNull Worker<InputT, OutputT> worker) { - return new DefaultDialerExecutorFactory().createNonUiTaskBuilder(Assert.isNotNull(worker)); + Context context, @NonNull Worker<InputT, OutputT> worker) { + return DialerExecutorComponent.get(Assert.isNotNull(context)) + .dialerExecutorFactory() + .createNonUiTaskBuilder(Assert.isNotNull(worker)); } - private static final ExecutorService lowPriorityThreadPool = - Executors.newFixedThreadPool( - 5, - new ThreadFactory() { - @Override - public Thread newThread(Runnable runnable) { - LogUtil.i("DialerExecutors.newThread", "creating low priority thread"); - Thread thread = new Thread(runnable, "DialerExecutors-LowPriority"); - thread.setPriority(4); // Corresponds to Process.THREAD_PRIORITY_BACKGROUND - return thread; - } - }); - /** * An application-wide thread pool used for low priority (non-UI) tasks. * * <p>This exists to prevent each individual dialer component from having to create its own * threads/pools, which would result in the application having more threads than really necessary. + * + * @param context any valid context object from which the application context can be retrieved */ - public static ExecutorService getLowPriorityThreadPool() { - return lowPriorityThreadPool; + public static ExecutorService getLowPriorityThreadPool(@NonNull Context context) { + return DialerExecutorComponent.get(Assert.isNotNull(context)).lowPriorityThreadPool(); } } |