Moving package installer initialization to worker thread

Bug: 169002215
Change-Id: Ie7b9a1eb27b634455e3d43da411037642efd0534
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index bfe327e..a4181c5 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -105,7 +105,7 @@
         new Handler().post( () -> mInvariantDeviceProfile.verifyConfigChangedInBackground(context));
 
         mInstallSessionTracker = InstallSessionHelper.INSTANCE.get(context)
-                .registerInstallTracker(mModel, MODEL_EXECUTOR);
+                .registerInstallTracker(mModel);
 
         // Register an observer to rebind the notification listener when dots are re-enabled.
         mNotificationDotsObserver =
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index 007e5f5..1bbbb2b 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -25,8 +25,11 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 
+import androidx.annotation.WorkerThread;
+
 import com.android.launcher3.model.ItemInstallQueue;
 import com.android.launcher3.pm.InstallSessionHelper;
+import com.android.launcher3.util.Executors;
 
 /**
  * BroadcastReceiver to handle session commit intent.
@@ -38,6 +41,11 @@
 
     @Override
     public void onReceive(Context context, Intent intent) {
+        Executors.MODEL_EXECUTOR.execute(() -> processIntent(context, intent));
+    }
+
+    @WorkerThread
+    private static void processIntent(Context context, Intent intent) {
         if (!isEnabled(context)) {
             // User has decided to not add icons on homescreen.
             return;
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 753a6dd..fa25114 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -17,6 +17,7 @@
 package com.android.launcher3.pm;
 
 import static com.android.launcher3.Utilities.getPrefs;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -31,6 +32,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
+import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.SessionCommitReceiver;
@@ -39,10 +41,10 @@
 import com.android.launcher3.model.ItemInstallQueue;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
-import com.android.launcher3.util.LooperExecutor;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.Preconditions;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -65,27 +67,27 @@
 
     private final LauncherApps mLauncherApps;
     private final Context mAppContext;
-    private final IntSet mPromiseIconIds;
 
     private final PackageInstaller mInstaller;
     private final HashMap<String, Boolean> mSessionVerifiedMap = new HashMap<>();
 
+    private IntSet mPromiseIconIds;
+
     public InstallSessionHelper(Context context) {
         mInstaller = context.getPackageManager().getPackageInstaller();
         mAppContext = context.getApplicationContext();
         mLauncherApps = context.getSystemService(LauncherApps.class);
+    }
 
+    @WorkerThread
+    private IntSet getPromiseIconIds() {
+        Preconditions.assertWorkerThread();
+        if (mPromiseIconIds != null) {
+            return mPromiseIconIds;
+        }
         mPromiseIconIds = IntSet.wrap(IntArray.fromConcatString(
-                getPrefs(context).getString(PROMISE_ICON_IDS, "")));
+                getPrefs(mAppContext).getString(PROMISE_ICON_IDS, "")));
 
-        cleanUpPromiseIconIds();
-    }
-
-    public static UserHandle getUserHandle(SessionInfo info) {
-        return Utilities.ATLEAST_Q ? info.getUser() : Process.myUserHandle();
-    }
-
-    protected void cleanUpPromiseIconIds() {
         IntArray existingIds = new IntArray();
         for (SessionInfo info : getActiveSessions().values()) {
             existingIds.add(info.getSessionId());
@@ -100,6 +102,7 @@
         for (int i = idsToRemove.size() - 1; i >= 0; --i) {
             mPromiseIconIds.getArray().removeValue(idsToRemove.get(i));
         }
+        return mPromiseIconIds;
     }
 
     public HashMap<PackageUserKey, SessionInfo> getActiveSessions() {
@@ -126,7 +129,7 @@
 
     private void updatePromiseIconPrefs() {
         getPrefs(mAppContext).edit()
-                .putString(PROMISE_ICON_IDS, mPromiseIconIds.getArray().toConcatString())
+                .putString(PROMISE_ICON_IDS, getPromiseIconIds().getArray().toConcatString())
                 .apply();
     }
 
@@ -184,13 +187,15 @@
         return info.getInstallReason() == PackageManager.INSTALL_REASON_DEVICE_RESTORE;
     }
 
+    @WorkerThread
     public boolean promiseIconAddedForId(int sessionId) {
-        return mPromiseIconIds.contains(sessionId);
+        return getPromiseIconIds().contains(sessionId);
     }
 
+    @WorkerThread
     public void removePromiseIconId(int sessionId) {
-        if (mPromiseIconIds.contains(sessionId)) {
-            mPromiseIconIds.getArray().removeValue(sessionId);
+        if (promiseIconAddedForId(sessionId)) {
+            getPromiseIconIds().getArray().removeValue(sessionId);
             updatePromiseIconPrefs();
         }
     }
@@ -203,6 +208,7 @@
      * - The app is not already installed
      * - A promise icon for the session has not already been created
      */
+    @WorkerThread
     void tryQueuePromiseAppIcon(PackageInstaller.SessionInfo sessionInfo) {
         if (FeatureFlags.PROMISE_APPS_NEW_INSTALLS.get()
                 && SessionCommitReceiver.isEnabled(mAppContext)
@@ -210,25 +216,24 @@
                 && sessionInfo.getInstallReason() == PackageManager.INSTALL_REASON_USER
                 && sessionInfo.getAppIcon() != null
                 && !TextUtils.isEmpty(sessionInfo.getAppLabel())
-                && !mPromiseIconIds.contains(sessionInfo.getSessionId())
+                && !promiseIconAddedForId(sessionInfo.getSessionId())
                 && new PackageManagerHelper(mAppContext).getApplicationInfo(
                         sessionInfo.getAppPackageName(), getUserHandle(sessionInfo), 0) == null) {
             ItemInstallQueue.INSTANCE.get(mAppContext)
                     .queueItem(sessionInfo.getAppPackageName(), getUserHandle(sessionInfo));
 
-            mPromiseIconIds.add(sessionInfo.getSessionId());
+            getPromiseIconIds().add(sessionInfo.getSessionId());
             updatePromiseIconPrefs();
         }
     }
 
-    public InstallSessionTracker registerInstallTracker(
-            InstallSessionTracker.Callback callback, LooperExecutor executor) {
+    public InstallSessionTracker registerInstallTracker(InstallSessionTracker.Callback callback) {
         InstallSessionTracker tracker = new InstallSessionTracker(this, callback);
 
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
-            mInstaller.registerSessionCallback(tracker, executor.getHandler());
+            mInstaller.registerSessionCallback(tracker, MODEL_EXECUTOR.getHandler());
         } else {
-            mLauncherApps.registerPackageInstallerSessionCallback(executor, tracker);
+            mLauncherApps.registerPackageInstallerSessionCallback(MODEL_EXECUTOR, tracker);
         }
         return tracker;
     }
@@ -240,4 +245,8 @@
             mLauncherApps.unregisterPackageInstallerSessionCallback(tracker);
         }
     }
+
+    public static UserHandle getUserHandle(SessionInfo info) {
+        return Utilities.ATLEAST_Q ? info.getUser() : Process.myUserHandle();
+    }
 }
diff --git a/src/com/android/launcher3/pm/InstallSessionTracker.java b/src/com/android/launcher3/pm/InstallSessionTracker.java
index eb3ca73..b0b907a 100644
--- a/src/com/android/launcher3/pm/InstallSessionTracker.java
+++ b/src/com/android/launcher3/pm/InstallSessionTracker.java
@@ -24,8 +24,11 @@
 import android.os.UserHandle;
 import android.util.SparseArray;
 
+import androidx.annotation.WorkerThread;
+
 import com.android.launcher3.util.PackageUserKey;
 
+@WorkerThread
 public class InstallSessionTracker extends PackageInstaller.SessionCallback {
 
     // Lazily initialized