From 6fe3eec95cfb153ed7c16c6381623b7e762452c3 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 15 Aug 2019 14:53:41 -0700 Subject: [PATCH] Moving various common executors to a single location Change-Id: I44bca49b8adb6fa22c3b48d10f674e42c28d792c --- .../quickstep/OverviewCommandHelper.java | 17 +-- .../quickstep/TouchInteractionService.java | 5 - .../appprediction/DynamicItemCache.java | 15 ++- .../appprediction/PredictionAppTracker.java | 8 +- .../android/quickstep/BaseSwipeUpHandler.java | 13 +- .../quickstep/OverviewCommandHelper.java | 17 +-- .../QuickstepTestInformationHandler.java | 7 +- .../android/quickstep/SwipeSharedState.java | 5 +- .../quickstep/TouchInteractionService.java | 27 ++-- .../util/RecentsAnimationListenerSet.java | 12 +- .../util/SwipeAnimationTargetSet.java | 12 +- .../views/DigitalWellBeingToast.java | 4 +- .../android/quickstep/views/RecentsView.java | 4 +- .../plugins/PluginInitializerImpl.java | 5 +- .../quickstep/OverviewInteractionState.java | 9 +- .../android/quickstep/RecentTasksList.java | 16 +-- .../quickstep/RecentsActivityTracker.java | 9 +- .../com/android/quickstep/RecentsModel.java | 18 +-- .../com/android/quickstep/TaskIconCache.java | 6 +- .../android/quickstep/TaskThumbnailCache.java | 9 +- .../quickstep/RecentTasksListTest.java | 21 +-- .../launcher3/InstallShortcutReceiver.java | 120 ++++++++---------- .../launcher3/InvariantDeviceProfile.java | 9 +- src/com/android/launcher3/LauncherModel.java | 46 ++----- .../android/launcher3/MainThreadExecutor.java | 33 ----- .../launcher3/SessionCommitReceiver.java | 4 +- src/com/android/launcher3/Utilities.java | 18 --- .../launcher3/WidgetPreviewLoader.java | 34 ++--- src/com/android/launcher3/Workspace.java | 3 +- .../compat/LauncherAppsCompatVO.java | 10 +- .../compat/PackageInstallerCompatVL.java | 12 +- .../launcher3/dragndrop/AddItemActivity.java | 5 +- .../android/launcher3/dragndrop/DragView.java | 14 +- .../dragndrop/FolderAdaptiveIcon.java | 5 +- .../graphics/DragPreviewProvider.java | 6 +- .../graphics/GridOptionsProvider.java | 8 +- .../android/launcher3/icons/IconCache.java | 15 +-- .../android/launcher3/logging/FileLog.java | 7 +- .../launcher3/model/BaseLoaderResults.java | 7 +- .../android/launcher3/model/LoaderTask.java | 4 +- .../android/launcher3/model/ModelWriter.java | 19 ++- .../notification/NotificationListener.java | 8 +- .../popup/PopupContainerWithArrow.java | 9 +- .../states/InternalStateHandler.java | 9 +- .../testing/TestInformationHandler.java | 9 +- .../android/launcher3/util/ConfigMonitor.java | 10 +- .../launcher3/util/DefaultDisplay.java | 4 +- src/com/android/launcher3/util/Executors.java | 87 +++++++++++++ .../launcher3/util/LooperExecutor.java | 35 ++++- .../util/MainThreadInitializedObject.java | 5 +- .../android/launcher3/util/Preconditions.java | 5 +- .../launcher3/util/UiThreadHelper.java | 17 +-- .../launcher3/util/ViewOnDrawExecutor.java | 7 +- .../util/WallpaperOffsetInterpolator.java | 4 +- .../launcher3/views/FloatingIconView.java | 20 ++- .../widget/LauncherAppWidgetHostView.java | 10 +- .../launcher3/ui/AbstractLauncherUiTest.java | 6 +- .../com/android/launcher3/util/Condition.java | 6 +- .../util/RaceConditionReproducer.java | 6 +- 59 files changed, 434 insertions(+), 441 deletions(-) delete mode 100644 src/com/android/launcher3/MainThreadExecutor.java create mode 100644 src/com/android/launcher3/util/Executors.java diff --git a/go/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/go/quickstep/src/com/android/quickstep/OverviewCommandHelper.java index 0fa3d866f6..216972cba2 100644 --- a/go/quickstep/src/com/android/quickstep/OverviewCommandHelper.java +++ b/go/quickstep/src/com/android/quickstep/OverviewCommandHelper.java @@ -15,8 +15,8 @@ */ package com.android.quickstep; -import static com.android.systemui.shared.system.ActivityManagerWrapper - .CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.annotation.TargetApi; import android.content.Context; @@ -25,7 +25,6 @@ import android.os.SystemClock; import android.view.ViewConfiguration; import com.android.launcher3.BaseDraggingActivity; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.quickstep.ActivityControlHelper.ActivityInitListener; @@ -43,7 +42,6 @@ public class OverviewCommandHelper { private final Context mContext; private final ActivityManagerWrapper mAM; private final RecentsModel mRecentsModel; - private final MainThreadExecutor mMainThreadExecutor; private final OverviewComponentObserver mOverviewComponentObserver; private long mLastToggleTime; @@ -51,7 +49,6 @@ public class OverviewCommandHelper { public OverviewCommandHelper(Context context, OverviewComponentObserver observer) { mContext = context; mAM = ActivityManagerWrapper.getInstance(); - mMainThreadExecutor = new MainThreadExecutor(); mRecentsModel = RecentsModel.INSTANCE.get(mContext); mOverviewComponentObserver = observer; } @@ -63,19 +60,19 @@ public class OverviewCommandHelper { } mAM.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); - mMainThreadExecutor.execute(new RecentsActivityCommand<>()); + MAIN_EXECUTOR.execute(new RecentsActivityCommand<>()); } public void onOverviewShown(boolean triggeredFromAltTab) { - mMainThreadExecutor.execute(new ShowRecentsCommand()); + MAIN_EXECUTOR.execute(new ShowRecentsCommand()); } public void onOverviewHidden() { - mMainThreadExecutor.execute(new HideRecentsCommand()); + MAIN_EXECUTOR.execute(new HideRecentsCommand()); } public void onTip(int actionType, int viewType) { - mMainThreadExecutor.execute(() -> + MAIN_EXECUTOR.execute(() -> UserEventDispatcher.newInstance(mContext).logActionTip(actionType, viewType)); } @@ -161,7 +158,7 @@ public class OverviewCommandHelper { // Otherwise, start overview. mListener = mHelper.createActivityInitListener(provider::onActivityReady); mListener.registerAndStartActivity(mOverviewComponentObserver.getOverviewIntent(), - provider, mContext, mMainThreadExecutor.getHandler(), + provider, mContext, MAIN_EXECUTOR.getHandler(), provider.getRecentsLaunchDuration()); } diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java index 577b175661..19dd82f7f7 100644 --- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -34,8 +34,6 @@ import android.view.MotionEvent; import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserManagerCompat; -import com.android.launcher3.util.LooperExecutor; -import com.android.launcher3.util.UiThreadHelper; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -139,9 +137,6 @@ public class TouchInteractionService extends Service { return sConnected; } - public static final LooperExecutor BACKGROUND_EXECUTOR = - new LooperExecutor(UiThreadHelper.getBackgroundLooper()); - private RecentsModel mRecentsModel; private OverviewComponentObserver mOverviewComponentObserver; private OverviewCommandHelper mOverviewCommandHelper; diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java index 4ecc39cf6a..65e69b6046 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java @@ -17,6 +17,8 @@ package com.android.launcher3.appprediction; import static android.content.pm.PackageManager.MATCH_INSTANT; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -30,8 +32,12 @@ import android.os.Message; import android.util.ArrayMap; import android.util.Log; +import androidx.annotation.MainThread; +import androidx.annotation.Nullable; +import androidx.annotation.UiThread; +import androidx.annotation.WorkerThread; + import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherModel; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.icons.IconCache; import com.android.launcher3.icons.LauncherIcons; @@ -45,11 +51,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import androidx.annotation.MainThread; -import androidx.annotation.Nullable; -import androidx.annotation.UiThread; -import androidx.annotation.WorkerThread; - /** * Utility class which loads and caches predicted items like instant apps and shortcuts, before * they can be displayed on the UI @@ -77,7 +78,7 @@ public class DynamicItemCache { public DynamicItemCache(Context context, Runnable onUpdateCallback) { mContext = context; - mWorker = new Handler(LauncherModel.getWorkerLooper(), this::handleWorkerMessage); + mWorker = new Handler(MODEL_EXECUTOR.getLooper(), this::handleWorkerMessage); mUiHandler = new Handler(Looper.getMainLooper(), this::handleUiMessage); mInstantAppResolver = InstantAppResolver.newInstance(context); mOnUpdateCallback = onUpdateCallback; diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java index 7d8fab1ae4..a12917f295 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java @@ -15,6 +15,9 @@ */ package com.android.launcher3.appprediction; +import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; + import android.annotation.TargetApi; import android.app.prediction.AppPredictionContext; import android.app.prediction.AppPredictionManager; @@ -38,9 +41,6 @@ import androidx.annotation.WorkerThread; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.appprediction.PredictionUiStateManager.Client; import com.android.launcher3.model.AppLaunchTracker; -import com.android.launcher3.util.UiThreadHelper; - -import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID; /** * Subclass of app tracker which publishes the data to the prediction engine and gets back results. @@ -65,7 +65,7 @@ public class PredictionAppTracker extends AppLaunchTracker { public PredictionAppTracker(Context context) { mContext = context; - mMessageHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleMessage); + mMessageHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleMessage); InvariantDeviceProfile.INSTANCE.get(mContext).addOnChangeListener(this::onIdpChanged); mMessageHandler.sendEmptyMessage(MSG_INIT); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index d627a7f14f..3f4dfd2330 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -22,9 +22,9 @@ import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.ACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION; -import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; -import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; import android.animation.Animator; @@ -47,6 +47,8 @@ import android.view.View; import android.view.WindowManager; import android.view.animation.Interpolator; +import androidx.annotation.UiThread; + import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; @@ -54,7 +56,6 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; -import com.android.launcher3.anim.Interpolators; import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.views.FloatingIconView; import com.android.quickstep.ActivityControlHelper.ActivityInitListener; @@ -75,8 +76,6 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import java.util.function.Consumer; -import androidx.annotation.UiThread; - /** * Base class for swipe up handler with some utility methods */ @@ -126,7 +125,7 @@ public abstract class BaseSwipeUpHandler mVibrator.vibrate(effect)); + UI_HELPER_EXECUTOR.execute(() -> mVibrator.vibrate(effect)); } public Consumer getRecentsViewDispatcher(RotationMode rotationMode) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java index a94f25d2b2..4249f1d0d5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java @@ -15,8 +15,8 @@ */ package com.android.quickstep; -import static com.android.systemui.shared.system.ActivityManagerWrapper - .CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -28,7 +28,6 @@ import android.os.SystemClock; import android.view.ViewConfiguration; import com.android.launcher3.BaseDraggingActivity; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.quickstep.ActivityControlHelper.ActivityInitListener; @@ -47,7 +46,6 @@ public class OverviewCommandHelper { private final Context mContext; private final ActivityManagerWrapper mAM; private final RecentsModel mRecentsModel; - private final MainThreadExecutor mMainThreadExecutor; private final OverviewComponentObserver mOverviewComponentObserver; private long mLastToggleTime; @@ -55,7 +53,6 @@ public class OverviewCommandHelper { public OverviewCommandHelper(Context context, OverviewComponentObserver observer) { mContext = context; mAM = ActivityManagerWrapper.getInstance(); - mMainThreadExecutor = new MainThreadExecutor(); mRecentsModel = RecentsModel.INSTANCE.get(mContext); mOverviewComponentObserver = observer; } @@ -67,19 +64,19 @@ public class OverviewCommandHelper { } mAM.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); - mMainThreadExecutor.execute(new RecentsActivityCommand<>()); + MAIN_EXECUTOR.execute(new RecentsActivityCommand<>()); } public void onOverviewShown(boolean triggeredFromAltTab) { - mMainThreadExecutor.execute(new ShowRecentsCommand(triggeredFromAltTab)); + MAIN_EXECUTOR.execute(new ShowRecentsCommand(triggeredFromAltTab)); } public void onOverviewHidden() { - mMainThreadExecutor.execute(new HideRecentsCommand()); + MAIN_EXECUTOR.execute(new HideRecentsCommand()); } public void onTip(int actionType, int viewType) { - mMainThreadExecutor.execute(() -> + MAIN_EXECUTOR.execute(() -> UserEventDispatcher.newInstance(mContext).logActionTip(actionType, viewType)); } @@ -178,7 +175,7 @@ public class OverviewCommandHelper { // Otherwise, start overview. mListener = mHelper.createActivityInitListener(this::onActivityReady); mListener.registerAndStartActivity(mOverviewComponentObserver.getOverviewIntent(), - this::createWindowAnimation, mContext, mMainThreadExecutor.getHandler(), + this::createWindowAnimation, mContext, MAIN_EXECUTOR.getHandler(), mAnimationProvider.getRecentsLaunchDuration()); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java index 4eb9df2cbd..61b57e2fb2 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -1,9 +1,10 @@ package com.android.quickstep; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + import android.content.Context; import android.os.Bundle; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.testing.TestInformationHandler; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.states.OverviewState; @@ -52,7 +53,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { case TestProtocol.REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN: { try { - final int leftMargin = new MainThreadExecutor().submit(() -> + final int leftMargin = MAIN_EXECUTOR.submit(() -> mLauncher.getOverviewPanel().getLeftGestureMargin()).get(); response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, leftMargin); } catch (ExecutionException e) { @@ -65,7 +66,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { case TestProtocol.REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN: { try { - final int rightMargin = new MainThreadExecutor().submit(() -> + final int rightMargin = MAIN_EXECUTOR.submit(() -> mLauncher.getOverviewPanel().getRightGestureMargin()). get(); response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, rightMargin); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java index c55f656dfd..0acce02256 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java @@ -15,7 +15,7 @@ */ package com.android.quickstep; -import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import android.util.Log; @@ -25,6 +25,7 @@ import com.android.launcher3.util.Preconditions; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; + import java.io.PrintWriter; /** @@ -77,7 +78,7 @@ public class SwipeSharedState implements SwipeAnimationListener { mRecentsAnimationListener.removeListener(this); mRecentsAnimationListener.cancelListener(); if (mLastAnimationRunning && mLastAnimationTarget != null) { - Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), + Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), finishAnimation ? mLastAnimationTarget::finishAnimation : mLastAnimationTarget::cancelAnimation); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 86ba855784..440e8b9fc0 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -23,6 +23,8 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_HINTS_IN_OVERVIEW import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.config.FeatureFlags.FAKE_LANDSCAPE_UI; import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE; @@ -72,7 +74,6 @@ import androidx.annotation.UiThread; import androidx.annotation.WorkerThread; import com.android.launcher3.BaseDraggingActivity; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.R; import com.android.launcher3.ResourceUtils; import com.android.launcher3.Utilities; @@ -82,8 +83,6 @@ import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.testing.TestProtocol; -import com.android.launcher3.util.LooperExecutor; -import com.android.launcher3.util.UiThreadHelper; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; import com.android.quickstep.inputconsumers.AccessibilityInputConsumer; @@ -106,8 +105,8 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags; import com.android.systemui.shared.system.RecentsAnimationListener; import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat; - import com.android.systemui.shared.system.TaskInfoCompat; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Arrays; @@ -138,10 +137,6 @@ class ArgList extends LinkedList { public class TouchInteractionService extends Service implements NavigationModeChangeListener, DisplayListener { - public static final MainThreadExecutor MAIN_THREAD_EXECUTOR = new MainThreadExecutor(); - public static final LooperExecutor BACKGROUND_EXECUTOR = - new LooperExecutor(UiThreadHelper.getBackgroundLooper()); - public static final EventLogArray TOUCH_INTERACTION_LOG = new EventLogArray("touch_interaction_log", 40); @@ -161,9 +156,9 @@ public class TouchInteractionService extends Service implements public void onInitialize(Bundle bundle) { mISystemUiProxy = ISystemUiProxy.Stub .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY)); - MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor); - MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet); - MAIN_THREAD_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */)); + MAIN_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor); + MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet); + MAIN_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */)); sIsInitialized = true; } @@ -198,7 +193,7 @@ public class TouchInteractionService extends Service implements @Override public void onAssistantVisibilityChanged(float visibility) { mLastAssistantVisibility = visibility; - MAIN_THREAD_EXECUTOR.execute( + MAIN_EXECUTOR.execute( TouchInteractionService.this::onAssistantVisibilityChanged); } @@ -214,13 +209,13 @@ public class TouchInteractionService extends Service implements isButton, gestureSwipeLeft, activityControl.getContainerType()); if (completed && !isButton && shouldNotifyBackGesture()) { - BACKGROUND_EXECUTOR.execute(TouchInteractionService.this::tryNotifyBackGesture); + UI_HELPER_EXECUTOR.execute(TouchInteractionService.this::tryNotifyBackGesture); } } public void onSystemUiStateChanged(int stateFlags) { mSystemUiStateFlags = stateFlags; - MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged); + MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged); } /** Deprecated methods **/ @@ -439,7 +434,7 @@ public class TouchInteractionService extends Service implements if (mMode.hasGestures != newMode.hasGestures) { if (newMode.hasGestures) { getSystemService(DisplayManager.class).registerDisplayListener( - this, MAIN_THREAD_EXECUTOR.getHandler()); + this, MAIN_EXECUTOR.getHandler()); } else { getSystemService(DisplayManager.class).unregisterDisplayListener(this); } @@ -897,7 +892,7 @@ public class TouchInteractionService extends Service implements } public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) { - BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance() + UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance() .startRecentsActivity(intent, null, listener, null, null)); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java index 14083dd958..b1999d716c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java @@ -15,11 +15,13 @@ */ package com.android.quickstep.util; -import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import android.graphics.Rect; import android.util.ArraySet; +import androidx.annotation.UiThread; + import com.android.launcher3.Utilities; import com.android.launcher3.util.Preconditions; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; @@ -31,8 +33,6 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.Set; import java.util.function.Consumer; -import androidx.annotation.UiThread; - /** * Wrapper around {@link RecentsAnimationListener} which delegates callbacks to multiple listeners * on the main thread @@ -82,7 +82,7 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { if (mCancelled) { targetSet.cancelAnimation(); } else { - Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> { + Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> { for (SwipeAnimationListener listener : getListeners()) { listener.onRecentsAnimationStart(targetSet); } @@ -92,14 +92,14 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { @Override public final void onAnimationCanceled(ThumbnailData thumbnailData) { - Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> { + Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> { for (SwipeAnimationListener listener : getListeners()) { listener.onRecentsAnimationCanceled(); } }); // TODO: handle the transition better instead of simply using a transition delay. if (thumbnailData != null) { - MAIN_THREAD_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(), + MAIN_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(), TRANSITION_DELAY); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java index 381c27a284..3619d3a0e8 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java @@ -15,8 +15,8 @@ */ package com.android.quickstep.util; -import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; -import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import android.graphics.Rect; @@ -68,25 +68,25 @@ public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet { public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) { mOnFinishListener.accept(this); - BACKGROUND_EXECUTOR.execute(() -> { + UI_HELPER_EXECUTOR.execute(() -> { controller.setInputConsumerEnabled(false); controller.finish(toRecents, sendUserLeaveHint); if (callback != null) { - MAIN_THREAD_EXECUTOR.execute(callback); + MAIN_EXECUTOR.execute(callback); } }); } public void enableInputConsumer() { - BACKGROUND_EXECUTOR.submit(() -> { + UI_HELPER_EXECUTOR.submit(() -> { controller.hideCurrentInputMethod(); controller.setInputConsumerEnabled(true); }); } public void setWindowThresholdCrossed(boolean thresholdCrossed) { - BACKGROUND_EXECUTOR.execute(() -> { + UI_HELPER_EXECUTOR.execute(() -> { controller.setAnimationTargetsBehindSystemBars(!thresholdCrossed); if (mShouldMinimizeSplitScreen && thresholdCrossed) { // NOTE: As a workaround for conflicting animations (Launcher animating the task diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java index 7fac813854..b06d4bc355 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java @@ -19,6 +19,7 @@ package com.android.quickstep.views; import static android.provider.Settings.ACTION_APP_USAGE_SETTINGS; import static com.android.launcher3.Utilities.prefixTextWithIcon; +import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR; import android.annotation.TargetApi; import android.app.ActivityOptions; @@ -41,7 +42,6 @@ import androidx.annotation.StringRes; import com.android.launcher3.BaseActivity; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.systemui.shared.recents.model.Task; @@ -117,7 +117,7 @@ public final class DigitalWellBeingToast { return; } - Utilities.THREAD_POOL_EXECUTOR.execute(() -> { + THREAD_POOL_EXECUTOR.execute(() -> { final AppUsageLimit usageLimit = mLauncherApps.getAppUsageLimit( task.getTopComponent().getPackageName(), UserHandle.of(task.key.userId)); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 3e1d61aca1..9464bd1930 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -35,9 +35,9 @@ import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS; import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP; import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW; import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId; -import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; import android.animation.Animator; import android.animation.AnimatorSet; @@ -228,7 +228,7 @@ public abstract class RecentsView extends PagedView impl return; } - BACKGROUND_EXECUTOR.execute(() -> { + UI_HELPER_EXECUTOR.execute(() -> { TaskView taskView = getTaskView(taskId); if (taskView == null) { return; diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java index 910fa0df6c..7beb9db841 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java +++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java @@ -14,16 +14,17 @@ package com.android.launcher3.uioverrides.plugins; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.content.Context; import android.os.Looper; -import com.android.launcher3.LauncherModel; import com.android.systemui.shared.plugins.PluginInitializer; public class PluginInitializerImpl implements PluginInitializer { @Override public Looper getBgLooper() { - return LauncherModel.getWorkerLooper(); + return MODEL_EXECUTOR.getLooper(); } @Override diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java index 78b48d77a4..858c3b6b3f 100644 --- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java +++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java @@ -15,20 +15,21 @@ */ package com.android.quickstep; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; + import android.content.Context; import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.util.Log; +import androidx.annotation.WorkerThread; + import com.android.launcher3.Utilities; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.util.MainThreadInitializedObject; -import com.android.launcher3.util.UiThreadHelper; import com.android.systemui.shared.recents.ISystemUiProxy; -import androidx.annotation.WorkerThread; - /** * Sets alpha for the back button */ @@ -62,7 +63,7 @@ public class OverviewInteractionState { // because of its high send frequency and data may be very different than the previous value // For example, send back alpha on uihandler to avoid flickering when setting its visibility mUiHandler = new Handler(this::handleUiMessage); - mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage); + mBgHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleBgMessage); onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(context) .addModeChangeListener(this::onNavigationModeChanged)); diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index 71ce32b28e..10f9febfb7 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -16,7 +16,7 @@ package com.android.quickstep; -import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import android.annotation.TargetApi; import android.app.ActivityManager; @@ -26,11 +26,12 @@ import android.util.SparseBooleanArray; import androidx.annotation.VisibleForTesting; -import com.android.launcher3.MainThreadExecutor; +import com.android.launcher3.util.LooperExecutor; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.KeyguardManagerCompat; import com.android.systemui.shared.system.TaskStackChangeListener; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -43,7 +44,7 @@ import java.util.function.Consumer; public class RecentTasksList extends TaskStackChangeListener { private final KeyguardManagerCompat mKeyguardManager; - private final MainThreadExecutor mMainThreadExecutor; + private final LooperExecutor mMainThreadExecutor; private final ActivityManagerWrapper mActivityManagerWrapper; // The list change id, increments as the task list changes in the system @@ -55,8 +56,7 @@ public class RecentTasksList extends TaskStackChangeListener { ArrayList mTasks = new ArrayList<>(); - - public RecentTasksList(MainThreadExecutor mainThreadExecutor, + public RecentTasksList(LooperExecutor mainThreadExecutor, KeyguardManagerCompat keyguardManager, ActivityManagerWrapper activityManagerWrapper) { mMainThreadExecutor = mainThreadExecutor; mKeyguardManager = keyguardManager; @@ -70,7 +70,7 @@ public class RecentTasksList extends TaskStackChangeListener { */ public void getTaskKeys(int numTasks, Consumer> callback) { // Kick off task loading in the background - BACKGROUND_EXECUTOR.execute(() -> { + UI_HELPER_EXECUTOR.execute(() -> { ArrayList tasks = loadTasksInBackground(numTasks, true /* loadKeysOnly */); mMainThreadExecutor.execute(() -> callback.accept(tasks)); }); @@ -92,12 +92,12 @@ public class RecentTasksList extends TaskStackChangeListener { if (mLastLoadedId == mChangeId && (!mLastLoadHadKeysOnly || loadKeysOnly)) { // The list is up to date, send the callback on the next frame, // so that requestID can be returned first. - mMainThreadExecutor.getHandler().post(resultCallback); + mMainThreadExecutor.post(resultCallback); return requestLoadId; } // Kick off task loading in the background - BACKGROUND_EXECUTOR.execute(() -> { + UI_HELPER_EXECUTOR.execute(() -> { ArrayList tasks = loadTasksInBackground(Integer.MAX_VALUE, loadKeysOnly); mMainThreadExecutor.execute(() -> { diff --git a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java index f9d2f11cba..4d1d9ef8a7 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java +++ b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java @@ -15,6 +15,8 @@ */ package com.android.quickstep; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; @@ -22,7 +24,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; -import com.android.launcher3.MainThreadExecutor; import com.android.quickstep.ActivityControlHelper.ActivityInitListener; import com.android.quickstep.util.RemoteAnimationProvider; @@ -92,14 +93,10 @@ public class RecentsActivityTracker implements Ac private static class Scheduler implements Runnable { private WeakReference mPendingTracker = new WeakReference<>(null); - private MainThreadExecutor mMainThreadExecutor; public synchronized void schedule(RecentsActivityTracker tracker) { mPendingTracker = new WeakReference<>(tracker); - if (mMainThreadExecutor == null) { - mMainThreadExecutor = new MainThreadExecutor(); - } - mMainThreadExecutor.execute(this); + MAIN_EXECUTOR.execute(this); } @Override diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java index d9ecdcd560..2e59ed5e48 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -15,6 +15,10 @@ */ package com.android.quickstep; +import static android.os.Process.THREAD_PRIORITY_BACKGROUND; + +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.createAndStartNewLooper; import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId; import android.annotation.TargetApi; @@ -22,13 +26,12 @@ import android.app.ActivityManager; import android.content.ComponentCallbacks2; import android.content.Context; import android.os.Build; -import android.os.HandlerThread; +import android.os.Looper; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.LauncherAppsCompat.OnAppsChangedCallbackCompat; import com.android.launcher3.util.MainThreadInitializedObject; @@ -66,13 +69,12 @@ public class RecentsModel extends TaskStackChangeListener { private RecentsModel(Context context) { mContext = context; - HandlerThread loaderThread = new HandlerThread("TaskThumbnailIconCache", - Process.THREAD_PRIORITY_BACKGROUND); - loaderThread.start(); - mTaskList = new RecentTasksList(new MainThreadExecutor(), + Looper looper = + createAndStartNewLooper("TaskThumbnailIconCache", THREAD_PRIORITY_BACKGROUND); + mTaskList = new RecentTasksList(MAIN_EXECUTOR, new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance()); - mIconCache = new TaskIconCache(context, loaderThread.getLooper()); - mThumbnailCache = new TaskThumbnailCache(context, loaderThread.getLooper()); + mIconCache = new TaskIconCache(context, looper); + mThumbnailCache = new TaskThumbnailCache(context, looper); ActivityManagerWrapper.getInstance().registerTaskStackListener(this); setupPackageListener(); } diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java index 5e0195806a..289a129706 100644 --- a/quickstep/src/com/android/quickstep/TaskIconCache.java +++ b/quickstep/src/com/android/quickstep/TaskIconCache.java @@ -16,6 +16,7 @@ package com.android.quickstep; import static com.android.launcher3.uioverrides.RecentsUiFactory.GO_LOW_RAM_RECENTS_ENABLED; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import android.content.ComponentName; import android.content.Context; @@ -27,7 +28,6 @@ import android.os.Looper; import android.util.LruCache; import android.view.accessibility.AccessibilityManager; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.icons.cache.HandlerRunnable; @@ -47,7 +47,6 @@ import java.util.function.Consumer; public class TaskIconCache { private final Handler mBackgroundHandler; - private final MainThreadExecutor mMainThreadExecutor; private final AccessibilityManager mAccessibilityManager; private final NormalizedIconLoader mIconLoader; @@ -68,7 +67,6 @@ public class TaskIconCache { public TaskIconCache(Context context, Looper backgroundLooper) { mBackgroundHandler = new Handler(backgroundLooper); - mMainThreadExecutor = new MainThreadExecutor(); mAccessibilityManager = context.getSystemService(AccessibilityManager.class); Resources res = context.getResources(); @@ -104,7 +102,7 @@ public class TaskIconCache { // We don't call back to the provided callback in this case return; } - mMainThreadExecutor.execute(() -> { + MAIN_EXECUTOR.execute(() -> { task.icon = icon; task.titleDescription = contentDescription; callback.accept(task); diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java index 57c5a27833..3b50c2623b 100644 --- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java +++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java @@ -15,12 +15,14 @@ */ package com.android.quickstep; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + import android.app.ActivityManager; import android.content.Context; import android.content.res.Resources; import android.os.Handler; import android.os.Looper; -import com.android.launcher3.MainThreadExecutor; + import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.icons.cache.HandlerRunnable; @@ -30,13 +32,13 @@ import com.android.systemui.shared.recents.model.Task.TaskKey; import com.android.systemui.shared.recents.model.TaskKeyLruCache; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; + import java.util.ArrayList; import java.util.function.Consumer; public class TaskThumbnailCache { private final Handler mBackgroundHandler; - private final MainThreadExecutor mMainThreadExecutor; private final int mCacheSize; private final ThumbnailCache mCache; @@ -94,7 +96,6 @@ public class TaskThumbnailCache { public TaskThumbnailCache(Context context, Looper backgroundLooper) { mBackgroundHandler = new Handler(backgroundLooper); - mMainThreadExecutor = new MainThreadExecutor(); mHighResLoadingState = new HighResLoadingState(context); Resources res = context.getResources(); @@ -168,7 +169,7 @@ public class TaskThumbnailCache { // We don't call back to the provided callback in this case return; } - mMainThreadExecutor.execute(() -> { + MAIN_EXECUTOR.execute(() -> { mCache.put(key, thumbnail); callback.accept(thumbnail); onEnd(); diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java index 5fb27bcc69..34eb7f8177 100644 --- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java +++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java @@ -16,11 +16,20 @@ package com.android.quickstep; +import static junit.framework.TestCase.assertNull; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import android.app.ActivityManager; import androidx.test.filters.SmallTest; -import com.android.launcher3.MainThreadExecutor; +import com.android.launcher3.util.LooperExecutor; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.KeyguardManagerCompat; @@ -31,14 +40,6 @@ import org.junit.Test; import java.util.Collections; import java.util.List; -import static junit.framework.TestCase.assertNull; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - @SmallTest public class RecentTasksListTest { @@ -49,7 +50,7 @@ public class RecentTasksListTest { @Before public void setup() { - MainThreadExecutor mockMainThreadExecutor = mock(MainThreadExecutor.class); + LooperExecutor mockMainThreadExecutor = mock(LooperExecutor.class); KeyguardManagerCompat mockKeyguardManagerCompat = mock(KeyguardManagerCompat.class); mockActivityManagerWrapper = mock(ActivityManagerWrapper.class); mRecentTasksList = new RecentTasksList(mockMainThreadExecutor, mockKeyguardManagerCompat, diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index a6b53b92db..351635c25c 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -16,6 +16,8 @@ package com.android.launcher3; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; @@ -28,9 +30,7 @@ import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.os.Handler; import android.os.Looper; -import android.os.Message; import android.os.Parcelable; import android.os.Process; import android.os.UserHandle; @@ -39,6 +39,8 @@ import android.util.Base64; import android.util.Log; import android.util.Pair; +import androidx.annotation.WorkerThread; + import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.icons.BitmapInfo; @@ -65,9 +67,6 @@ import java.util.Set; public class InstallShortcutReceiver extends BroadcastReceiver { - private static final int MSG_ADD_TO_QUEUE = 1; - private static final int MSG_FLUSH_QUEUE = 2; - public static final int FLAG_ACTIVITY_PAUSED = 1; public static final int FLAG_LOADER_RUNNING = 2; public static final int FLAG_DRAG_AND_DROP = 4; @@ -100,65 +99,56 @@ public class InstallShortcutReceiver extends BroadcastReceiver { public static final int NEW_SHORTCUT_BOUNCE_DURATION = 450; public static final int NEW_SHORTCUT_STAGGER_DELAY = 85; - private static final Handler sHandler = new Handler(LauncherModel.getWorkerLooper()) { + @WorkerThread + private static void addToQueue(Context context, PendingInstallShortcutInfo info) { + String encoded = info.encodeToString(); + SharedPreferences prefs = Utilities.getPrefs(context); + Set strings = prefs.getStringSet(APPS_PENDING_INSTALL, null); + strings = (strings != null) ? new HashSet<>(strings) : new HashSet<>(1); + strings.add(encoded); + prefs.edit().putStringSet(APPS_PENDING_INSTALL, strings).apply(); + } - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_ADD_TO_QUEUE: { - Pair pair = - (Pair) msg.obj; - String encoded = pair.second.encodeToString(); - SharedPreferences prefs = Utilities.getPrefs(pair.first); - Set strings = prefs.getStringSet(APPS_PENDING_INSTALL, null); - strings = (strings != null) ? new HashSet<>(strings) : new HashSet(1); - strings.add(encoded); - prefs.edit().putStringSet(APPS_PENDING_INSTALL, strings).apply(); - return; - } - case MSG_FLUSH_QUEUE: { - Context context = (Context) msg.obj; - LauncherModel model = LauncherAppState.getInstance(context).getModel(); - if (model.getCallback() == null) { - // Launcher not loaded - return; - } - - ArrayList> installQueue = new ArrayList<>(); - SharedPreferences prefs = Utilities.getPrefs(context); - Set strings = prefs.getStringSet(APPS_PENDING_INSTALL, null); - if (DBG) Log.d(TAG, "Getting and clearing APPS_PENDING_INSTALL: " + strings); - if (strings == null) { - return; - } - - LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); - for (String encoded : strings) { - PendingInstallShortcutInfo info = decode(encoded, context); - if (info == null) { - continue; - } - - String pkg = getIntentPackage(info.launchIntent); - if (!TextUtils.isEmpty(pkg) - && !launcherApps.isPackageEnabledForProfile(pkg, info.user)) { - if (DBG) Log.d(TAG, "Ignoring shortcut for absent package: " - + info.launchIntent); - continue; - } - - // Generate a shortcut info to add into the model - installQueue.add(info.getItemInfo()); - } - prefs.edit().remove(APPS_PENDING_INSTALL).apply(); - if (!installQueue.isEmpty()) { - model.addAndBindAddedWorkspaceItems(installQueue); - } - return; - } - } + @WorkerThread + private static void flushQueueInBackground(Context context) { + LauncherModel model = LauncherAppState.getInstance(context).getModel(); + if (model.getCallback() == null) { + // Launcher not loaded + return; } - }; + + ArrayList> installQueue = new ArrayList<>(); + SharedPreferences prefs = Utilities.getPrefs(context); + Set strings = prefs.getStringSet(APPS_PENDING_INSTALL, null); + if (DBG) Log.d(TAG, "Getting and clearing APPS_PENDING_INSTALL: " + strings); + if (strings == null) { + return; + } + + LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); + for (String encoded : strings) { + PendingInstallShortcutInfo info = decode(encoded, context); + if (info == null) { + continue; + } + + String pkg = getIntentPackage(info.launchIntent); + if (!TextUtils.isEmpty(pkg) + && !launcherApps.isPackageEnabledForProfile(pkg, info.user)) { + if (DBG) { + Log.d(TAG, "Ignoring shortcut for absent package: " + info.launchIntent); + } + continue; + } + + // Generate a shortcut info to add into the model + installQueue.add(info.getItemInfo()); + } + prefs.edit().remove(APPS_PENDING_INSTALL).apply(); + if (!installQueue.isEmpty()) { + model.addAndBindAddedWorkspaceItems(installQueue); + } + } public static void removeFromInstallQueue(Context context, HashSet packageNames, UserHandle user) { @@ -288,7 +278,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { private static void queuePendingShortcutInfo(PendingInstallShortcutInfo info, Context context) { // Queue the item up for adding if launcher has not loaded properly yet - Message.obtain(sHandler, MSG_ADD_TO_QUEUE, Pair.create(context, info)).sendToTarget(); + MODEL_EXECUTOR.post(() -> addToQueue(context, info)); flushInstallQueue(context); } @@ -304,7 +294,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { if (sInstallQueueDisabledFlags != 0) { return; } - Message.obtain(sHandler, MSG_FLUSH_QUEUE, context.getApplicationContext()).sendToTarget(); + MODEL_EXECUTOR.post(() -> flushQueueInBackground(context)); } /** @@ -484,7 +474,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { appInfo.title = ""; appInfo.applyFrom(app.getIconCache().getDefaultIcon(user)); final WorkspaceItemInfo si = appInfo.makeWorkspaceItem(); - if (Looper.myLooper() == LauncherModel.getWorkerLooper()) { + if (Looper.myLooper() == MODEL_EXECUTOR.getLooper()) { app.getIconCache().getTitleAndIcon(si, activityInfo, false /* useLowResIcon */); } else { app.getModel().updateAndBindWorkspaceItem(() -> { diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index bde87cb505..8ee530f0f9 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -18,6 +18,7 @@ package com.android.launcher3; import static com.android.launcher3.Utilities.getDevicePrefs; import static com.android.launcher3.config.FeatureFlags.APPLY_CONFIG_AT_RUNTIME; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter; import android.annotation.TargetApi; @@ -42,6 +43,9 @@ import android.util.Xml; import android.view.Display; import android.view.WindowManager; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + import com.android.launcher3.graphics.IconShape; import com.android.launcher3.util.ConfigMonitor; import com.android.launcher3.util.IntArray; @@ -55,9 +59,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - public class InvariantDeviceProfile { public static final String TAG = "IDP"; @@ -280,7 +281,7 @@ public class InvariantDeviceProfile { public void setCurrentGrid(Context context, String gridName) { Context appContext = context.getApplicationContext(); Utilities.getPrefs(appContext).edit().putString(KEY_IDP_GRID_NAME, gridName).apply(); - new MainThreadExecutor().execute(() -> onConfigChanged(appContext)); + MAIN_EXECUTOR.execute(() -> onConfigChanged(appContext)); } private void onConfigChanged(Context context) { diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index eed23770ef..da9617af72 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -18,20 +18,21 @@ package com.android.launcher3; import static com.android.launcher3.LauncherAppState.ACTION_FORCE_ROLOAD; import static com.android.launcher3.config.FeatureFlags.IS_DOGFOOD_BUILD; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.pm.ShortcutInfo; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; import android.os.Process; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.util.Pair; +import androidx.annotation.Nullable; + import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo; import com.android.launcher3.compat.UserManagerCompat; @@ -65,8 +66,6 @@ import java.util.concurrent.CancellationException; import java.util.concurrent.Executor; import java.util.function.Supplier; -import androidx.annotation.Nullable; - /** * Maintains in-memory state of the Launcher. It is expected that there should be only one * LauncherModel object held in a static. Also provide APIs for updating the database state @@ -78,21 +77,12 @@ public class LauncherModel extends BroadcastReceiver static final String TAG = "Launcher.Model"; - private final MainThreadExecutor mUiExecutor = new MainThreadExecutor(); @Thunk final LauncherAppState mApp; @Thunk final Object mLock = new Object(); @Thunk LoaderTask mLoaderTask; @Thunk boolean mIsLoaderTaskRunning; - @Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); - private static final Looper mWorkerLooper; - static { - sWorkerThread.start(); - mWorkerLooper = sWorkerThread.getLooper(); - } - @Thunk static final Handler sWorker = new Handler(mWorkerLooper); - // Indicates whether the current model data is valid or not. // We start off with everything not loaded. After that, we assume that // our monitoring of the package manager provides all updates and we never @@ -318,7 +308,7 @@ public class LauncherModel extends BroadcastReceiver if (mCallbacks != null && mCallbacks.get() != null) { final Callbacks oldCallbacks = mCallbacks.get(); // Clear any pending bind-runnables from the synchronized load process. - mUiExecutor.execute(oldCallbacks::clearPendingBinds); + MAIN_EXECUTOR.execute(oldCallbacks::clearPendingBinds); // If there is already one running, tell it to stop. stopLoader(); @@ -362,7 +352,7 @@ public class LauncherModel extends BroadcastReceiver // Always post the loader task, instead of running directly (even on same thread) so // that we exit any nested synchronized blocks - sWorker.post(mLoaderTask); + MODEL_EXECUTOR.post(mLoaderTask); } } @@ -429,8 +419,8 @@ public class LauncherModel extends BroadcastReceiver * use partial updates similar to {@link UserManagerCompat} */ public void refreshShortcutsIfRequired() { - sWorker.removeCallbacks(mShortcutPermissionCheckRunnable); - sWorker.post(mShortcutPermissionCheckRunnable); + MODEL_EXECUTOR.getHandler().removeCallbacks(mShortcutPermissionCheckRunnable); + MODEL_EXECUTOR.post(mShortcutPermissionCheckRunnable); } /** @@ -457,14 +447,8 @@ public class LauncherModel extends BroadcastReceiver } public void enqueueModelUpdateTask(ModelUpdateTask task) { - task.init(mApp, this, sBgDataModel, mBgAllAppsList, mUiExecutor); - - if (sWorkerThread.getThreadId() == Process.myTid()) { - task.run(); - } else { - // If we are not on the worker thread, then post to the worker handler - sWorker.post(task); - } + task.init(mApp, this, sBgDataModel, mBgAllAppsList, MAIN_EXECUTOR); + MODEL_EXECUTOR.execute(task); } /** @@ -540,14 +524,4 @@ public class LauncherModel extends BroadcastReceiver return mCallbacks != null ? mCallbacks.get() : null; } - /** - * @return the looper for the worker thread which can be used to start background tasks. - */ - public static Looper getWorkerLooper() { - return mWorkerLooper; - } - - public static void setWorkerPriority(final int priority) { - Process.setThreadPriority(sWorkerThread.getThreadId(), priority); - } } diff --git a/src/com/android/launcher3/MainThreadExecutor.java b/src/com/android/launcher3/MainThreadExecutor.java deleted file mode 100644 index 5094682333..0000000000 --- a/src/com/android/launcher3/MainThreadExecutor.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2014 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; - -import android.os.Looper; - -import com.android.launcher3.util.LooperExecutor; - -/** - * An executor service that executes its tasks on the main thread. - * - * Shutting down this executor is not supported. - */ -public class MainThreadExecutor extends LooperExecutor { - - public MainThreadExecutor() { - super(Looper.getMainLooper()); - } -} diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java index b0da6b9cd9..a1c77ef1d1 100644 --- a/src/com/android/launcher3/SessionCommitReceiver.java +++ b/src/com/android/launcher3/SessionCommitReceiver.java @@ -30,13 +30,13 @@ import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; -import android.os.Process; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import com.android.launcher3.compat.LauncherAppsCompat; +import com.android.launcher3.util.Executors; import java.util.List; @@ -103,7 +103,7 @@ public class SessionCommitReceiver extends BroadcastReceiver { // grid. prefs.edit().putBoolean(ADD_ICON_PREFERENCE_KEY, true).apply(); } else if (!prefs.contains(ADD_ICON_PREFERENCE_INITIALIZED_KEY)) { - new PrefInitTask(context).executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR); + new PrefInitTask(context).executeOnExecutor(Executors.THREAD_POOL_EXECUTOR); } } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 05336f2e7d..6ddebe75d0 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -76,10 +76,6 @@ import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; import java.util.Locale; -import java.util.concurrent.Executor; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -112,8 +108,6 @@ public final class Utilities { public static final boolean ATLEAST_OREO = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; - public static final int SINGLE_FRAME_MS = 16; - /** * Set on a motion event dispatched from the nav bar. See {@link MotionEvent#setEdgeFlags(int)}. */ @@ -136,18 +130,6 @@ public final class Utilities { public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET"; public static final String EXTRA_WALLPAPER_FLAVOR = "com.android.launcher3.WALLPAPER_FLAVOR"; - // These values are same as that in {@link AsyncTask}. - private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); - private static final int CORE_POOL_SIZE = CPU_COUNT + 1; - private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; - private static final int KEEP_ALIVE = 1; - /** - * An {@link Executor} to be used with async task with no limit on the queue size. - */ - public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor( - CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, - TimeUnit.SECONDS, new LinkedBlockingQueue<>()); - public static boolean IS_RUNNING_IN_TEST_HARNESS = ActivityManager.isRunningInTestHarness(); diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java index 6d1bc1a9c0..003bcc1ce2 100644 --- a/src/com/android/launcher3/WidgetPreviewLoader.java +++ b/src/com/android/launcher3/WidgetPreviewLoader.java @@ -1,5 +1,8 @@ package com.android.launcher3; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; @@ -23,21 +26,23 @@ import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.CancellationSignal; -import android.os.Handler; import android.os.Process; import android.os.UserHandle; import android.util.Log; import android.util.LongSparseArray; +import androidx.annotation.Nullable; + import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.ShortcutConfigActivityInfo; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.icons.GraphicsUtils; +import com.android.launcher3.icons.IconCache; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.icons.ShadowGenerator; -import com.android.launcher3.icons.IconCache; import com.android.launcher3.model.WidgetItem; import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.util.Executors; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.SQLiteCacheHelper; @@ -50,11 +55,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Set; import java.util.WeakHashMap; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; -import androidx.annotation.Nullable; - public class WidgetPreviewLoader { private static final String TAG = "WidgetPreviewLoader"; @@ -68,23 +70,18 @@ public class WidgetPreviewLoader { * Note: synchronized block used for this variable is expensive and the block should always * be posted to a background thread. */ - @Thunk final Set mUnusedBitmaps = - Collections.newSetFromMap(new WeakHashMap()); + @Thunk final Set mUnusedBitmaps = Collections.newSetFromMap(new WeakHashMap<>()); private final Context mContext; private final IconCache mIconCache; private final UserManagerCompat mUserManager; private final CacheDb mDb; - private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); - @Thunk final Handler mWorkerHandler; - public WidgetPreviewLoader(Context context, IconCache iconCache) { mContext = context; mIconCache = iconCache; mUserManager = UserManagerCompat.getInstance(context); mDb = new CacheDb(context); - mWorkerHandler = new Handler(LauncherModel.getWorkerLooper()); } /** @@ -99,7 +96,7 @@ public class WidgetPreviewLoader { WidgetCacheKey key = new WidgetCacheKey(item.componentName, item.user, size); PreviewLoadTask task = new PreviewLoadTask(key, item, previewWidth, previewHeight, caller); - task.executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR); + task.executeOnExecutor(Executors.THREAD_POOL_EXECUTOR); CancellationSignal signal = new CancellationSignal(); signal.setOnCancelListener(task); @@ -494,12 +491,7 @@ public class WidgetPreviewLoader { private Drawable mutateOnMainThread(final Drawable drawable) { try { - return mMainThreadExecutor.submit(new Callable() { - @Override - public Drawable call() throws Exception { - return drawable.mutate(); - } - }).get(); + return MAIN_EXECUTOR.submit(drawable::mutate).get(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e); @@ -607,7 +599,7 @@ public class WidgetPreviewLoader { // Write the generated preview to the DB in the worker thread if (mVersions != null) { - mWorkerHandler.post(new Runnable() { + MODEL_EXECUTOR.post(new Runnable() { @Override public void run() { if (!isCancelled()) { @@ -637,7 +629,7 @@ public class WidgetPreviewLoader { // recycled set immediately. Otherwise, it will be recycled after the preview is written // to disk. if (preview != null) { - mWorkerHandler.post(new Runnable() { + MODEL_EXECUTOR.post(new Runnable() { @Override public void run() { synchronized (mUnusedBitmaps) { @@ -658,7 +650,7 @@ public class WidgetPreviewLoader { // in the tasks's onCancelled() call, and if cancelled while the task is writing to // disk, it will be cancelled in the task's onPostExecute() call. if (mBitmapToRecycle != null) { - mWorkerHandler.post(new Runnable() { + MODEL_EXECUTOR.post(new Runnable() { @Override public void run() { synchronized (mUnusedBitmaps) { diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 812f44458c..d9eb311bde 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -90,6 +90,7 @@ import com.android.launcher3.touch.WorkspaceTouchListener; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; +import com.android.launcher3.util.Executors; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.IntSparseArrayMap; @@ -1159,7 +1160,7 @@ public class Workspace extends PagedView } protected void setWallpaperDimension() { - Utilities.THREAD_POOL_EXECUTOR.execute(new Runnable() { + Executors.THREAD_POOL_EXECUTOR.execute(new Runnable() { @Override public void run() { final Point size = LauncherAppState.getIDP(getContext()).defaultWallpaperSize; diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java index 6e7a1bdcfe..5e13d00b74 100644 --- a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java +++ b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java @@ -16,6 +16,8 @@ package com.android.launcher3.compat; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; @@ -30,19 +32,17 @@ import android.os.Parcelable; import android.os.Process; import android.os.UserHandle; +import androidx.annotation.Nullable; + import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherModel; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.compat.ShortcutConfigActivityInfo.ShortcutConfigActivityInfoVO; import com.android.launcher3.icons.LauncherIcons; -import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.PackageUserKey; import java.util.ArrayList; import java.util.List; -import androidx.annotation.Nullable; - @TargetApi(26) public class LauncherAppsCompatVO extends LauncherAppsCompatVL { @@ -120,7 +120,7 @@ public class LauncherAppsCompatVO extends LauncherAppsCompatVL { } } else { // Block the worker thread until the accept() is called. - new LooperExecutor(LauncherModel.getWorkerLooper()).execute(new Runnable() { + MODEL_EXECUTOR.execute(new Runnable() { @Override public void run() { try { diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java index 8a5eabca99..052b0c373e 100644 --- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java +++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java @@ -16,22 +16,22 @@ package com.android.launcher3.compat; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller.SessionCallback; import android.content.pm.PackageInstaller.SessionInfo; -import android.os.Handler; import android.os.Process; import android.os.UserHandle; import android.text.TextUtils; import android.util.SparseArray; -import com.android.launcher3.Utilities; -import com.android.launcher3.icons.IconCache; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherModel; +import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.icons.IconCache; import com.android.launcher3.util.Thunk; import java.util.ArrayList; @@ -47,7 +47,6 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat { @Thunk final PackageInstaller mInstaller; private final IconCache mCache; - private final Handler mWorker; private final Context mAppContext; private final HashMap mSessionVerifiedMap = new HashMap<>(); private final LauncherAppsCompat mLauncherApps; @@ -56,8 +55,7 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat { mAppContext = context.getApplicationContext(); mInstaller = context.getPackageManager().getPackageInstaller(); mCache = LauncherAppState.getInstance(context).getIconCache(); - mWorker = new Handler(LauncherModel.getWorkerLooper()); - mInstaller.registerSessionCallback(mCallback, mWorker); + mInstaller.registerSessionCallback(mCallback, MODEL_EXECUTOR.getHandler()); mLauncherApps = LauncherAppsCompat.getInstance(context); } diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java index a2dcbf87d7..9fb10905f8 100644 --- a/src/com/android/launcher3/dragndrop/AddItemActivity.java +++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java @@ -20,6 +20,7 @@ import static com.android.launcher3.logging.LoggerUtils.newCommandAction; import static com.android.launcher3.logging.LoggerUtils.newContainerTarget; import static com.android.launcher3.logging.LoggerUtils.newItemTarget; import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.annotation.TargetApi; import android.app.ActivityOptions; @@ -47,7 +48,6 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetHost; import com.android.launcher3.LauncherAppWidgetProviderInfo; -import com.android.launcher3.LauncherModel; import com.android.launcher3.R; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.LauncherAppsCompatVO; @@ -55,7 +55,6 @@ import com.android.launcher3.model.WidgetItem; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.InstantAppResolver; -import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; @@ -234,7 +233,7 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener mWidgetCell.applyFromCellItem(item, mApp.getWidgetCache()); mWidgetCell.ensurePreview(); } - }.executeOnExecutor(new LooperExecutor(LauncherModel.getWorkerLooper())); + }.executeOnExecutor(MODEL_EXECUTOR); // TODO: Create a worker looper executor and reuse that everywhere. } diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java index 09c5e5b2b2..f66d07e3d8 100644 --- a/src/com/android/launcher3/dragndrop/DragView.java +++ b/src/com/android/launcher3/dragndrop/DragView.java @@ -17,6 +17,7 @@ package com.android.launcher3.dragndrop; import static com.android.launcher3.Utilities.getBadge; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -41,16 +42,19 @@ import android.os.Handler; import android.os.Looper; import android.view.View; +import androidx.dynamicanimation.animation.FloatPropertyCompat; +import androidx.dynamicanimation.animation.SpringAnimation; +import androidx.dynamicanimation.animation.SpringForce; + import com.android.launcher3.FastBitmapDrawable; +import com.android.launcher3.FirstFrameAnimatorHelper; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; -import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.FirstFrameAnimatorHelper; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.util.Themes; @@ -58,10 +62,6 @@ import com.android.launcher3.util.Thunk; import java.util.Arrays; -import androidx.dynamicanimation.animation.FloatPropertyCompat; -import androidx.dynamicanimation.animation.SpringAnimation; -import androidx.dynamicanimation.animation.SpringForce; - public class DragView extends View implements LauncherStateManager.StateListener { private static final ColorMatrix sTempMatrix1 = new ColorMatrix(); private static final ColorMatrix sTempMatrix2 = new ColorMatrix(); @@ -210,7 +210,7 @@ public class DragView extends View implements LauncherStateManager.StateListener return; } // Load the adaptive icon on a background thread and add the view in ui thread. - new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(new Runnable() { + MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(new Runnable() { @Override public void run() { Object[] outObj = new Object[1]; diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java index d8a1f99516..0bb3fbac52 100644 --- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java +++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java @@ -16,6 +16,8 @@ package com.android.launcher3.dragndrop; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + import android.annotation.TargetApi; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -31,7 +33,6 @@ import android.util.Log; import androidx.annotation.Nullable; import com.android.launcher3.Launcher; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.R; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.folder.PreviewBackground; @@ -85,7 +86,7 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable { // Create the actual drawable on the UI thread to avoid race conditions with // FolderIcon draw pass try { - return new MainThreadExecutor().submit(() -> { + return MAIN_EXECUTOR.submit(() -> { FolderIcon icon = launcher.findFolderIcon(folderId); return icon == null ? null : createDrawableOnUiThread(icon, badge, dragViewSize); }).get(); diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java index 9263a2ac94..747efe3075 100644 --- a/src/com/android/launcher3/graphics/DragPreviewProvider.java +++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java @@ -16,6 +16,8 @@ package com.android.launcher3.graphics; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; + import android.content.Context; import android.graphics.Bitmap; import android.graphics.BlurMaskFilter; @@ -25,7 +27,6 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.os.Handler; import android.view.View; import com.android.launcher3.BubbleTextView; @@ -35,7 +36,6 @@ import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.icons.BitmapRenderer; -import com.android.launcher3.util.UiThreadHelper; import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.launcher3.widget.PendingAppWidgetHostView; @@ -157,7 +157,7 @@ public class DragPreviewProvider { } mOutlineGeneratorCallback = new OutlineGeneratorCallback(preview); - new Handler(UiThreadHelper.getBackgroundLooper()).post(mOutlineGeneratorCallback); + UI_HELPER_EXECUTOR.post(mOutlineGeneratorCallback); } protected static Rect getDrawableBounds(Drawable d) { diff --git a/src/com/android/launcher3/graphics/GridOptionsProvider.java b/src/com/android/launcher3/graphics/GridOptionsProvider.java index efd39ee8ed..71b436600d 100644 --- a/src/com/android/launcher3/graphics/GridOptionsProvider.java +++ b/src/com/android/launcher3/graphics/GridOptionsProvider.java @@ -1,5 +1,7 @@ package com.android.launcher3.graphics; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; + import android.content.ContentProvider; import android.content.ContentValues; import android.content.res.XmlResourceParser; @@ -17,8 +19,6 @@ import android.util.Xml; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.InvariantDeviceProfile.GridOption; import com.android.launcher3.R; -import com.android.launcher3.util.LooperExecutor; -import com.android.launcher3.util.UiThreadHelper; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -180,10 +180,10 @@ public class GridOptionsProvider extends ContentProvider { throw new FileNotFoundException(e.getMessage()); } - LooperExecutor executor = new LooperExecutor(UiThreadHelper.getBackgroundLooper()); try { return openPipeHelper(uri, MIME_TYPE_PNG, null, - executor.submit(new LauncherPreviewRenderer(getContext(), idp)), BITMAP_WRITER); + UI_HELPER_EXECUTOR.submit(new LauncherPreviewRenderer(getContext(), idp)), + BITMAP_WRITER); } catch (Exception e) { throw new FileNotFoundException(e.getMessage()); } diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java index 55d58b9c09..5fb833ced4 100644 --- a/src/com/android/launcher3/icons/IconCache.java +++ b/src/com/android/launcher3/icons/IconCache.java @@ -16,6 +16,9 @@ package com.android.launcher3.icons; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -36,8 +39,6 @@ import com.android.launcher3.IconProvider; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.LauncherFiles; -import com.android.launcher3.LauncherModel; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.Utilities; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.compat.LauncherAppsCompat; @@ -59,8 +60,6 @@ public class IconCache extends BaseIconCache { private static final String TAG = "Launcher.IconCache"; - private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); - private final CachingLogic mComponentWithLabelCachingLogic; private final CachingLogic mLauncherActivityInfoCachingLogic; @@ -72,7 +71,7 @@ public class IconCache extends BaseIconCache { private int mPendingIconRequestCount = 0; public IconCache(Context context, InvariantDeviceProfile inv) { - super(context, LauncherFiles.APP_ICONS_DB, LauncherModel.getWorkerLooper(), + super(context, LauncherFiles.APP_ICONS_DB, MODEL_EXECUTOR.getLooper(), inv.fillResIconDpi, inv.iconBitmapSize, true /* inMemoryCache */); mComponentWithLabelCachingLogic = new ComponentCachingLogic(context); mLauncherActivityInfoCachingLogic = LauncherActivityCachingLogic.newInstance(context); @@ -123,7 +122,7 @@ public class IconCache extends BaseIconCache { final ItemInfoWithIcon info) { Preconditions.assertUIThread(); if (mPendingIconRequestCount <= 0) { - LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_FOREGROUND); + MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); } mPendingIconRequestCount ++; @@ -135,7 +134,7 @@ public class IconCache extends BaseIconCache { } else if (info instanceof PackageItemInfo) { getTitleAndIconForApp((PackageItemInfo) info, false); } - mMainThreadExecutor.execute(() -> { + MAIN_EXECUTOR.execute(() -> { caller.reapplyItemInfo(info); onEnd(); }); @@ -148,7 +147,7 @@ public class IconCache extends BaseIconCache { private void onIconRequestEnd() { mPendingIconRequestCount --; if (mPendingIconRequestCount <= 0) { - LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_BACKGROUND); + MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } } diff --git a/src/com/android/launcher3/logging/FileLog.java b/src/com/android/launcher3/logging/FileLog.java index cc920767f6..47a0f537c8 100644 --- a/src/com/android/launcher3/logging/FileLog.java +++ b/src/com/android/launcher3/logging/FileLog.java @@ -1,5 +1,7 @@ package com.android.launcher3.logging; +import static com.android.launcher3.util.Executors.createAndStartNewLooper; + import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -92,9 +94,8 @@ public final class FileLog { private static Handler getHandler() { synchronized (DATE_FORMAT) { if (sHandler == null) { - HandlerThread thread = new HandlerThread("file-logger"); - thread.start(); - sHandler = new Handler(thread.getLooper(), new LogWriterCallback()); + sHandler = new Handler(createAndStartNewLooper("file-logger"), + new LogWriterCallback()); } } return sHandler; diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java index 018f93a5c7..0a4f00582d 100644 --- a/src/com/android/launcher3/model/BaseLoaderResults.java +++ b/src/com/android/launcher3/model/BaseLoaderResults.java @@ -16,6 +16,8 @@ package com.android.launcher3.model; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + import android.os.Looper; import android.util.Log; @@ -25,11 +27,10 @@ import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherModel.CallbackTask; -import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.LauncherSettings; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.PagedView; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.LooperIdleLock; @@ -64,7 +65,7 @@ public abstract class BaseLoaderResults { public BaseLoaderResults(LauncherAppState app, BgDataModel dataModel, AllAppsList allAppsList, int pageToBindFirst, WeakReference callbacks) { - mUiExecutor = new MainThreadExecutor(); + mUiExecutor = MAIN_EXECUTOR; mApp = app; mBgDataModel = dataModel; mBgAllAppsList = allAppsList; diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index 54249dc61f..8845ab3920 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -20,6 +20,7 @@ import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED; import static com.android.launcher3.model.LoaderResults.filterCurrentWorkspaceItems; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import static com.android.launcher3.util.PackageManagerHelper.isSystemApp; import android.appwidget.AppWidgetProviderInfo; @@ -32,7 +33,6 @@ import android.content.pm.LauncherActivityInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.ShortcutInfo; -import android.os.Handler; import android.os.Process; import android.os.UserHandle; import android.text.TextUtils; @@ -772,7 +772,7 @@ public class LoaderTask implements Runnable { new SdCardAvailableReceiver(mApp, pendingPackages), new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, - new Handler(LauncherModel.getWorkerLooper())); + MODEL_EXECUTOR.getHandler()); } } } diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java index d7ab0ddae8..b7a19d39ee 100644 --- a/src/com/android/launcher3/model/ModelWriter.java +++ b/src/com/android/launcher3/model/ModelWriter.java @@ -16,6 +16,8 @@ package com.android.launcher3.model; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.ContentValues; @@ -31,17 +33,16 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetHost; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherModel; -import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.LauncherProvider; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.LauncherSettings.Settings; -import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.Utilities; +import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.util.ContentWriter; import com.android.launcher3.util.ItemInfoMatcher; -import com.android.launcher3.util.LooperExecutor; import java.util.ArrayList; import java.util.Arrays; @@ -61,7 +62,6 @@ public class ModelWriter { private final BgDataModel mBgDataModel; private final Handler mUiHandler; - private final Executor mWorkerExecutor; private final boolean mHasVerticalHotseat; private final boolean mVerifyChanges; @@ -74,7 +74,6 @@ public class ModelWriter { mContext = context; mModel = model; mBgDataModel = dataModel; - mWorkerExecutor = new LooperExecutor(LauncherModel.getWorkerLooper()); mHasVerticalHotseat = hasVerticalHotseat; mVerifyChanges = verifyChanges; mUiHandler = new Handler(Looper.getMainLooper()); @@ -194,7 +193,7 @@ public class ModelWriter { item.spanX = spanX; item.spanY = spanY; - mWorkerExecutor.execute(new UpdateItemRunnable(item, () -> + ((Executor) MODEL_EXECUTOR).execute(new UpdateItemRunnable(item, () -> new ContentWriter(mContext) .put(Favorites.CONTAINER, item.container) .put(Favorites.CELLX, item.cellX) @@ -209,7 +208,7 @@ public class ModelWriter { * Update an item to the database in a specified container. */ public void updateItemInDatabase(ItemInfo item) { - mWorkerExecutor.execute(new UpdateItemRunnable(item, () -> { + ((Executor) MODEL_EXECUTOR).execute(new UpdateItemRunnable(item, () -> { ContentWriter writer = new ContentWriter(mContext); item.onAddToDatabase(writer); return writer; @@ -229,7 +228,7 @@ public class ModelWriter { ModelVerifier verifier = new ModelVerifier(); final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); - mWorkerExecutor.execute(() -> { + ((Executor) MODEL_EXECUTOR).execute(() -> { // Write the item on background thread, as some properties might have been updated in // the background. final ContentWriter writer = new ContentWriter(mContext); @@ -333,14 +332,14 @@ public class ModelWriter { if (mPreparingToUndo) { mDeleteRunnables.add(r); } else { - mWorkerExecutor.execute(r); + ((Executor) MODEL_EXECUTOR).execute(r); } } public void commitDelete() { mPreparingToUndo = false; for (Runnable runnable : mDeleteRunnables) { - mWorkerExecutor.execute(runnable); + ((Executor) MODEL_EXECUTOR).execute(runnable); } mDeleteRunnables.clear(); } diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java index e57a051f88..10378ee437 100644 --- a/src/com/android/launcher3/notification/NotificationListener.java +++ b/src/com/android/launcher3/notification/NotificationListener.java @@ -16,6 +16,7 @@ package com.android.launcher3.notification; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver; import android.annotation.TargetApi; @@ -31,7 +32,8 @@ import android.text.TextUtils; import android.util.Log; import android.util.Pair; -import com.android.launcher3.LauncherModel; +import androidx.annotation.Nullable; + import com.android.launcher3.util.IntSet; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.SecureSettingsObserver; @@ -43,8 +45,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import androidx.annotation.Nullable; - /** * A {@link NotificationListenerService} that sends updates to its * {@link NotificationsChangedListener} when notifications are posted or canceled, @@ -141,7 +141,7 @@ public class NotificationListener extends NotificationListenerService { public NotificationListener() { super(); - mWorkerHandler = new Handler(LauncherModel.getWorkerLooper(), mWorkerCallback); + mWorkerHandler = new Handler(MODEL_EXECUTOR.getLooper(), mWorkerCallback); mUiHandler = new Handler(Looper.getMainLooper(), mUiCallback); sNotificationListenerInstance = this; } diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index baaad65736..1296a969dd 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -24,6 +24,7 @@ import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFI import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType; import static com.android.launcher3.userevent.nano.LauncherLogProto.Target; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.animation.AnimatorSet; import android.animation.LayoutTransition; @@ -36,7 +37,6 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; -import android.util.Log; import android.util.Pair; import android.view.MotionEvent; import android.view.View; @@ -51,9 +51,7 @@ import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.ItemInfo; import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.Launcher; -import com.android.launcher3.LauncherModel; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate; import com.android.launcher3.dot.DotInfo; @@ -65,10 +63,8 @@ import com.android.launcher3.notification.NotificationInfo; import com.android.launcher3.notification.NotificationItemView; import com.android.launcher3.notification.NotificationKeyData; import com.android.launcher3.popup.PopupDataProvider.PopupDataChangeListener; -import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.touch.ItemLongClickListener; import com.android.launcher3.util.PackageUserKey; @@ -307,8 +303,7 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource, setLayoutTransition(new LayoutTransition()); // Load the shortcuts on a background thread and update the container as it animates. - final Looper workerLooper = LauncherModel.getWorkerLooper(); - new Handler(workerLooper).postAtFrontOfQueue(PopupPopulator.createUpdateRunnable( + MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(PopupPopulator.createUpdateRunnable( mLauncher, originalItemInfo, new Handler(Looper.getMainLooper()), this, mShortcuts, notificationKeys)); } diff --git a/src/com/android/launcher3/states/InternalStateHandler.java b/src/com/android/launcher3/states/InternalStateHandler.java index 446d4f8ed7..a23cd6d2e3 100644 --- a/src/com/android/launcher3/states/InternalStateHandler.java +++ b/src/com/android/launcher3/states/InternalStateHandler.java @@ -15,6 +15,8 @@ */ package com.android.launcher3.states; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + import android.content.Intent; import android.os.Binder; import android.os.Bundle; @@ -23,7 +25,6 @@ import android.os.IBinder; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.model.BgDataModel.Callbacks; -import com.android.launcher3.MainThreadExecutor; import java.lang.ref.WeakReference; @@ -94,16 +95,12 @@ public abstract class InternalStateHandler extends Binder { private static class Scheduler implements Runnable { private WeakReference mPendingHandler = new WeakReference<>(null); - private MainThreadExecutor mMainThreadExecutor; public void schedule(InternalStateHandler handler) { synchronized (this) { mPendingHandler = new WeakReference<>(handler); - if (mMainThreadExecutor == null) { - mMainThreadExecutor = new MainThreadExecutor(); - } } - mMainThreadExecutor.execute(this); + MAIN_EXECUTOR.execute(this); } @Override diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index 4fd0f884d6..516c251bf3 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -15,6 +15,8 @@ */ package com.android.launcher3.testing; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + import android.content.Context; import android.os.Bundle; @@ -23,7 +25,6 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherState; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.R; import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.util.ResourceBasedOverride; @@ -88,20 +89,20 @@ public class TestInformationHandler implements ResourceBasedOverride { break; case TestProtocol.REQUEST_FREEZE_APP_LIST: - new MainThreadExecutor().execute(() -> + MAIN_EXECUTOR.execute(() -> mLauncher.getAppsView().getAppsStore().enableDeferUpdates( AllAppsStore.DEFER_UPDATES_TEST)); break; case TestProtocol.REQUEST_UNFREEZE_APP_LIST: - new MainThreadExecutor().execute(() -> + MAIN_EXECUTOR.execute(() -> mLauncher.getAppsView().getAppsStore().disableDeferUpdates( AllAppsStore.DEFER_UPDATES_TEST)); break; case TestProtocol.REQUEST_APP_LIST_FREEZE_FLAGS: { try { - final int deferUpdatesFlags = new MainThreadExecutor().submit(() -> + final int deferUpdatesFlags = MAIN_EXECUTOR.submit(() -> mLauncher.getAppsView().getAppsStore().getDeferUpdatesFlags()).get(); response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, deferUpdatesFlags); diff --git a/src/com/android/launcher3/util/ConfigMonitor.java b/src/com/android/launcher3/util/ConfigMonitor.java index 12d35e9628..4ae84d808a 100644 --- a/src/com/android/launcher3/util/ConfigMonitor.java +++ b/src/com/android/launcher3/util/ConfigMonitor.java @@ -16,6 +16,9 @@ package com.android.launcher3.util; * limitations under the License. */ +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -24,13 +27,10 @@ import android.content.res.Configuration; import android.graphics.Point; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; -import android.os.Handler; import android.util.Log; import android.view.Display; import android.view.WindowManager; -import com.android.launcher3.MainThreadExecutor; - import java.util.function.Consumer; /** @@ -78,7 +78,7 @@ public class ConfigMonitor extends BroadcastReceiver implements DisplayListener // Listen for display manager change mContext.getSystemService(DisplayManager.class) - .registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper())); + .registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler()); } @Override @@ -122,7 +122,7 @@ public class ConfigMonitor extends BroadcastReceiver implements DisplayListener if (mCallback != null) { Consumer callback = mCallback; mCallback = null; - new MainThreadExecutor().execute(() -> callback.accept(mContext)); + MAIN_EXECUTOR.execute(() -> callback.accept(mContext)); } } diff --git a/src/com/android/launcher3/util/DefaultDisplay.java b/src/com/android/launcher3/util/DefaultDisplay.java index 7719f084d7..4080e212bc 100644 --- a/src/com/android/launcher3/util/DefaultDisplay.java +++ b/src/com/android/launcher3/util/DefaultDisplay.java @@ -15,6 +15,8 @@ */ package com.android.launcher3.util; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; + import android.content.Context; import android.graphics.Point; import android.hardware.display.DisplayManager; @@ -54,7 +56,7 @@ public class DefaultDisplay implements DisplayListener { mChangeHandler = new Handler(this::onChange); context.getSystemService(DisplayManager.class) - .registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper())); + .registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler()); } @Override diff --git a/src/com/android/launcher3/util/Executors.java b/src/com/android/launcher3/util/Executors.java new file mode 100644 index 0000000000..4d5ee49e83 --- /dev/null +++ b/src/com/android/launcher3/util/Executors.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2008 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 android.os.HandlerThread; +import android.os.Looper; +import android.os.Process; + +import java.util.concurrent.Executor; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Various different executors used in Launcher + */ +public class Executors { + + // These values are same as that in {@link AsyncTask}. + private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); + private static final int CORE_POOL_SIZE = CPU_COUNT + 1; + private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; + private static final int KEEP_ALIVE = 1; + + /** + * An {@link Executor} to be used with async task with no limit on the queue size. + */ + public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor( + CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, + TimeUnit.SECONDS, new LinkedBlockingQueue<>()); + + /** + * Returns the executor for running tasks on the main thread. + */ + public static final LooperExecutor MAIN_EXECUTOR = + new LooperExecutor(Looper.getMainLooper()); + + /** + * A background executor for using time sensitive actions where user is waiting for response. + */ + public static final LooperExecutor UI_HELPER_EXECUTOR = + new LooperExecutor(createAndStartNewForegroundLooper("UiThreadHelper")); + + /** + * Utility method to get a started handler thread statically + */ + public static Looper createAndStartNewLooper(String name) { + return createAndStartNewLooper(name, Process.THREAD_PRIORITY_DEFAULT); + } + + /** + * Utility method to get a started handler thread statically with the provided priority + */ + public static Looper createAndStartNewLooper(String name, int priority) { + HandlerThread thread = new HandlerThread(name, priority); + thread.start(); + return thread.getLooper(); + } + + /** + * Similar to {@link #createAndStartNewLooper(String)}, but starts the thread with + * foreground priority. + * Think before using + */ + public static Looper createAndStartNewForegroundLooper(String name) { + return createAndStartNewLooper(name, Process.THREAD_PRIORITY_FOREGROUND); + } + + /** + * Executor used for running Launcher model related tasks (eg loading icons or updated db) + */ + public static final LooperExecutor MODEL_EXECUTOR = + new LooperExecutor(createAndStartNewLooper("launcher-loader")); +} diff --git a/src/com/android/launcher3/util/LooperExecutor.java b/src/com/android/launcher3/util/LooperExecutor.java index cc07469971..8ac600f735 100644 --- a/src/com/android/launcher3/util/LooperExecutor.java +++ b/src/com/android/launcher3/util/LooperExecutor.java @@ -16,7 +16,9 @@ package com.android.launcher3.util; import android.os.Handler; +import android.os.HandlerThread; import android.os.Looper; +import android.os.Process; import java.util.List; import java.util.concurrent.AbstractExecutorService; @@ -46,6 +48,13 @@ public class LooperExecutor extends AbstractExecutorService { } } + /** + * Same as execute, but never runs the action inline. + */ + public void post(Runnable runnable) { + mHandler.post(runnable); + } + /** * Not supported and throws an exception when used. */ @@ -79,7 +88,31 @@ public class LooperExecutor extends AbstractExecutorService { */ @Override @Deprecated - public boolean awaitTermination(long l, TimeUnit timeUnit) throws InterruptedException { + public boolean awaitTermination(long l, TimeUnit timeUnit) { throw new UnsupportedOperationException(); } + + /** + * Returns the thread for this executor + */ + public Thread getThread() { + return mHandler.getLooper().getThread(); + } + + /** + * Returns the looper for this executor + */ + public Looper getLooper() { + return mHandler.getLooper(); + } + + /** + * Set the priority of a thread, based on Linux priorities. + * @param priority Linux priority level, from -20 for highest scheduling priority + * to 19 for lowest scheduling priority. + * @see Process#setThreadPriority(int, int) + */ + public void setThreadPriority(int priority) { + Process.setThreadPriority(((HandlerThread) getThread()).getThreadId(), priority); + } } diff --git a/src/com/android/launcher3/util/MainThreadInitializedObject.java b/src/com/android/launcher3/util/MainThreadInitializedObject.java index e185a31990..fe9c2c468b 100644 --- a/src/com/android/launcher3/util/MainThreadInitializedObject.java +++ b/src/com/android/launcher3/util/MainThreadInitializedObject.java @@ -15,12 +15,13 @@ */ package com.android.launcher3.util; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + import android.content.Context; import android.os.Looper; import androidx.annotation.VisibleForTesting; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.util.ResourceBasedOverride.Overrides; import java.util.concurrent.ExecutionException; @@ -43,7 +44,7 @@ public class MainThreadInitializedObject { mValue = mProvider.get(context.getApplicationContext()); } else { try { - return new MainThreadExecutor().submit(() -> get(context)).get(); + return MAIN_EXECUTOR.submit(() -> get(context)).get(); } catch (InterruptedException|ExecutionException e) { throw new RuntimeException(e); } diff --git a/src/com/android/launcher3/util/Preconditions.java b/src/com/android/launcher3/util/Preconditions.java index 7ab0d3103d..ed66422be0 100644 --- a/src/com/android/launcher3/util/Preconditions.java +++ b/src/com/android/launcher3/util/Preconditions.java @@ -16,9 +16,10 @@ package com.android.launcher3.util; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.os.Looper; -import com.android.launcher3.LauncherModel; import com.android.launcher3.config.FeatureFlags; /** @@ -33,7 +34,7 @@ public class Preconditions { } public static void assertWorkerThread() { - if (FeatureFlags.IS_DOGFOOD_BUILD && !isSameLooper(LauncherModel.getWorkerLooper())) { + if (FeatureFlags.IS_DOGFOOD_BUILD && !isSameLooper(MODEL_EXECUTOR.getLooper())) { throw new IllegalStateException(); } } diff --git a/src/com/android/launcher3/util/UiThreadHelper.java b/src/com/android/launcher3/util/UiThreadHelper.java index cc442f988e..f8d163230d 100644 --- a/src/com/android/launcher3/util/UiThreadHelper.java +++ b/src/com/android/launcher3/util/UiThreadHelper.java @@ -15,14 +15,13 @@ */ package com.android.launcher3.util; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; + import android.app.Activity; import android.content.Context; import android.os.Handler; -import android.os.HandlerThread; import android.os.IBinder; -import android.os.Looper; import android.os.Message; -import android.os.Process; import android.view.inputmethod.InputMethodManager; /** @@ -30,25 +29,15 @@ import android.view.inputmethod.InputMethodManager; */ public class UiThreadHelper { - private static HandlerThread sHandlerThread; private static Handler sHandler; private static final int MSG_HIDE_KEYBOARD = 1; private static final int MSG_SET_ORIENTATION = 2; private static final int MSG_RUN_COMMAND = 3; - public static Looper getBackgroundLooper() { - if (sHandlerThread == null) { - sHandlerThread = - new HandlerThread("UiThreadHelper", Process.THREAD_PRIORITY_FOREGROUND); - sHandlerThread.start(); - } - return sHandlerThread.getLooper(); - } - private static Handler getHandler(Context context) { if (sHandler == null) { - sHandler = new Handler(getBackgroundLooper(), + sHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), new UiCallbacks(context.getApplicationContext())); } return sHandler; diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java index acce308607..61ba4e5662 100644 --- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java +++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java @@ -16,13 +16,14 @@ package com.android.launcher3.util; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.os.Process; import android.view.View; import android.view.View.OnAttachStateChangeListener; import android.view.ViewTreeObserver.OnDrawListener; import com.android.launcher3.Launcher; -import com.android.launcher3.LauncherModel; import java.util.ArrayList; import java.util.concurrent.Executor; @@ -66,7 +67,7 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable, @Override public void execute(Runnable command) { mTasks.add(command); - LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_BACKGROUND); + MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } @Override @@ -108,7 +109,7 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable, if (mLauncher != null) { mLauncher.clearPendingExecutor(this); } - LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_DEFAULT); + MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); } protected boolean isCompleted() { diff --git a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java index 5c24687404..2ad80cf665 100644 --- a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java +++ b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java @@ -1,5 +1,7 @@ package com.android.launcher3.util; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; + import android.app.WallpaperManager; import android.content.BroadcastReceiver; import android.content.Context; @@ -198,7 +200,7 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver { private float mOffsetX; public OffsetHandler(Context context) { - super(UiThreadHelper.getBackgroundLooper()); + super(UI_HELPER_EXECUTOR.getLooper()); mInterpolator = Interpolators.DEACCEL_1_5; mWM = WallpaperManager.getInstance(context); } diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index e09a9e8bfc..b146452bd6 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -18,11 +18,11 @@ package com.android.launcher3.views; import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA; import static com.android.launcher3.Utilities.getBadge; import static com.android.launcher3.Utilities.getFullDrawable; -import static com.android.launcher3.Utilities.isRtl; import static com.android.launcher3.Utilities.mapToRange; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -42,7 +42,6 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.CancellationSignal; -import android.os.Handler; import android.util.AttributeSet; import android.util.Log; import android.view.View; @@ -51,11 +50,17 @@ import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.ImageView; +import androidx.annotation.Nullable; +import androidx.annotation.UiThread; +import androidx.annotation.WorkerThread; +import androidx.dynamicanimation.animation.FloatPropertyCompat; +import androidx.dynamicanimation.animation.SpringAnimation; +import androidx.dynamicanimation.animation.SpringForce; + import com.android.launcher3.BubbleTextView; import com.android.launcher3.InsettableFrameLayout.LayoutParams; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; -import com.android.launcher3.LauncherModel; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.dragndrop.DragLayer; @@ -67,13 +72,6 @@ import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.shortcuts.DeepShortcutView; -import androidx.annotation.Nullable; -import androidx.annotation.UiThread; -import androidx.annotation.WorkerThread; -import androidx.dynamicanimation.animation.FloatPropertyCompat; -import androidx.dynamicanimation.animation.SpringAnimation; -import androidx.dynamicanimation.animation.SpringForce; - /** * A view that is created to look like another view with the purpose of creating fluid animations. */ @@ -717,7 +715,7 @@ public class FloatingIconView extends View implements @UiThread public static IconLoadResult fetchIcon(Launcher l, View v, ItemInfo info, boolean isOpening) { IconLoadResult result = new IconLoadResult(); - new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(() -> { + MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> { RectF position = new RectF(); getLocationBoundsForView(l, v, isOpening, position); getIconResult(l, v, info, position, result); diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index dce839f397..f3fd7ca4da 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -44,6 +44,7 @@ import com.android.launcher3.SimpleOnStylusPressListener; import com.android.launcher3.StylusEventHelper; import com.android.launcher3.Utilities; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.util.Executors; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer.TouchCompleteListener; @@ -96,7 +97,7 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView setBackgroundResource(R.drawable.widget_internal_focus_bg); if (Utilities.ATLEAST_OREO) { - setExecutor(Utilities.THREAD_POOL_EXECUTOR); + setExecutor(Executors.THREAD_POOL_EXECUTOR); } if (Utilities.ATLEAST_Q && Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText)) { setOnLightBackground(true); @@ -332,12 +333,7 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView if (shouldRegisterAutoAdvance != mIsAutoAdvanceRegistered) { mIsAutoAdvanceRegistered = shouldRegisterAutoAdvance; if (mAutoAdvanceRunnable == null) { - mAutoAdvanceRunnable = new Runnable() { - @Override - public void run() { - runAutoAdvance(); - } - }; + mAutoAdvanceRunnable = this::runAutoAdvance; } handler.removeCallbacks(mAutoAdvanceRunnable); diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index fc19baace2..6d636cf698 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -19,12 +19,12 @@ import static androidx.test.InstrumentationRegistry.getInstrumentation; import static com.android.launcher3.tapl.LauncherInstrumentation.ContainerType; import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static org.junit.Assert.assertTrue; import static java.lang.System.exit; -import android.app.Instrumentation; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -48,7 +48,6 @@ import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.Utilities; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.model.AppLaunchTracker; @@ -56,6 +55,7 @@ import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.tapl.TestHelpers; import com.android.launcher3.testcomponent.TestCommandReceiver; import com.android.launcher3.testing.TestProtocol; +import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.FailureWatcher; @@ -90,7 +90,7 @@ public abstract class AbstractLauncherUiTest { public static final long DEFAULT_UI_TIMEOUT = 60000; // b/136278866 private static final String TAG = "AbstractLauncherUiTest"; - protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); + protected LooperExecutor mMainThreadExecutor = MAIN_EXECUTOR; protected final UiDevice mDevice = UiDevice.getInstance(getInstrumentation()); protected final LauncherInstrumentation mLauncher = new LauncherInstrumentation(getInstrumentation()); diff --git a/tests/src/com/android/launcher3/util/Condition.java b/tests/src/com/android/launcher3/util/Condition.java index b564a1a873..d85dd3a2d7 100644 --- a/tests/src/com/android/launcher3/util/Condition.java +++ b/tests/src/com/android/launcher3/util/Condition.java @@ -1,8 +1,8 @@ package com.android.launcher3.util; -import androidx.test.uiautomator.UiObject2; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; -import com.android.launcher3.MainThreadExecutor; +import androidx.test.uiautomator.UiObject2; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -16,7 +16,7 @@ public interface Condition { * Converts the condition to be run on UI thread. */ static Condition runOnUiThread(final Condition condition) { - final MainThreadExecutor executor = new MainThreadExecutor(); + final LooperExecutor executor = MAIN_EXECUTOR; return () -> { final AtomicBoolean value = new AtomicBoolean(false); final Throwable[] exceptions = new Throwable[1]; diff --git a/tests/src/com/android/launcher3/util/RaceConditionReproducer.java b/tests/src/com/android/launcher3/util/RaceConditionReproducer.java index 0235f95d0b..8f89173203 100644 --- a/tests/src/com/android/launcher3/util/RaceConditionReproducer.java +++ b/tests/src/com/android/launcher3/util/RaceConditionReproducer.java @@ -16,6 +16,7 @@ package com.android.launcher3.util; +import static com.android.launcher3.util.Executors.createAndStartNewLooper; import static com.android.launcher3.util.RaceConditionTracker.ENTER_POSTFIX; import static com.android.launcher3.util.RaceConditionTracker.EXIT_POSTFIX; @@ -23,7 +24,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.os.Handler; -import android.os.HandlerThread; import android.util.Log; import java.util.ArrayList; @@ -72,9 +72,7 @@ public class RaceConditionReproducer implements RaceConditionTracker.EventProces private static final Handler POSTPONED_EVENT_RESUME_HANDLER = createEventResumeHandler(); private static Handler createEventResumeHandler() { - final HandlerThread thread = new HandlerThread("RaceConditionEventResumer"); - thread.start(); - return new Handler(thread.getLooper()); + return new Handler(createAndStartNewLooper("RaceConditionEventResumer")); } /**