191197049c458f07092b31501d2ed512180b13d58Chiao Cheng/*
291197049c458f07092b31501d2ed512180b13d58Chiao Cheng * Copyright (C) 2011 The Android Open Source Project
391197049c458f07092b31501d2ed512180b13d58Chiao Cheng *
491197049c458f07092b31501d2ed512180b13d58Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
591197049c458f07092b31501d2ed512180b13d58Chiao Cheng * you may not use this file except in compliance with the License.
691197049c458f07092b31501d2ed512180b13d58Chiao Cheng * You may obtain a copy of the License at
791197049c458f07092b31501d2ed512180b13d58Chiao Cheng *
891197049c458f07092b31501d2ed512180b13d58Chiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
991197049c458f07092b31501d2ed512180b13d58Chiao Cheng *
1091197049c458f07092b31501d2ed512180b13d58Chiao Cheng * Unless required by applicable law or agreed to in writing, software
1191197049c458f07092b31501d2ed512180b13d58Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
1291197049c458f07092b31501d2ed512180b13d58Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1391197049c458f07092b31501d2ed512180b13d58Chiao Cheng * See the License for the specific language governing permissions and
1491197049c458f07092b31501d2ed512180b13d58Chiao Cheng * limitations under the License.
1591197049c458f07092b31501d2ed512180b13d58Chiao Cheng */
1691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
1791197049c458f07092b31501d2ed512180b13d58Chiao Chengpackage com.android.dialer.util;
1891197049c458f07092b31501d2ed512180b13d58Chiao Cheng
1991197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.os.AsyncTask;
2091197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.os.Looper;
2191197049c458f07092b31501d2ed512180b13d58Chiao Cheng
22e38e9ab6195950d2083efde283788b91d03354c4Yorke Leeimport com.android.contacts.common.testing.NeededForTesting;
2391197049c458f07092b31501d2ed512180b13d58Chiao Chengimport com.google.common.base.Preconditions;
2491197049c458f07092b31501d2ed512180b13d58Chiao Cheng
2591197049c458f07092b31501d2ed512180b13d58Chiao Chengimport java.util.concurrent.Executor;
2691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
2791197049c458f07092b31501d2ed512180b13d58Chiao Cheng/**
2891197049c458f07092b31501d2ed512180b13d58Chiao Cheng * Factory methods for creating AsyncTaskExecutors.
2991197049c458f07092b31501d2ed512180b13d58Chiao Cheng * <p>
3091197049c458f07092b31501d2ed512180b13d58Chiao Cheng * All of the factory methods on this class check first to see if you have set a static
3191197049c458f07092b31501d2ed512180b13d58Chiao Cheng * {@link AsyncTaskExecutorFactory} set through the
3291197049c458f07092b31501d2ed512180b13d58Chiao Cheng * {@link #setFactoryForTest(AsyncTaskExecutorFactory)} method, and if so delegate to that instead,
3391197049c458f07092b31501d2ed512180b13d58Chiao Cheng * which is one way of injecting dependencies for testing classes whose construction cannot be
3491197049c458f07092b31501d2ed512180b13d58Chiao Cheng * controlled such as {@link android.app.Activity}.
3591197049c458f07092b31501d2ed512180b13d58Chiao Cheng */
3691197049c458f07092b31501d2ed512180b13d58Chiao Chengpublic final class AsyncTaskExecutors {
3791197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /**
3891197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * A single instance of the {@link AsyncTaskExecutorFactory}, to which we delegate if it is
3991197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * non-null, for injecting when testing.
4091197049c458f07092b31501d2ed512180b13d58Chiao Cheng     */
4191197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private static AsyncTaskExecutorFactory mInjectedAsyncTaskExecutorFactory = null;
4291197049c458f07092b31501d2ed512180b13d58Chiao Cheng
4391197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /**
4491197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Creates an AsyncTaskExecutor that submits tasks to run with
4591197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * {@link AsyncTask#SERIAL_EXECUTOR}.
4691197049c458f07092b31501d2ed512180b13d58Chiao Cheng     */
4791197049c458f07092b31501d2ed512180b13d58Chiao Cheng    public static AsyncTaskExecutor createAsyncTaskExecutor() {
4891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        synchronized (AsyncTaskExecutors.class) {
4991197049c458f07092b31501d2ed512180b13d58Chiao Cheng            if (mInjectedAsyncTaskExecutorFactory != null) {
5091197049c458f07092b31501d2ed512180b13d58Chiao Cheng                return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
5191197049c458f07092b31501d2ed512180b13d58Chiao Cheng            }
5291197049c458f07092b31501d2ed512180b13d58Chiao Cheng            return new SimpleAsyncTaskExecutor(AsyncTask.SERIAL_EXECUTOR);
5391197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
5491197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
5591197049c458f07092b31501d2ed512180b13d58Chiao Cheng
5691197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /**
5791197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Creates an AsyncTaskExecutor that submits tasks to run with
5891197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * {@link AsyncTask#THREAD_POOL_EXECUTOR}.
5991197049c458f07092b31501d2ed512180b13d58Chiao Cheng     */
6091197049c458f07092b31501d2ed512180b13d58Chiao Cheng    public static AsyncTaskExecutor createThreadPoolExecutor() {
6191197049c458f07092b31501d2ed512180b13d58Chiao Cheng        synchronized (AsyncTaskExecutors.class) {
6291197049c458f07092b31501d2ed512180b13d58Chiao Cheng            if (mInjectedAsyncTaskExecutorFactory != null) {
6391197049c458f07092b31501d2ed512180b13d58Chiao Cheng                return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
6491197049c458f07092b31501d2ed512180b13d58Chiao Cheng            }
6591197049c458f07092b31501d2ed512180b13d58Chiao Cheng            return new SimpleAsyncTaskExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
6691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
6791197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
6891197049c458f07092b31501d2ed512180b13d58Chiao Cheng
6991197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /** Interface for creating AsyncTaskExecutor objects. */
7091197049c458f07092b31501d2ed512180b13d58Chiao Cheng    public interface AsyncTaskExecutorFactory {
7191197049c458f07092b31501d2ed512180b13d58Chiao Cheng        AsyncTaskExecutor createAsyncTaskExeuctor();
7291197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
7391197049c458f07092b31501d2ed512180b13d58Chiao Cheng
7491197049c458f07092b31501d2ed512180b13d58Chiao Cheng    @NeededForTesting
7591197049c458f07092b31501d2ed512180b13d58Chiao Cheng    public static void setFactoryForTest(AsyncTaskExecutorFactory factory) {
7691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        synchronized (AsyncTaskExecutors.class) {
7791197049c458f07092b31501d2ed512180b13d58Chiao Cheng            mInjectedAsyncTaskExecutorFactory = factory;
7891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
7991197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
8091197049c458f07092b31501d2ed512180b13d58Chiao Cheng
8191197049c458f07092b31501d2ed512180b13d58Chiao Cheng    public static void checkCalledFromUiThread() {
8291197049c458f07092b31501d2ed512180b13d58Chiao Cheng        Preconditions.checkState(Thread.currentThread() == Looper.getMainLooper().getThread(),
8391197049c458f07092b31501d2ed512180b13d58Chiao Cheng                "submit method must be called from ui thread, was: " + Thread.currentThread());
8491197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
8591197049c458f07092b31501d2ed512180b13d58Chiao Cheng
8691197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private static class SimpleAsyncTaskExecutor implements AsyncTaskExecutor {
8791197049c458f07092b31501d2ed512180b13d58Chiao Cheng        private final Executor mExecutor;
8891197049c458f07092b31501d2ed512180b13d58Chiao Cheng
8991197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public SimpleAsyncTaskExecutor(Executor executor) {
9091197049c458f07092b31501d2ed512180b13d58Chiao Cheng            mExecutor = executor;
9191197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
9291197049c458f07092b31501d2ed512180b13d58Chiao Cheng
9391197049c458f07092b31501d2ed512180b13d58Chiao Cheng        @Override
9491197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public <T> AsyncTask<T, ?, ?> submit(Object identifer, AsyncTask<T, ?, ?> task,
9591197049c458f07092b31501d2ed512180b13d58Chiao Cheng                T... params) {
9691197049c458f07092b31501d2ed512180b13d58Chiao Cheng            checkCalledFromUiThread();
9791197049c458f07092b31501d2ed512180b13d58Chiao Cheng            return task.executeOnExecutor(mExecutor, params);
9891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
9991197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
10091197049c458f07092b31501d2ed512180b13d58Chiao Cheng}
101