diff options
Diffstat (limited to 'src/com/android/messaging/util/SafeAsyncTask.java')
-rw-r--r-- | src/com/android/messaging/util/SafeAsyncTask.java | 176 |
1 files changed, 0 insertions, 176 deletions
diff --git a/src/com/android/messaging/util/SafeAsyncTask.java b/src/com/android/messaging/util/SafeAsyncTask.java deleted file mode 100644 index 1cce6e9..0000000 --- a/src/com/android/messaging/util/SafeAsyncTask.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2015 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.messaging.util; - -import android.content.Intent; -import android.os.AsyncTask; -import android.os.Debug; -import android.os.SystemClock; - -import com.android.messaging.Factory; -import com.android.messaging.util.Assert.RunsOnAnyThread; - -/** - * Wrapper class which provides explicit API for: - * <ol> - * <li>Threading policy choice - Users of this class should use the explicit API instead of - * {@link #execute} which uses different threading policy on different OS versions. - * <li>Enforce creation on main thread as required by AsyncTask - * <li>Enforce that the background task does not take longer than expected. - * </ol> - */ -public abstract class SafeAsyncTask<Params, Progress, Result> - extends AsyncTask<Params, Progress, Result> { - private static final long DEFAULT_MAX_EXECUTION_TIME_MILLIS = 10 * 1000; // 10 seconds - - /** This is strongly discouraged as it can block other AsyncTasks indefinitely. */ - public static final long UNBOUNDED_TIME = Long.MAX_VALUE; - - private static final String WAKELOCK_ID = "bugle_safe_async_task_wakelock"; - protected static final int WAKELOCK_OP = 1000; - private static WakeLockHelper sWakeLock = new WakeLockHelper(WAKELOCK_ID); - - private final long mMaxExecutionTimeMillis; - private final boolean mCancelExecutionOnTimeout; - private boolean mThreadPoolRequested; - - public SafeAsyncTask() { - this(DEFAULT_MAX_EXECUTION_TIME_MILLIS, false); - } - - public SafeAsyncTask(final long maxTimeMillis) { - this(maxTimeMillis, false); - } - - /** - * @param maxTimeMillis maximum expected time for the background operation. This is just - * a diagnostic tool to catch unexpectedly long operations. If an operation does take - * longer than expected, it is fine to increase this argument. If the value is larger - * than a minute, you should consider using a dedicated thread so as not to interfere - * with other AsyncTasks. - * - * <p>Use {@link #UNBOUNDED_TIME} if you do not know the maximum expected time. This - * is strongly discouraged as it can block other AsyncTasks indefinitely. - * - * @param cancelExecutionOnTimeout whether to attempt to cancel the task execution on timeout. - * If this is set, at execution timeout we will call cancel(), so doInBackgroundTimed() - * should periodically check if the task is to be cancelled and finish promptly if - * possible, and handle the cancel event in onCancelled(). Also, at the end of execution - * we will not crash the execution if it went over limit since we explicitly canceled it. - */ - public SafeAsyncTask(final long maxTimeMillis, final boolean cancelExecutionOnTimeout) { - Assert.isMainThread(); // AsyncTask has to be created on the main thread - mMaxExecutionTimeMillis = maxTimeMillis; - mCancelExecutionOnTimeout = cancelExecutionOnTimeout; - } - - public final SafeAsyncTask<Params, Progress, Result> executeOnThreadPool( - final Params... params) { - Assert.isMainThread(); // AsyncTask requires this - mThreadPoolRequested = true; - executeOnExecutor(THREAD_POOL_EXECUTOR, params); - return this; - } - - protected abstract Result doInBackgroundTimed(final Params... params); - - @Override - protected final Result doInBackground(final Params... params) { - // This enforces that executeOnThreadPool was called, not execute. Ideally, we would - // make execute throw an exception, but since it is final, we cannot override it. - Assert.isTrue(mThreadPoolRequested); - - if (mCancelExecutionOnTimeout) { - ThreadUtil.getMainThreadHandler().postDelayed(new Runnable() { - @Override - public void run() { - if (getStatus() == Status.RUNNING) { - // Cancel the task if it's still running. - LogUtil.w(LogUtil.BUGLE_TAG, String.format("%s timed out and is canceled", - this)); - cancel(true /* mayInterruptIfRunning */); - } - } - }, mMaxExecutionTimeMillis); - } - - final long startTime = SystemClock.elapsedRealtime(); - try { - return doInBackgroundTimed(params); - } finally { - final long executionTime = SystemClock.elapsedRealtime() - startTime; - if (executionTime > mMaxExecutionTimeMillis) { - LogUtil.w(LogUtil.BUGLE_TAG, String.format("%s took %dms", this, executionTime)); - // Don't crash if debugger is attached or if we are asked to cancel on timeout. - if (!Debug.isDebuggerConnected() && !mCancelExecutionOnTimeout) { - Assert.fail(this + " took too long"); - } - } - } - - } - - @Override - protected void onPostExecute(final Result result) { - // No need to use AsyncTask at all if there is no onPostExecute - Assert.fail("Use SafeAsyncTask.executeOnThreadPool"); - } - - /** - * This provides a way for people to run async tasks but without onPostExecute. - * This can be called on any thread. - * - * Run code in a thread using AsyncTask's thread pool. - * - * To enable wakelock during the execution, see {@link #executeOnThreadPool(Runnable, boolean)} - * - * @param runnable The Runnable to execute asynchronously - */ - @RunsOnAnyThread - public static void executeOnThreadPool(final Runnable runnable) { - executeOnThreadPool(runnable, false); - } - - /** - * This provides a way for people to run async tasks but without onPostExecute. - * This can be called on any thread. - * - * Run code in a thread using AsyncTask's thread pool. - * - * @param runnable The Runnable to execute asynchronously - * @param withWakeLock when set, a wake lock will be held for the duration of the runnable - * execution - */ - public static void executeOnThreadPool(final Runnable runnable, final boolean withWakeLock) { - if (withWakeLock) { - final Intent intent = new Intent(); - sWakeLock.acquire(Factory.get().getApplicationContext(), intent, WAKELOCK_OP); - THREAD_POOL_EXECUTOR.execute(new Runnable() { - @Override - public void run() { - try { - runnable.run(); - } finally { - sWakeLock.release(intent, WAKELOCK_OP); - } - } - }); - } else { - THREAD_POOL_EXECUTOR.execute(runnable); - } - } -} |