summaryrefslogtreecommitdiffstats
path: root/src/com/android/messaging/util/SafeAsyncTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/messaging/util/SafeAsyncTask.java')
-rw-r--r--src/com/android/messaging/util/SafeAsyncTask.java176
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);
- }
- }
-}