Merge "Merging multiple implementations of CancellableTask" into main
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index 4e6b23f..e6febff 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -41,12 +42,12 @@
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.Preconditions;
-import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.TaskKeyLruCache;
import com.android.quickstep.util.TaskVisualsChangeListener;
import com.android.systemui.shared.recents.model.Task;
@@ -109,21 +110,17 @@
callback.accept(task);
return null;
}
- CancellableTask<TaskCacheEntry> request = new CancellableTask<TaskCacheEntry>() {
- @Override
- public TaskCacheEntry getResultOnBg() {
- return getCacheEntry(task);
- }
-
- @Override
- public void handleResult(TaskCacheEntry result) {
- task.icon = result.icon;
- task.titleDescription = result.contentDescription;
- task.title = result.title;
- callback.accept(task);
- dispatchIconUpdate(task.key.id);
- }
- };
+ CancellableTask<TaskCacheEntry> request = new CancellableTask<>(
+ () -> getCacheEntry(task),
+ MAIN_EXECUTOR,
+ result -> {
+ task.icon = result.icon;
+ task.titleDescription = result.contentDescription;
+ task.title = result.title;
+ callback.accept(task);
+ dispatchIconUpdate(task.key.id);
+ }
+ );
mBgExecutor.execute(request);
return request;
}
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
index 9e21595..b7cbb47 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
@@ -16,6 +16,7 @@
package com.android.quickstep;
import static com.android.launcher3.Flags.enableGridOnlyOverview;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Context;
import android.content.res.Resources;
@@ -23,8 +24,8 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.R;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.Preconditions;
-import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.TaskKeyByLastActiveTimeCache;
import com.android.quickstep.util.TaskKeyCache;
import com.android.quickstep.util.TaskKeyLruCache;
@@ -195,33 +196,29 @@
return null;
}
- CancellableTask<ThumbnailData> request = new CancellableTask<>() {
- @Override
- public ThumbnailData getResultOnBg() {
- ThumbnailData thumbnailData = ActivityManagerWrapper.getInstance().getTaskThumbnail(
- key.id, lowResolution);
- if (thumbnailData.thumbnail != null) {
- return thumbnailData;
- }
- return ActivityManagerWrapper.getInstance().takeTaskThumbnail(key.id);
- }
-
- @Override
- public void handleResult(ThumbnailData result) {
- // Avoid an async timing issue that a low res entry replaces an existing high res
- // entry in high res enabled state, so we check before putting it to cache
- if (enableGridOnlyOverview() && result.reducedResolution
- && getHighResLoadingState().isEnabled()) {
- ThumbnailData cachedThumbnail = mCache.getAndInvalidateIfModified(key);
- if (cachedThumbnail != null && cachedThumbnail.thumbnail != null
- && !cachedThumbnail.reducedResolution) {
- return;
+ CancellableTask<ThumbnailData> request = new CancellableTask<>(
+ () -> {
+ ThumbnailData thumbnailData = ActivityManagerWrapper.getInstance()
+ .getTaskThumbnail(key.id, lowResolution);
+ return thumbnailData.thumbnail != null ? thumbnailData
+ : ActivityManagerWrapper.getInstance().takeTaskThumbnail(key.id);
+ },
+ MAIN_EXECUTOR,
+ result -> {
+ // Avoid an async timing issue that a low res entry replaces an existing high
+ // res entry in high res enabled state, so we check before putting it to cache
+ if (enableGridOnlyOverview() && result.reducedResolution
+ && getHighResLoadingState().isEnabled()) {
+ ThumbnailData newCachedThumbnail = mCache.getAndInvalidateIfModified(key);
+ if (newCachedThumbnail != null && newCachedThumbnail.thumbnail != null
+ && !newCachedThumbnail.reducedResolution) {
+ return;
+ }
}
+ mCache.put(key, result);
+ callback.accept(result);
}
- mCache.put(key, result);
- callback.accept(result);
- }
- };
+ );
mBgExecutor.execute(request);
return request;
}
diff --git a/quickstep/src/com/android/quickstep/util/CancellableTask.java b/quickstep/src/com/android/quickstep/util/CancellableTask.java
deleted file mode 100644
index a6e2e81..0000000
--- a/quickstep/src/com/android/quickstep/util/CancellableTask.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2020 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.quickstep.util;
-
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
-import androidx.annotation.UiThread;
-import androidx.annotation.WorkerThread;
-
-/**
- * Utility class to executore a task on background and post the result on UI thread
- */
-public abstract class CancellableTask<T> implements Runnable {
-
- private boolean mCancelled = false;
-
- @Override
- public final void run() {
- if (mCancelled) {
- return;
- }
- T result = getResultOnBg();
- if (mCancelled) {
- return;
- }
- MAIN_EXECUTOR.execute(() -> {
- if (mCancelled) {
- return;
- }
- handleResult(result);
- });
- }
-
- /**
- * Called on the worker thread to process the request. The return object is passed to
- * {@link #handleResult(Object)}
- */
- @WorkerThread
- public abstract T getResultOnBg();
-
- /**
- * Called on the UI thread to handle the final result.
- * @param result
- */
- @UiThread
- public abstract void handleResult(T result);
-
- /**
- * Cancels the request. If it is called before {@link #handleResult(Object)}, that method
- * will not be called
- */
- public void cancel() {
- mCancelled = true;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index 6b00473..4c7d5c4 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -44,10 +44,10 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.icons.IconProvider;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.RunnableList;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.TaskThumbnailCache;
-import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -63,7 +63,6 @@
import java.util.List;
import java.util.function.Consumer;
-
/**
* TaskView that contains all tasks that are part of the desktop.
*/
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index ad4b292..10ef47c 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -24,6 +24,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
@@ -31,7 +32,6 @@
import com.android.quickstep.RecentsModel;
import com.android.quickstep.TaskIconCache;
import com.android.quickstep.TaskThumbnailCache;
-import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.systemui.shared.recents.model.Task;
@@ -45,7 +45,6 @@
import java.util.HashMap;
import java.util.function.Consumer;
-
/**
* TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
*
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index e909418..99c42a7 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -147,7 +147,6 @@
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.desktop.DesktopRecentsTransitionController;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statehandlers.DepthController;
@@ -156,6 +155,7 @@
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.OverScroll;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
@@ -590,8 +590,7 @@
return;
}
Task.TaskKey taskKey = taskView.getTask().key;
- UI_HELPER_EXECUTOR.execute(new HandlerRunnable<>(
- UI_HELPER_EXECUTOR.getHandler(),
+ UI_HELPER_EXECUTOR.execute(new CancellableTask<>(
() -> PackageManagerWrapper.getInstance()
.getActivityInfo(taskKey.getComponent(), taskKey.userId) == null,
MAIN_EXECUTOR,
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index ba39844..085c502 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -54,7 +54,6 @@
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
@@ -89,6 +88,7 @@
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.ActivityOptionsWrapper;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions;
@@ -107,7 +107,6 @@
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.BorderAnimator;
-import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.util.TaskCornerRadius;
@@ -135,8 +134,6 @@
private static final String TAG = TaskView.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final RectF EMPTY_RECT_F = new RectF();
-
public static final int FLAG_UPDATE_ICON = 1;
public static final int FLAG_UPDATE_THUMBNAIL = FLAG_UPDATE_ICON << 1;
public static final int FLAG_UPDATE_CORNER_RADIUS = FLAG_UPDATE_THUMBNAIL << 1;
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index c4ef4ae..259ddbd 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -69,13 +69,13 @@
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.icons.PlaceHolderIconDrawable;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.search.StringMatcherUtility;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.SafeCloseable;
@@ -190,7 +190,7 @@
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mDisableRelayout = false;
- private HandlerRunnable mIconLoadRequest;
+ private CancellableTask mIconLoadRequest;
private boolean mEnableIconUpdateAnimation = false;
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index d8fa90a..ee66a60 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -54,7 +54,6 @@
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
import com.android.launcher3.icons.cache.BaseIconCache;
import com.android.launcher3.icons.cache.CachingLogic;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.IconRequestInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
@@ -63,6 +62,7 @@
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutKey;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Preconditions;
@@ -100,7 +100,7 @@
private final UserCache mUserManager;
private final InstantAppResolver mInstantAppResolver;
private final IconProvider mIconProvider;
- private final HandlerRunnable mCancelledRunnable;
+ private final CancellableTask mCancelledTask;
private final SparseArray<BitmapInfo> mWidgetCategoryBitmapInfos;
@@ -119,9 +119,8 @@
mIconProvider = iconProvider;
mWidgetCategoryBitmapInfos = new SparseArray<>();
- mCancelledRunnable = new HandlerRunnable(
- mWorkerHandler, () -> null, MAIN_EXECUTOR, c -> { });
- mCancelledRunnable.cancel();
+ mCancelledTask = new CancellableTask(() -> null, MAIN_EXECUTOR, c -> { });
+ mCancelledTask.cancel();
}
@Override
@@ -174,7 +173,7 @@
*
* @return a request ID that can be used to cancel the request.
*/
- public HandlerRunnable updateIconInBackground(final ItemInfoUpdateReceiver caller,
+ public CancellableTask updateIconInBackground(final ItemInfoUpdateReceiver caller,
final ItemInfoWithIcon info) {
Preconditions.assertUIThread();
Supplier<ItemInfoWithIcon> task;
@@ -191,7 +190,7 @@
} else {
Log.i(TAG, "Icon update not supported for "
+ info == null ? "null" : info.getClass().getName());
- return mCancelledRunnable;
+ return mCancelledTask;
}
if (mPendingIconRequestCount <= 0) {
@@ -199,7 +198,7 @@
}
mPendingIconRequestCount++;
- HandlerRunnable<ItemInfoWithIcon> request = new HandlerRunnable<>(mWorkerHandler,
+ CancellableTask<ItemInfoWithIcon> request = new CancellableTask<>(
task, MAIN_EXECUTOR, caller::reapplyItemInfo, this::onIconRequestEnd);
Utilities.postAsyncCallback(mWorkerHandler, request);
return request;
diff --git a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
index 71957e1..43027da 100644
--- a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
+++ b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
@@ -23,7 +23,7 @@
import com.android.launcher3.BubbleTextView
import com.android.launcher3.allapps.BaseAllAppsAdapter
import com.android.launcher3.config.FeatureFlags
-import com.android.launcher3.util.ExecutorRunnable
+import com.android.launcher3.util.CancellableTask
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
import com.android.launcher3.util.Executors.VIEW_PREINFLATION_EXECUTOR
import com.android.launcher3.views.ActivityContext
@@ -39,7 +39,7 @@
class AllAppsRecyclerViewPool<T> : RecycledViewPool() {
var hasWorkProfile = false
- var executorRunnable: ExecutorRunnable<List<ViewHolder>>? = null
+ private var mCancellableTask: CancellableTask<List<ViewHolder>>? = null
/**
* Preinflate app icons. If all apps RV cannot be scrolled down, we don't need to preinflate.
@@ -62,14 +62,14 @@
override fun getLayoutManager(): RecyclerView.LayoutManager? = null
}
- executorRunnable?.cancel(/* interrupt= */ false)
- executorRunnable =
- ExecutorRunnable.createAndExecute(
- VIEW_PREINFLATION_EXECUTOR,
+ mCancellableTask?.cancel()
+ var task: CancellableTask<List<ViewHolder>>? = null
+ task =
+ CancellableTask(
{
val list: ArrayList<ViewHolder> = ArrayList()
for (i in 0 until preInflateCount) {
- if (Thread.interrupted()) {
+ if (task?.canceled == true) {
break
}
list.add(
@@ -85,6 +85,8 @@
}
}
)
+ mCancellableTask = task
+ VIEW_PREINFLATION_EXECUTOR.submit(mCancellableTask)
}
/**
@@ -93,7 +95,7 @@
*/
override fun clear() {
super.clear()
- executorRunnable?.cancel(/* interrupt= */ true)
+ mCancellableTask?.cancel()
}
/**
diff --git a/src/com/android/launcher3/util/CancellableTask.kt b/src/com/android/launcher3/util/CancellableTask.kt
new file mode 100644
index 0000000..49ef020
--- /dev/null
+++ b/src/com/android/launcher3/util/CancellableTask.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 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.launcher3.util
+
+import java.util.concurrent.Executor
+import java.util.function.Consumer
+import java.util.function.Supplier
+
+/** A [Runnable] that can be posted to a [Executor] that can be cancelled. */
+class CancellableTask<T>
+@JvmOverloads
+constructor(
+ private val task: Supplier<T>,
+ // Executor where consumer needs to be executed on. Typically UI executor.
+ private val callbackExecutor: Executor,
+ // Consumer that needs to be accepted upon completion of the task. Typically work that needs to
+ // be done in UI thread after task completes.
+ private val callback: Consumer<T>,
+ // Callback to be executed on callbackExecutor at the end irrespective of the task being
+ // completed or cancelled
+ private val endRunnable: Runnable = Runnable {}
+) : Runnable {
+
+ // flag to cancel the callback
+ var canceled = false
+ private set
+
+ private var ended = false
+
+ override fun run() {
+ if (canceled) return
+ val value = task.get()
+ callbackExecutor.execute {
+ if (!canceled) {
+ callback.accept(value)
+ }
+ onEnd()
+ }
+ }
+
+ /**
+ * Cancel the [CancellableTask] if not scheduled. If [CancellableTask] has started execution at
+ * this time, we will try to cancel the callback if not executed yet.
+ */
+ fun cancel() {
+ canceled = true
+ callbackExecutor.execute(this::onEnd)
+ }
+
+ private fun onEnd() {
+ if (!ended) {
+ ended = true
+ endRunnable.run()
+ }
+ }
+}
diff --git a/src/com/android/launcher3/util/ExecutorRunnable.kt b/src/com/android/launcher3/util/ExecutorRunnable.kt
deleted file mode 100644
index 49cf592..0000000
--- a/src/com/android/launcher3/util/ExecutorRunnable.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2023 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.launcher3.util
-
-import java.util.concurrent.Executor
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Future
-import java.util.function.Consumer
-import java.util.function.Supplier
-
-/** A [Runnable] that can be posted to a [Executor] that can be cancelled. */
-class ExecutorRunnable<T>
-private constructor(
- private val task: Supplier<T>,
- // Executor where consumer needs to be executed on. Typically UI executor.
- private val callbackExecutor: Executor,
- // Consumer that needs to be accepted upon completion of the task. Typically work that needs to
- // be done in UI thread after task completes.
- private val callback: Consumer<T>
-) : Runnable {
-
- // future of this runnable that will used for cancellation.
- lateinit var future: Future<*>
-
- // flag to cancel the callback
- var canceled = false
-
- override fun run() {
- val value: T = task.get()
- callbackExecutor.execute {
- if (!canceled) {
- callback.accept(value)
- }
- }
- }
-
- /**
- * Cancel the [ExecutorRunnable] if not scheduled. If [ExecutorRunnable] has started execution
- * at this time, we will try to cancel the callback if not executed yet.
- */
- fun cancel(interrupt: Boolean) {
- future.cancel(interrupt)
- canceled = true
- }
-
- companion object {
- /**
- * Create [ExecutorRunnable] and execute it on task [Executor]. It will also save the
- * [Future] into this [ExecutorRunnable] to be used for cancellation.
- */
- fun <T> createAndExecute(
- // Executor where task will be executed, typically an Executor running on background
- // thread.
- taskExecutor: ExecutorService,
- task: Supplier<T>,
- callbackExecutor: Executor,
- callback: Consumer<T>
- ): ExecutorRunnable<T> {
- val executorRunnable = ExecutorRunnable(task, callbackExecutor, callback)
- executorRunnable.future = taskExecutor.submit(executorRunnable)
- return executorRunnable
- }
- }
-}
diff --git a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
index 99485be..aab78bd 100644
--- a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
+++ b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
@@ -41,9 +41,9 @@
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShadowGenerator;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.Executors;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.util.WidgetSizes;
@@ -74,12 +74,12 @@
* @return a request id which can be used to cancel the request.
*/
@NonNull
- public HandlerRunnable loadPreview(
+ public CancellableTask loadPreview(
@NonNull WidgetItem item,
@NonNull Size previewSize,
@NonNull Consumer<Bitmap> callback) {
Handler handler = Executors.UI_HELPER_EXECUTOR.getHandler();
- HandlerRunnable<Bitmap> request = new HandlerRunnable<>(handler,
+ CancellableTask<Bitmap> request = new CancellableTask<>(
() -> generatePreview(item, previewSize.getWidth(), previewSize.getHeight()),
MAIN_EXECUTOR,
callback);
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 94c630a..7345511 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -51,8 +51,8 @@
import com.android.launcher3.R;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.RoundDrawableWrapper;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.views.ActivityContext;
import java.util.function.Consumer;
@@ -90,7 +90,7 @@
private final DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
- protected HandlerRunnable mActiveRequest;
+ protected CancellableTask mActiveRequest;
private boolean mAnimatePreview = true;
protected final ActivityContext mActivity;
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
index 3383299..d373a3b 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
@@ -35,9 +35,9 @@
import com.android.launcher3.R;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.icons.PlaceHolderIconDrawable;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.PackageItemInfo;
+import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
@@ -57,7 +57,7 @@
* widget apps aren't collapsable.
*/
private final boolean mIsCollapsable;
- @Nullable private HandlerRunnable mIconLoadRequest;
+ @Nullable private CancellableTask mIconLoadRequest;
@Nullable private Drawable mIconDrawable;
@Nullable private WidgetsListDrawableState mListDrawableState;
private ImageView mAppIcon;
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/ExecutorRunnableTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/CancellableTaskTest.kt
similarity index 92%
rename from tests/multivalentTests/src/com/android/launcher3/util/ExecutorRunnableTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/util/CancellableTaskTest.kt
index 6634577..eb58096 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/ExecutorRunnableTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/util/CancellableTaskTest.kt
@@ -29,12 +29,12 @@
import org.junit.Test
import org.junit.runner.RunWith
-/** Unit test for [ExecutorRunnable] */
+/** Unit test for [CancellableTask] */
@SmallTest
@RunWith(AndroidJUnit4::class)
-class ExecutorRunnableTest {
+class CancellableTaskTest {
- private lateinit var underTest: ExecutorRunnable<Int>
+ private lateinit var underTest: CancellableTask<Int>
private val lock = ReentrantLock()
private var result: Int = -1
@@ -51,8 +51,7 @@
private fun submitJob() {
underTest =
- ExecutorRunnable.createAndExecute(
- Executors.UI_HELPER_EXECUTOR,
+ CancellableTask(
{
isTaskExecuted = true
1
@@ -63,6 +62,7 @@
result = it + 1
}
)
+ Executors.UI_HELPER_EXECUTOR.execute(underTest)
}
@Test
@@ -82,7 +82,7 @@
Executors.UI_HELPER_EXECUTOR.submit { lock.lock() }
submitJob()
- underTest.cancel(false)
+ underTest.cancel()
lock.unlock() // unblock task on UI_HELPER_EXECUTOR
awaitAllExecutorCompleted()
@@ -101,7 +101,7 @@
awaitExecutorCompleted(Executors.UI_HELPER_EXECUTOR)
assertTrue("task should be executed.", isTaskExecuted)
- underTest.cancel(false)
+ underTest.cancel()
lock.unlock() // unblock callback on VIEW_PREINFLATION_EXECUTOR
awaitExecutorCompleted(Executors.VIEW_PREINFLATION_EXECUTOR)
@@ -113,7 +113,7 @@
fun run_and_cancelAfterCompletion_executeAll() {
awaitAllExecutorCompleted()
- underTest.cancel(false)
+ underTest.cancel()
assertTrue("task should be executed", isTaskExecuted)
assertTrue("callback should be executed", isCallbackExecuted)