19c747ac625d212a10176082fba6b087035f5d144Hugo Hudson/*
29c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * Copyright (C) 2011 The Android Open Source Project
39c747ac625d212a10176082fba6b087035f5d144Hugo Hudson *
49c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * Licensed under the Apache License, Version 2.0 (the "License");
59c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * you may not use this file except in compliance with the License.
69c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * You may obtain a copy of the License at
79c747ac625d212a10176082fba6b087035f5d144Hugo Hudson *
89c747ac625d212a10176082fba6b087035f5d144Hugo Hudson *      http://www.apache.org/licenses/LICENSE-2.0
99c747ac625d212a10176082fba6b087035f5d144Hugo Hudson *
109c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * Unless required by applicable law or agreed to in writing, software
119c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * distributed under the License is distributed on an "AS IS" BASIS,
129c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * See the License for the specific language governing permissions and
149c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * limitations under the License.
159c747ac625d212a10176082fba6b087035f5d144Hugo Hudson */
169c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
179c747ac625d212a10176082fba6b087035f5d144Hugo Hudsonpackage com.android.contacts.util;
189c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
199c747ac625d212a10176082fba6b087035f5d144Hugo Hudsonimport com.android.contacts.test.NeededForTesting;
209c747ac625d212a10176082fba6b087035f5d144Hugo Hudsonimport com.google.common.base.Preconditions;
219c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
229c747ac625d212a10176082fba6b087035f5d144Hugo Hudsonimport android.os.AsyncTask;
239c747ac625d212a10176082fba6b087035f5d144Hugo Hudsonimport android.os.Looper;
249c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
259c747ac625d212a10176082fba6b087035f5d144Hugo Hudsonimport java.util.concurrent.Executor;
269c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
279c747ac625d212a10176082fba6b087035f5d144Hugo Hudson/**
289c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * Factory methods for creating AsyncTaskExecutors.
299c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * <p>
309c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * All of the factory methods on this class check first to see if you have set a static
319c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * {@link AsyncTaskExecutorFactory} set through the
329c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * {@link #setFactoryForTest(AsyncTaskExecutorFactory)} method, and if so delegate to that instead,
339c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * which is one way of injecting dependencies for testing classes whose construction cannot be
349c747ac625d212a10176082fba6b087035f5d144Hugo Hudson * controlled such as {@link android.app.Activity}.
359c747ac625d212a10176082fba6b087035f5d144Hugo Hudson */
369c747ac625d212a10176082fba6b087035f5d144Hugo Hudsonpublic final class AsyncTaskExecutors {
379c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    /**
389c747ac625d212a10176082fba6b087035f5d144Hugo Hudson     * A single instance of the {@link AsyncTaskExecutorFactory}, to which we delegate if it is
399c747ac625d212a10176082fba6b087035f5d144Hugo Hudson     * non-null, for injecting when testing.
409c747ac625d212a10176082fba6b087035f5d144Hugo Hudson     */
419c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    private static AsyncTaskExecutorFactory mInjectedAsyncTaskExecutorFactory = null;
429c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
439c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    /**
449c747ac625d212a10176082fba6b087035f5d144Hugo Hudson     * Creates an AsyncTaskExecutor that submits tasks to run with
459c747ac625d212a10176082fba6b087035f5d144Hugo Hudson     * {@link AsyncTask#SERIAL_EXECUTOR}.
469c747ac625d212a10176082fba6b087035f5d144Hugo Hudson     */
479c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    public static AsyncTaskExecutor createAsyncTaskExecutor() {
489c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        synchronized (AsyncTaskExecutors.class) {
499c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            if (mInjectedAsyncTaskExecutorFactory != null) {
509c747ac625d212a10176082fba6b087035f5d144Hugo Hudson                return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
519c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            }
529c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            return new SimpleAsyncTaskExecutor(AsyncTask.SERIAL_EXECUTOR);
539c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        }
549c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    }
559c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
569c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    /**
579c747ac625d212a10176082fba6b087035f5d144Hugo Hudson     * Creates an AsyncTaskExecutor that submits tasks to run with
589c747ac625d212a10176082fba6b087035f5d144Hugo Hudson     * {@link AsyncTask#THREAD_POOL_EXECUTOR}.
599c747ac625d212a10176082fba6b087035f5d144Hugo Hudson     */
609c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    public static AsyncTaskExecutor createThreadPoolExecutor() {
619c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        synchronized (AsyncTaskExecutors.class) {
629c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            if (mInjectedAsyncTaskExecutorFactory != null) {
639c747ac625d212a10176082fba6b087035f5d144Hugo Hudson                return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
649c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            }
659c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            return new SimpleAsyncTaskExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
669c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        }
679c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    }
689c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
699c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    /** Interface for creating AsyncTaskExecutor objects. */
709c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    public interface AsyncTaskExecutorFactory {
719c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        AsyncTaskExecutor createAsyncTaskExeuctor();
729c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    }
739c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
749c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    @NeededForTesting
759c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    public static void setFactoryForTest(AsyncTaskExecutorFactory factory) {
769c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        synchronized (AsyncTaskExecutors.class) {
779c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            mInjectedAsyncTaskExecutorFactory = factory;
789c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        }
799c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    }
809c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
819c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    public static void checkCalledFromUiThread() {
829c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        Preconditions.checkState(Thread.currentThread() == Looper.getMainLooper().getThread(),
839c747ac625d212a10176082fba6b087035f5d144Hugo Hudson                "submit method must be called from ui thread, was: " + Thread.currentThread());
849c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    }
859c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
869c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    private static class SimpleAsyncTaskExecutor implements AsyncTaskExecutor {
879c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        private final Executor mExecutor;
889c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
899c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        public SimpleAsyncTaskExecutor(Executor executor) {
909c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            mExecutor = executor;
919c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        }
929c747ac625d212a10176082fba6b087035f5d144Hugo Hudson
939c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        @Override
949c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        public <T> AsyncTask<T, ?, ?> submit(Object identifer, AsyncTask<T, ?, ?> task,
959c747ac625d212a10176082fba6b087035f5d144Hugo Hudson                T... params) {
969c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            checkCalledFromUiThread();
979c747ac625d212a10176082fba6b087035f5d144Hugo Hudson            return task.executeOnExecutor(mExecutor, params);
989c747ac625d212a10176082fba6b087035f5d144Hugo Hudson        }
999c747ac625d212a10176082fba6b087035f5d144Hugo Hudson    }
1009c747ac625d212a10176082fba6b087035f5d144Hugo Hudson}
101