From 573b9ca9ada0b3b0dff7daeeff8acba7d4d95229 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 22 Sep 2020 12:13:35 -0700 Subject: [PATCH] Moving package installer initialization to worker thread Bug: 169002215 Change-Id: Ie7b9a1eb27b634455e3d43da411037642efd0534 --- .../android/launcher3/LauncherAppState.java | 2 +- .../launcher3/SessionCommitReceiver.java | 8 +++ .../launcher3/pm/InstallSessionHelper.java | 51 +++++++++++-------- .../launcher3/pm/InstallSessionTracker.java | 3 ++ 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index bfe327e40d..a4181c53c9 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -105,7 +105,7 @@ public class LauncherAppState { 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 007e5f5370..1bbbb2b59e 100644 --- a/src/com/android/launcher3/SessionCommitReceiver.java +++ b/src/com/android/launcher3/SessionCommitReceiver.java @@ -25,8 +25,11 @@ import android.content.pm.PackageManager; 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 @@ public class SessionCommitReceiver extends BroadcastReceiver { @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 753a6dd85e..fa25114d49 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 android.text.TextUtils; 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.config.FeatureFlags; 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 @@ public class InstallSessionHelper { private final LauncherApps mLauncherApps; private final Context mAppContext; - private final IntSet mPromiseIconIds; private final PackageInstaller mInstaller; private final HashMap 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 @@ public class InstallSessionHelper { for (int i = idsToRemove.size() - 1; i >= 0; --i) { mPromiseIconIds.getArray().removeValue(idsToRemove.get(i)); } + return mPromiseIconIds; } public HashMap getActiveSessions() { @@ -126,7 +129,7 @@ public class InstallSessionHelper { 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 @@ public class InstallSessionHelper { 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 @@ public class InstallSessionHelper { * - 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 @@ public class InstallSessionHelper { && 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 @@ public class InstallSessionHelper { 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 eb3ca7366b..b0b907ab19 100644 --- a/src/com/android/launcher3/pm/InstallSessionTracker.java +++ b/src/com/android/launcher3/pm/InstallSessionTracker.java @@ -24,8 +24,11 @@ import android.content.pm.PackageInstaller.SessionInfo; 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