diff --git a/src/com/android/launcher3/util/Executors.java b/src/com/android/launcher3/util/Executors.java index 6329540dc2..8485371a79 100644 --- a/src/com/android/launcher3/util/Executors.java +++ b/src/com/android/launcher3/util/Executors.java @@ -15,10 +15,17 @@ */ package com.android.launcher3.util; +import static android.os.Process.THREAD_PRIORITY_BACKGROUND; + +import static java.util.concurrent.Executors.newSingleThreadExecutor; + import android.os.HandlerThread; import android.os.Looper; import android.os.Process; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; @@ -34,6 +41,9 @@ public class Executors { Math.max(Runtime.getRuntime().availableProcessors(), 2); private static final int KEEP_ALIVE = 1; + /** Dedicated executor instances for work depending on other packages. */ + private static final Map PACKAGE_EXECUTORS = new ConcurrentHashMap<>(); + /** * An {@link ThreadPoolExecutor} to be used with async task with no limit on the queue size. */ @@ -75,6 +85,18 @@ public class Executors { public static final LooperExecutor MODEL_EXECUTOR = new LooperExecutor(createAndStartNewLooper("launcher-loader")); + /** + * Returns and caches a single thread executor for a given package. + * + * @param packageName Package associated with the executor. + */ + public static ExecutorService getPackageExecutor(String packageName) { + return PACKAGE_EXECUTORS.computeIfAbsent( + packageName, + p -> newSingleThreadExecutor( + new SimpleThreadFactory(p, THREAD_PRIORITY_BACKGROUND))); + } + /** * A simple ThreadFactory to set the thread name and priority when used with executors. */