From bb32b7e0de5d9efbec12bb2680ef5d4d68aadbad Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Thu, 4 Apr 2024 05:46:32 +0000 Subject: [PATCH] Migrate PackageManagerHelper to MainThreadInitializedObject - This is in preparation for other things that can be loaded with PMH initialization and prevents duplicate temporary helpers from loading this many times. - Most calls in PMH can use the app context, but one call requires starting activities/showing toasts so that one needs to take the context and can be made static instead. Bug: 323112914 Test: atest NexusLauncherTests Change-Id: Id11c780955880cf49c022cbf2744c41e1b696355 --- .../src/com/android/quickstep/TaskUtils.java | 2 +- src/com/android/launcher3/LauncherModel.java | 4 ++-- .../launcher3/SecondaryDropTarget.java | 2 +- .../launcher3/dragndrop/AddItemActivity.java | 2 +- .../model/AddWorkspaceItemsTask.java | 12 ++++++----- .../android/launcher3/model/AllAppsList.java | 2 +- .../android/launcher3/model/LoaderTask.java | 5 +++-- .../model/SdCardAvailableReceiver.java | 2 +- .../launcher3/model/ShortcutsChangedTask.java | 2 +- .../launcher3/pm/InstallSessionHelper.java | 4 ++-- .../launcher3/popup/SystemShortcut.java | 4 ++-- .../launcher3/util/PackageManagerHelper.java | 19 ++++++++++++----- .../WidgetRecommendationCategoryProvider.java | 21 ++++++++++--------- 13 files changed, 47 insertions(+), 34 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java index 80a449bf5b..63e536ae0a 100644 --- a/quickstep/src/com/android/quickstep/TaskUtils.java +++ b/quickstep/src/com/android/quickstep/TaskUtils.java @@ -70,7 +70,7 @@ public final class TaskUtils { return ""; } UserHandle user = UserHandle.of(userId); - ApplicationInfo applicationInfo = new PackageManagerHelper(context) + ApplicationInfo applicationInfo = PackageManagerHelper.INSTANCE.get(context) .getApplicationInfo(packageName, user, 0); if (applicationInfo == null) { Log.e(TAG, "Failed to get title for userId=" + userId + ", packageName=" + packageName); diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 7fdfd726f9..9b0e0ec0b9 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -447,8 +447,8 @@ public class LauncherModel implements InstallSessionTracker.Callback { IconCache iconCache = app.getIconCache(); final IntSet removedIds = new IntSet(); HashSet archivedWorkspaceItemsToCacheRefresh = new HashSet<>(); - boolean isAppArchived = new PackageManagerHelper( - mApp.getContext()).isAppArchivedForUser(packageName, user); + boolean isAppArchived = PackageManagerHelper.INSTANCE.get(mApp.getContext()) + .isAppArchivedForUser(packageName, user); synchronized (dataModel) { if (isAppArchived) { // Remove package icon cache entry for archived app in case of a session diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java index 1362586c9e..0a4fb73a86 100644 --- a/src/com/android/launcher3/SecondaryDropTarget.java +++ b/src/com/android/launcher3/SecondaryDropTarget.java @@ -362,7 +362,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList public void onLauncherResume() { // We use MATCH_UNINSTALLED_PACKAGES as the app can be on SD card as well. - if (new PackageManagerHelper(mContext).getApplicationInfo(mPackageName, + if (PackageManagerHelper.INSTANCE.get(mContext).getApplicationInfo(mPackageName, mDragObject.dragInfo.user, PackageManager.MATCH_UNINSTALLED_PACKAGES) == null) { mDragObject.dragSource = mOriginal; mOriginal.onDropCompleted(SecondaryDropTarget.this, mDragObject, true); diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java index 05fdcef461..ec0a222a8a 100644 --- a/src/com/android/launcher3/dragndrop/AddItemActivity.java +++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java @@ -162,7 +162,7 @@ public class AddItemActivity extends BaseActivity finish(); return; } - ApplicationInfo info = new PackageManagerHelper(this) + ApplicationInfo info = PackageManagerHelper.INSTANCE.get(this) .getApplicationInfo(targetApp.packageName, targetApp.user, 0); if (info == null) { finish(); diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java index ce563b7184..3fa6da4f05 100644 --- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java +++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java @@ -15,6 +15,7 @@ */ package com.android.launcher3.model; +import android.content.Context; import android.content.Intent; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; @@ -85,6 +86,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask { final ArrayList addedItemsFinal = new ArrayList<>(); final IntArray addedWorkspaceScreensFinal = new IntArray(); + final Context context = app.getContext(); synchronized (dataModel) { IntArray workspaceScreens = dataModel.collectWorkspaceScreens(); @@ -99,7 +101,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask { } // b/139663018 Short-circuit this logic if the icon is a system app - if (PackageManagerHelper.isSystemApp(app.getContext(), + if (PackageManagerHelper.isSystemApp(context, Objects.requireNonNull(item.getIntent()))) { continue; } @@ -112,7 +114,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask { if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { if (item instanceof WorkspaceItemFactory) { - item = ((WorkspaceItemFactory) item).makeWorkspaceItem(app.getContext()); + item = ((WorkspaceItemFactory) item).makeWorkspaceItem(context); } } if (item != null) { @@ -121,8 +123,8 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask { } InstallSessionHelper packageInstaller = - InstallSessionHelper.INSTANCE.get(app.getContext()); - LauncherApps launcherApps = app.getContext().getSystemService(LauncherApps.class); + InstallSessionHelper.INSTANCE.get(context); + LauncherApps launcherApps = context.getSystemService(LauncherApps.class); for (ItemInfo item : filteredItems) { // Find appropriate space for the item. @@ -135,7 +137,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask { || item instanceof LauncherAppWidgetInfo) { itemInfo = item; } else if (item instanceof WorkspaceItemFactory) { - itemInfo = ((WorkspaceItemFactory) item).makeWorkspaceItem(app.getContext()); + itemInfo = ((WorkspaceItemFactory) item).makeWorkspaceItem(context); } else { throw new RuntimeException("Unexpected info type"); } diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java index a1a05f4071..39c1243bd1 100644 --- a/src/com/android/launcher3/model/AllAppsList.java +++ b/src/com/android/launcher3/model/AllAppsList.java @@ -169,7 +169,7 @@ public class AllAppsList { public AppInfo addPromiseApp( Context context, PackageInstallInfo installInfo, boolean loadIcon) { // only if not yet installed - if (new PackageManagerHelper(context) + if (PackageManagerHelper.INSTANCE.get(context) .isAppInstalled(installInfo.packageName, installInfo.user)) { return null; } diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index a742c752df..77bc32e519 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -138,6 +138,7 @@ public class LoaderTask implements Runnable { private final LauncherApps mLauncherApps; private final UserManager mUserManager; private final UserCache mUserCache; + private final PackageManagerHelper mPmHelper; private final InstallSessionHelper mSessionHelper; private final IconCache mIconCache; @@ -170,6 +171,7 @@ public class LoaderTask implements Runnable { mLauncherApps = mApp.getContext().getSystemService(LauncherApps.class); mUserManager = mApp.getContext().getSystemService(UserManager.class); mUserCache = UserCache.INSTANCE.get(mApp.getContext()); + mPmHelper = PackageManagerHelper.INSTANCE.get(mApp.getContext()); mSessionHelper = InstallSessionHelper.INSTANCE.get(mApp.getContext()); mIconCache = mApp.getIconCache(); mUserManagerState = userManagerState; @@ -407,7 +409,6 @@ public class LoaderTask implements Runnable { @Nullable LoaderMemoryLogger memoryLogger, @Nullable LauncherRestoreEventLogger restoreEventLogger) { final Context context = mApp.getContext(); - final PackageManagerHelper pmHelper = new PackageManagerHelper(context); final boolean isSdCardReady = Utilities.isBootCompleted(); final WidgetInflater widgetInflater = new WidgetInflater(context); @@ -447,7 +448,7 @@ public class LoaderTask implements Runnable { mUserCache, mUserManagerState, mLauncherApps, mPendingPackages, mShortcutKeyToPinnedShortcuts, mApp, mBgDataModel, mWidgetProvidersMap, installingPkgs, isSdCardReady, - widgetInflater, pmHelper, iconRequestInfos, unlockedUsers, + widgetInflater, mPmHelper, iconRequestInfos, unlockedUsers, allDeepShortcuts); while (!mStopped && c.moveToNext()) { diff --git a/src/com/android/launcher3/model/SdCardAvailableReceiver.java b/src/com/android/launcher3/model/SdCardAvailableReceiver.java index 8cfa3aa7d9..529331675b 100644 --- a/src/com/android/launcher3/model/SdCardAvailableReceiver.java +++ b/src/com/android/launcher3/model/SdCardAvailableReceiver.java @@ -52,7 +52,7 @@ public class SdCardAvailableReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { final LauncherApps launcherApps = context.getSystemService(LauncherApps.class); - final PackageManagerHelper pmHelper = new PackageManagerHelper(context); + final PackageManagerHelper pmHelper = PackageManagerHelper.INSTANCE.get(context); for (PackageUserKey puk : mPackages) { UserHandle user = puk.mUser; diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java index 59dd1b1e09..1cb521559f 100644 --- a/src/com/android/launcher3/model/ShortcutsChangedTask.java +++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java @@ -78,7 +78,7 @@ public class ShortcutsChangedTask extends BaseModelUpdateTask { if (!matchingWorkspaceItems.isEmpty()) { if (mShortcuts.isEmpty()) { - PackageManagerHelper packageManagerHelper = new PackageManagerHelper( + PackageManagerHelper packageManagerHelper = PackageManagerHelper.INSTANCE.get( app.getContext()); // Verify that the app is indeed installed. if (!packageManagerHelper.isAppInstalled(mPackageName, mUser) diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java index 4a3318e834..e1d1868ae4 100644 --- a/src/com/android/launcher3/pm/InstallSessionHelper.java +++ b/src/com/android/launcher3/pm/InstallSessionHelper.java @@ -168,7 +168,7 @@ public class InstallSessionHelper { synchronized (mSessionVerifiedMap) { if (!mSessionVerifiedMap.containsKey(pkg)) { boolean hasSystemFlag = DEBUG || mAppContext.getPackageName().equals(pkg) - || new PackageManagerHelper(mAppContext) + || PackageManagerHelper.INSTANCE.get(mAppContext) .getApplicationInfo(pkg, user, ApplicationInfo.FLAG_SYSTEM) != null; mSessionVerifiedMap.put(pkg, hasSystemFlag); } @@ -242,7 +242,7 @@ public class InstallSessionHelper { && sessionInfo.getInstallReason() == PackageManager.INSTALL_REASON_USER && sessionInfo.getAppIcon() != null && !TextUtils.isEmpty(sessionInfo.getAppLabel()) - && !new PackageManagerHelper(mAppContext).isAppInstalled( + && !PackageManagerHelper.INSTANCE.get(mAppContext).isAppInstalled( sessionInfo.getAppPackageName(), getUserHandle(sessionInfo)); } diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java index f56d732aa6..6005573e77 100644 --- a/src/com/android/launcher3/popup/SystemShortcut.java +++ b/src/com/android/launcher3/popup/SystemShortcut.java @@ -181,8 +181,8 @@ public abstract class SystemShortcut extends ItemInfo public void onClick(View view) { dismissTaskMenuView(); Rect sourceBounds = Utilities.getViewBounds(view); - new PackageManagerHelper(view.getContext()).startDetailsActivityForInfo( - mItemInfo, sourceBounds, ActivityOptions.makeBasic().toBundle()); + PackageManagerHelper.startDetailsActivityForInfo(view.getContext(), mItemInfo, + sourceBounds, ActivityOptions.makeBasic().toBundle()); mTarget.getStatsLogManager().logger().withItemInfo(mItemInfo) .log(LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP); } diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java index 608bed7090..3684f569c3 100644 --- a/src/com/android/launcher3/util/PackageManagerHelper.java +++ b/src/com/android/launcher3/util/PackageManagerHelper.java @@ -56,10 +56,14 @@ import java.util.Objects; /** * Utility methods using package manager */ -public class PackageManagerHelper { +public class PackageManagerHelper implements SafeCloseable{ private static final String TAG = "PackageManagerHelper"; + @NonNull + public static final MainThreadInitializedObject INSTANCE = + new MainThreadInitializedObject<>(PackageManagerHelper::new); + @NonNull private final Context mContext; @@ -75,6 +79,9 @@ public class PackageManagerHelper { mLauncherApps = Objects.requireNonNull(context.getSystemService(LauncherApps.class)); } + @Override + public void close() { } + /** * Returns true if the app can possibly be on the SDCard. This is just a workaround and doesn't * guarantee that the app is on SD card. @@ -170,10 +177,11 @@ public class PackageManagerHelper { /** * Starts the details activity for {@code info} */ - public void startDetailsActivityForInfo(ItemInfo info, Rect sourceBounds, Bundle opts) { + public static void startDetailsActivityForInfo(Context context, ItemInfo info, + Rect sourceBounds, Bundle opts) { if (info instanceof ItemInfoWithIcon appInfo && (appInfo.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0) { - mContext.startActivity(ApiWrapper.INSTANCE.get(mContext).getAppMarketActivityIntent( + context.startActivity(ApiWrapper.INSTANCE.get(context).getAppMarketActivityIntent( appInfo.getTargetComponent().getPackageName(), Process.myUserHandle())); return; } @@ -189,9 +197,10 @@ public class PackageManagerHelper { } if (componentName != null) { try { - mLauncherApps.startAppDetailsActivity(componentName, info.user, sourceBounds, opts); + context.getSystemService(LauncherApps.class).startAppDetailsActivity(componentName, + info.user, sourceBounds, opts); } catch (SecurityException | ActivityNotFoundException e) { - Toast.makeText(mContext, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); + Toast.makeText(context, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Unable to launch settings", e); } } diff --git a/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProvider.java b/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProvider.java index c3906a67c8..80bda22058 100644 --- a/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProvider.java +++ b/src/com/android/launcher3/widget/picker/WidgetRecommendationCategoryProvider.java @@ -62,16 +62,17 @@ public class WidgetRecommendationCategoryProvider implements ResourceBasedOverri // via the overridden WidgetRecommendationCategoryProvider resource. Preconditions.assertWorkerThread(); - PackageManagerHelper pmHelper = new PackageManagerHelper(context); - if (item.widgetInfo != null && item.widgetInfo.getComponent() != null) { - String widgetComponentName = item.widgetInfo.getComponent().getClassName(); - ApplicationInfo applicationInfo = pmHelper.getApplicationInfo( - item.widgetInfo.getComponent().getPackageName(), item.widgetInfo.getUser(), - 0 /* flags */); - if (applicationInfo != null) { - int predictionCategory = applicationInfo.category; - return getCategoryFromApplicationCategory(context, predictionCategory, - widgetComponentName); + try (PackageManagerHelper pmHelper = new PackageManagerHelper(context)) { + if (item.widgetInfo != null && item.widgetInfo.getComponent() != null) { + String widgetComponentName = item.widgetInfo.getComponent().getClassName(); + ApplicationInfo applicationInfo = pmHelper.getApplicationInfo( + item.widgetInfo.getComponent().getPackageName(), item.widgetInfo.getUser(), + 0 /* flags */); + if (applicationInfo != null) { + int predictionCategory = applicationInfo.category; + return getCategoryFromApplicationCategory(context, predictionCategory, + widgetComponentName); + } } } return null;