1/*
2 * Copyright (C) 2011 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
17package com.android.dialer.common.concurrent;
18
19import android.os.AsyncTask;
20import android.support.annotation.MainThread;
21import com.android.dialer.common.Assert;
22import java.util.concurrent.Executor;
23
24/**
25 * Factory methods for creating AsyncTaskExecutors.
26 *
27 * <p>All of the factory methods on this class check first to see if you have set a static {@link
28 * AsyncTaskExecutorFactory} set through the {@link #setFactoryForTest(AsyncTaskExecutorFactory)}
29 * method, and if so delegate to that instead, which is one way of injecting dependencies for
30 * testing classes whose construction cannot be controlled such as {@link android.app.Activity}.
31 */
32public final class AsyncTaskExecutors {
33
34  /**
35   * A single instance of the {@link AsyncTaskExecutorFactory}, to which we delegate if it is
36   * non-null, for injecting when testing.
37   */
38  private static AsyncTaskExecutorFactory injectedAsyncTaskExecutorFactory = null;
39
40  /**
41   * Creates an AsyncTaskExecutor that submits tasks to run with {@link AsyncTask#SERIAL_EXECUTOR}.
42   */
43  public static AsyncTaskExecutor createAsyncTaskExecutor() {
44    synchronized (AsyncTaskExecutors.class) {
45      if (injectedAsyncTaskExecutorFactory != null) {
46        return injectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
47      }
48      return new SimpleAsyncTaskExecutor(AsyncTask.SERIAL_EXECUTOR);
49    }
50  }
51
52  /**
53   * Creates an AsyncTaskExecutor that submits tasks to run with {@link
54   * AsyncTask#THREAD_POOL_EXECUTOR}.
55   */
56  public static AsyncTaskExecutor createThreadPoolExecutor() {
57    synchronized (AsyncTaskExecutors.class) {
58      if (injectedAsyncTaskExecutorFactory != null) {
59        return injectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
60      }
61      return new SimpleAsyncTaskExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
62    }
63  }
64
65  public static void setFactoryForTest(AsyncTaskExecutorFactory factory) {
66    synchronized (AsyncTaskExecutors.class) {
67      injectedAsyncTaskExecutorFactory = factory;
68    }
69  }
70
71  /** Interface for creating AsyncTaskExecutor objects. */
72  public interface AsyncTaskExecutorFactory {
73
74    AsyncTaskExecutor createAsyncTaskExeuctor();
75  }
76
77  static class SimpleAsyncTaskExecutor implements AsyncTaskExecutor {
78
79    private final Executor executor;
80
81    public SimpleAsyncTaskExecutor(Executor executor) {
82      this.executor = executor;
83    }
84
85    @Override
86    @MainThread
87    public <T> AsyncTask<T, ?, ?> submit(Object identifer, AsyncTask<T, ?, ?> task, T... params) {
88      Assert.isMainThread();
89      return task.executeOnExecutor(executor, params);
90    }
91  }
92}
93