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
This commit is contained in:
Winson Chung
2024-04-04 05:46:32 +00:00
parent 1ebeb1d1ae
commit bb32b7e0de
13 changed files with 47 additions and 34 deletions
@@ -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);
+2 -2
View File
@@ -447,8 +447,8 @@ public class LauncherModel implements InstallSessionTracker.Callback {
IconCache iconCache = app.getIconCache();
final IntSet removedIds = new IntSet();
HashSet<WorkspaceItemInfo> 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
@@ -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);
@@ -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();
@@ -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<ItemInfo> 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");
}
@@ -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;
}
@@ -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()) {
@@ -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;
@@ -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)
@@ -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));
}
@@ -181,8 +181,8 @@ public abstract class SystemShortcut<T extends ActivityContext> 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);
}
@@ -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<PackageManagerHelper> 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);
}
}
@@ -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;