Merge "Requesting ApplicationInfo in cached object" into main

This commit is contained in:
Treehugger Robot
2024-09-28 00:08:58 +00:00
committed by Android (Google) Code Review
15 changed files with 227 additions and 158 deletions
+2 -2
View File
@@ -83,8 +83,8 @@ import androidx.core.graphics.ColorUtils;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.graphics.TintedDrawableSpan;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.CacheableShortcutInfo;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShortcutCachingLogic;
import com.android.launcher3.icons.ThemedIconDrawable;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
@@ -635,7 +635,7 @@ public final class Utilities {
return null;
} else {
ShortcutInfo si = siList.get(0);
mainIcon = ShortcutCachingLogic.getIcon(context, si,
mainIcon = CacheableShortcutInfo.getIcon(context, si,
appState.getInvariantDeviceProfile().fillResIconDpi);
// Only fetch badge if the icon is on workspace
if (info.id != ItemInfo.NO_ID && badge == null) {
@@ -69,7 +69,8 @@ public class PinShortcutRequestActivityInfo extends ShortcutConfigActivityInfo {
public PinShortcutRequestActivityInfo(
ShortcutInfo si, Supplier<PinItemRequest> requestSupplier, Context context) {
super(new ComponentName(si.getPackage(), STUB_COMPONENT_CLASS), si.getUserHandle());
super(new ComponentName(si.getPackage(), STUB_COMPONENT_CLASS),
si.getUserHandle(), context);
mRequestSupplier = requestSupplier;
mInfo = si;
mContext = context;
@@ -0,0 +1,131 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.icons
import android.content.ComponentName
import android.content.Context
import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps
import android.content.pm.PackageInfo
import android.content.pm.ShortcutInfo
import android.graphics.drawable.Drawable
import android.os.UserHandle
import android.text.TextUtils
import android.util.Log
import com.android.launcher3.BuildConfig
import com.android.launcher3.LauncherAppState
import com.android.launcher3.icons.BaseIconFactory.IconOptions
import com.android.launcher3.icons.cache.BaseIconCache
import com.android.launcher3.icons.cache.CachingLogic
import com.android.launcher3.shortcuts.ShortcutKey
import com.android.launcher3.util.ApplicationInfoWrapper
import com.android.launcher3.util.PackageUserKey
import com.android.launcher3.util.Themes
import kotlin.math.max
/** Wrapper over ShortcutInfo to provide extra information related to ShortcutInfo */
class CacheableShortcutInfo(val shortcutInfo: ShortcutInfo, val appInfo: ApplicationInfoWrapper) {
constructor(
info: ShortcutInfo,
ctx: Context,
) : this(info, ApplicationInfoWrapper(ctx, info.getPackage(), info.userHandle))
companion object {
private const val TAG = "CacheableShortcutInfo"
/**
* Similar to [LauncherApps.getShortcutIconDrawable] with additional Launcher specific
* checks
*/
@JvmStatic
fun getIcon(context: Context, shortcutInfo: ShortcutInfo, density: Int): Drawable? {
if (!BuildConfig.WIDGETS_ENABLED) {
return null
}
try {
return context
.getSystemService(LauncherApps::class.java)
.getShortcutIconDrawable(shortcutInfo, density)
} catch (e: Exception) {
Log.e(TAG, "Failed to get shortcut icon", e)
return null
}
}
/**
* Converts the provided list of Shortcuts to CacheableShortcuts by using the application
* info from the provided list of apps
*/
@JvmStatic
fun convertShortcutsToCacheableShortcuts(
shortcuts: List<ShortcutInfo>,
activities: List<LauncherActivityInfo>,
): List<CacheableShortcutInfo> {
// Create a map of package to applicationInfo
val appMap =
activities.associateBy(
{ PackageUserKey(it.componentName.packageName, it.user) },
{ it.applicationInfo },
)
return shortcuts.map {
CacheableShortcutInfo(
it,
ApplicationInfoWrapper(appMap[PackageUserKey(it.getPackage(), it.userHandle)]),
)
}
}
}
}
/** Caching logic for CacheableShortcutInfo. */
object CacheableShortcutCachingLogic : CachingLogic<CacheableShortcutInfo> {
override fun getComponent(info: CacheableShortcutInfo): ComponentName =
ShortcutKey.fromInfo(info.shortcutInfo).componentName
override fun getUser(info: CacheableShortcutInfo): UserHandle = info.shortcutInfo.userHandle
override fun getLabel(info: CacheableShortcutInfo): CharSequence? = info.shortcutInfo.shortLabel
override fun getDescription(info: CacheableShortcutInfo, fallback: CharSequence): CharSequence =
info.shortcutInfo.longLabel.let { if (TextUtils.isEmpty(it)) fallback else it!! }
override fun getLastUpdatedTime(info: CacheableShortcutInfo?, packageInfo: PackageInfo) =
info?.let { max(info.shortcutInfo.lastChangedTimestamp, packageInfo.lastUpdateTime) }
?: packageInfo.lastUpdateTime
override fun addToMemCache() = false
override fun getApplicationInfo(info: CacheableShortcutInfo) = info.appInfo.getInfo()
override fun loadIcon(context: Context, cache: BaseIconCache, info: CacheableShortcutInfo) =
LauncherIcons.obtain(context).use { li ->
CacheableShortcutInfo.getIcon(
context,
info.shortcutInfo,
LauncherAppState.getIDP(context).fillResIconDpi,
)
?.let { d ->
li.createBadgedIconBitmap(
d,
IconOptions().setExtractedColor(Themes.getColorAccent(context)),
)
} ?: BitmapInfo.LOW_RES_INFO
}
}
+21 -12
View File
@@ -65,7 +65,6 @@ import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.PackageUserKey;
@@ -97,7 +96,6 @@ public class IconCache extends BaseIconCache {
private final CachingLogic<ComponentWithLabel> mComponentWithLabelCachingLogic;
private final CachingLogic<LauncherActivityInfo> mLauncherActivityInfoCachingLogic;
private final CachingLogic<ShortcutInfo> mShortcutCachingLogic;
private final LauncherApps mLauncherApps;
private final UserCache mUserManager;
@@ -115,7 +113,6 @@ public class IconCache extends BaseIconCache {
mComponentWithLabelCachingLogic = new CachedObjectCachingLogic(
context, false /* loadIcons */, false /* addToMemCache */);
mLauncherActivityInfoCachingLogic = LauncherActivityCachingLogic.INSTANCE;
mShortcutCachingLogic = new ShortcutCachingLogic();
mLauncherApps = mContext.getSystemService(LauncherApps.class);
mUserManager = UserCache.INSTANCE.get(mContext);
mInstantAppResolver = InstantAppResolver.newInstance(mContext);
@@ -232,7 +229,7 @@ public class IconCache extends BaseIconCache {
}
/**
* Fill in {@param info} with the icon and label for {@param activityInfo}
* Fill in {@code info} with the icon and label for {@code activityInfo}
*/
@SuppressWarnings("NewApi")
public synchronized void getTitleAndIcon(ItemInfoWithIcon info,
@@ -244,28 +241,40 @@ public class IconCache extends BaseIconCache {
}
/**
* Fill in {@param info} with the icon for {@param si}
* Fill in {@code info} with the icon for {@code si}
*/
public void getShortcutIcon(ItemInfoWithIcon info, ShortcutInfo si) {
getShortcutIcon(info, new CacheableShortcutInfo(si, mContext));
}
/**
* Fill in {@code info} with the icon for {@code si}
*/
public void getShortcutIcon(ItemInfoWithIcon info, CacheableShortcutInfo si) {
getShortcutIcon(info, si, mIsUsingFallbackOrNonDefaultIconCheck);
}
/**
* Fill in {@param info} with the icon and label for {@param si}. If the icon is not
* Fill in {@code info} with the icon and label for {@code si}. If the icon is not
* available, and fallback check returns true, it keeps the old icon.
*/
public <T extends ItemInfoWithIcon> void getShortcutIcon(T info, ShortcutInfo si,
public <T extends ItemInfoWithIcon> void getShortcutIcon(T info, CacheableShortcutInfo si,
@NonNull Predicate<T> fallbackIconCheck) {
BitmapInfo bitmapInfo = cacheLocked(ShortcutKey.fromInfo(si).componentName,
si.getUserHandle(), () -> si, mShortcutCachingLogic, LookupFlag.DEFAULT).bitmap;
UserHandle user = CacheableShortcutCachingLogic.INSTANCE.getUser(si);
BitmapInfo bitmapInfo = cacheLocked(
CacheableShortcutCachingLogic.INSTANCE.getComponent(si),
user,
() -> si,
CacheableShortcutCachingLogic.INSTANCE,
LookupFlag.DEFAULT).bitmap;
if (bitmapInfo.isNullOrLowRes()) {
bitmapInfo = getDefaultIcon(si.getUserHandle());
bitmapInfo = getDefaultIcon(user);
}
if (isDefaultIcon(bitmapInfo, si.getUserHandle()) && fallbackIconCheck.test(info)) {
if (isDefaultIcon(bitmapInfo, user) && fallbackIconCheck.test(info)) {
return;
}
info.bitmap = bitmapInfo.withBadgeInfo(getShortcutInfoBadge(si));
info.bitmap = bitmapInfo.withBadgeInfo(getShortcutInfoBadge(si.getShortcutInfo()));
}
/**
@@ -1,117 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.icons;
import static com.android.launcher3.BuildConfig.WIDGETS_ENABLED;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.pm.PackageInfo;
import android.content.pm.ShortcutInfo;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.icons.BaseIconFactory.IconOptions;
import com.android.launcher3.icons.cache.BaseIconCache;
import com.android.launcher3.icons.cache.CachingLogic;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.Themes;
/**
* Caching logic for shortcuts.
*/
public class ShortcutCachingLogic implements CachingLogic<ShortcutInfo> {
private static final String TAG = "ShortcutCachingLogic";
@Override
@NonNull
public ComponentName getComponent(@NonNull ShortcutInfo info) {
return ShortcutKey.fromInfo(info).componentName;
}
@NonNull
@Override
public UserHandle getUser(@NonNull ShortcutInfo info) {
return info.getUserHandle();
}
@NonNull
@Override
public CharSequence getLabel(@NonNull ShortcutInfo info) {
return info.getShortLabel();
}
@Override
@NonNull
public CharSequence getDescription(@NonNull ShortcutInfo object,
@NonNull CharSequence fallback) {
CharSequence label = object.getLongLabel();
return TextUtils.isEmpty(label) ? fallback : label;
}
@NonNull
@Override
public BitmapInfo loadIcon(@NonNull Context context, @NonNull BaseIconCache cache,
@NonNull ShortcutInfo info) {
try (LauncherIcons li = LauncherIcons.obtain(context)) {
Drawable unbadgedDrawable = ShortcutCachingLogic.getIcon(
context, info, LauncherAppState.getIDP(context).fillResIconDpi);
if (unbadgedDrawable == null) return BitmapInfo.LOW_RES_INFO;
return li.createBadgedIconBitmap(unbadgedDrawable,
new IconOptions().setExtractedColor(Themes.getColorAccent(context)));
}
}
@Override
public long getLastUpdatedTime(@Nullable ShortcutInfo shortcutInfo,
@NonNull PackageInfo info) {
if (shortcutInfo == null) {
return info.lastUpdateTime;
}
return Math.max(shortcutInfo.getLastChangedTimestamp(), info.lastUpdateTime);
}
@Override
public boolean addToMemCache() {
return false;
}
/**
* Similar to {@link LauncherApps#getShortcutIconDrawable(ShortcutInfo, int)} with additional
* Launcher specific checks
*/
public static Drawable getIcon(Context context, ShortcutInfo shortcutInfo, int density) {
if (!WIDGETS_ENABLED) {
return null;
}
try {
return context.getSystemService(LauncherApps.class)
.getShortcutIconDrawable(shortcutInfo, density);
} catch (SecurityException | IllegalStateException | NullPointerException e) {
Log.e(TAG, "Failed to get shortcut icon", e);
return null;
}
}
}
@@ -23,6 +23,7 @@ import static com.android.launcher3.Flags.enableSmartspaceRemovalToggle;
import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
import static com.android.launcher3.LauncherPrefs.SHOULD_SHOW_SMARTSPACE;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
import static com.android.launcher3.icons.CacheableShortcutInfo.convertShortcutsToCacheableShortcuts;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
@@ -69,9 +70,10 @@ import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderGridOrganizer;
import com.android.launcher3.folder.FolderNameInfos;
import com.android.launcher3.folder.FolderNameProvider;
import com.android.launcher3.icons.CacheableShortcutCachingLogic;
import com.android.launcher3.icons.CacheableShortcutInfo;
import com.android.launcher3.icons.ComponentWithLabelAndIcon;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.ShortcutCachingLogic;
import com.android.launcher3.icons.cache.CachedObjectCachingLogic;
import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
import com.android.launcher3.icons.cache.LauncherActivityCachingLogic;
@@ -246,7 +248,7 @@ public class LoaderTask implements Runnable {
}
try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
List<ShortcutInfo> allShortcuts = new ArrayList<>();
List<CacheableShortcutInfo> allShortcuts = new ArrayList<>();
loadWorkspace(allShortcuts, "", memoryLogger, restoreEventLogger);
// Sanitize data re-syncs widgets/shortcuts based on the workspace loaded from db.
@@ -304,7 +306,7 @@ public class LoaderTask implements Runnable {
verifyNotStopped();
logASplit("save shortcuts in icon cache");
updateHandler.updateIcons(allShortcuts, new ShortcutCachingLogic(),
updateHandler.updateIcons(allShortcuts, CacheableShortcutCachingLogic.INSTANCE,
mApp.getModel()::onPackageIconsUpdated);
// Take a break
@@ -322,8 +324,10 @@ public class LoaderTask implements Runnable {
verifyNotStopped();
logASplit("save deep shortcuts in icon cache");
updateHandler.updateIcons(allDeepShortcuts,
new ShortcutCachingLogic(), (pkgs, user) -> { });
updateHandler.updateIcons(
convertShortcutsToCacheableShortcuts(allDeepShortcuts, allActivityList),
CacheableShortcutCachingLogic.INSTANCE,
(pkgs, user) -> { });
// Take a break
waitForIdle();
@@ -397,7 +401,7 @@ public class LoaderTask implements Runnable {
}
protected void loadWorkspace(
List<ShortcutInfo> allDeepShortcuts,
List<CacheableShortcutInfo> allDeepShortcuts,
String selection,
LoaderMemoryLogger memoryLogger,
@Nullable LauncherRestoreEventLogger restoreEventLogger
@@ -423,7 +427,7 @@ public class LoaderTask implements Runnable {
}
private void loadWorkspaceImpl(
List<ShortcutInfo> allDeepShortcuts,
List<CacheableShortcutInfo> allDeepShortcuts,
String selection,
@Nullable LoaderMemoryLogger memoryLogger,
@Nullable LauncherRestoreEventLogger restoreEventLogger) {
@@ -24,6 +24,7 @@ import androidx.annotation.NonNull;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel.ModelUpdateTask;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.icons.CacheableShortcutInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
@@ -79,9 +80,9 @@ public class ShortcutsChangedTask implements ModelUpdateTask {
}
if (!matchingWorkspaceItems.isEmpty()) {
ApplicationInfoWrapper infoWrapper =
new ApplicationInfoWrapper(context, mPackageName, mUser);
if (mShortcuts.isEmpty()) {
ApplicationInfoWrapper infoWrapper =
new ApplicationInfoWrapper(context, mPackageName, mUser);
// Verify that the app is indeed installed.
if (!infoWrapper.isInstalled() && !infoWrapper.isArchived()) {
// App is not installed or archived, ignoring package events
@@ -103,7 +104,6 @@ public class ShortcutsChangedTask implements ModelUpdateTask {
if (!fullDetails.isPinned()) {
continue;
}
String sid = fullDetails.getId();
nonPinnedIds.remove(sid);
matchingWorkspaceItems
@@ -111,7 +111,8 @@ public class ShortcutsChangedTask implements ModelUpdateTask {
.filter(itemInfo -> sid.equals(itemInfo.getDeepShortcutId()))
.forEach(workspaceItemInfo -> {
workspaceItemInfo.updateFromDeepShortcutInfo(fullDetails, context);
app.getIconCache().getShortcutIcon(workspaceItemInfo, fullDetails);
app.getIconCache().getShortcutIcon(workspaceItemInfo,
new CacheableShortcutInfo(fullDetails, infoWrapper));
updatedWorkspaceItemInfos.add(workspaceItemInfo);
});
}
@@ -32,6 +32,7 @@ import com.android.launcher3.LauncherAppState
import com.android.launcher3.LauncherSettings.Favorites
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError
import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.icons.CacheableShortcutInfo
import com.android.launcher3.logging.FileLog
import com.android.launcher3.model.data.AppInfo
import com.android.launcher3.model.data.AppPairInfo
@@ -76,7 +77,7 @@ class WorkspaceItemProcessor(
private val pmHelper: PackageManagerHelper,
private val iconRequestInfos: MutableList<IconRequestInfo<WorkspaceItemInfo>>,
private val unlockedUsers: LongSparseArray<Boolean>,
private val allDeepShortcuts: MutableList<ShortcutInfo>,
private val allDeepShortcuts: MutableList<CacheableShortcutInfo>,
) {
private val isSafeMode = app.isSafeModeEnabled
@@ -278,13 +279,14 @@ class WorkspaceItemProcessor(
info = WorkspaceItemInfo(pinnedShortcut, app.context)
// If the pinned deep shortcut is no longer published,
// use the last saved icon instead of the default.
iconCache.getShortcutIcon(info, pinnedShortcut, c::loadIcon)
val csi = CacheableShortcutInfo(pinnedShortcut, appInfoWrapper)
iconCache.getShortcutIcon(info, csi, c::loadIcon)
if (appInfoWrapper.isSuspended()) {
info.runtimeStatusFlags =
info.runtimeStatusFlags or ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED
}
intent = info.getIntent()
allDeepShortcuts.add(pinnedShortcut)
allDeepShortcuts.add(csi)
} else {
// Create a shortcut info in disabled mode for now.
info = c.loadSimpleWorkspaceItem()
@@ -32,7 +32,8 @@ import android.os.SystemClock;
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.icons.ShortcutCachingLogic;
import com.android.launcher3.icons.CacheableShortcutCachingLogic;
import com.android.launcher3.icons.CacheableShortcutInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
public class PinRequestHelper {
@@ -78,7 +79,8 @@ public class PinRequestHelper {
// Apply the unbadged icon synchronously using the caching logic directly and
// fetch the actual icon asynchronously.
LauncherAppState app = LauncherAppState.getInstance(context);
info.bitmap = new ShortcutCachingLogic().loadIcon(context, app.getIconCache(), si);
info.bitmap = CacheableShortcutCachingLogic.INSTANCE.loadIcon(
context, app.getIconCache(), new CacheableShortcutInfo(si, context));
app.getModel().updateAndBindWorkspaceItem(info, si);
return info;
} else {
@@ -26,6 +26,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
@@ -43,6 +44,7 @@ import com.android.launcher3.R;
import com.android.launcher3.icons.ComponentWithLabelAndIcon;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.ApplicationInfoWrapper;
import com.android.launcher3.util.PackageUserKey;
import java.util.ArrayList;
@@ -58,10 +60,20 @@ public abstract class ShortcutConfigActivityInfo implements ComponentWithLabelAn
private final ComponentName mCn;
private final UserHandle mUser;
private final ApplicationInfoWrapper mInfoWrapper;
protected ShortcutConfigActivityInfo(ComponentName cn, UserHandle user) {
protected ShortcutConfigActivityInfo(
ComponentName cn, UserHandle user, ApplicationInfoWrapper infoWrapper) {
mCn = cn;
mUser = user;
mInfoWrapper = infoWrapper;
}
protected ShortcutConfigActivityInfo(
ComponentName cn, UserHandle user, Context context) {
mCn = cn;
mUser = user;
mInfoWrapper = new ApplicationInfoWrapper(context, cn.getPackageName(), user);
}
@Override
@@ -89,6 +101,12 @@ public abstract class ShortcutConfigActivityInfo implements ComponentWithLabelAn
return null;
}
@Nullable
@Override
public ApplicationInfo getApplicationInfo() {
return mInfoWrapper.getInfo();
}
public boolean startConfigActivity(Activity activity, int requestCode) {
Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT)
.setComponent(getComponent());
@@ -120,7 +138,8 @@ public abstract class ShortcutConfigActivityInfo implements ComponentWithLabelAn
private final LauncherActivityInfo mInfo;
public ShortcutConfigActivityInfoVO(LauncherActivityInfo info) {
super(info.getComponentName(), info.getUser());
super(info.getComponentName(), info.getUser(),
new ApplicationInfoWrapper(info.getApplicationInfo()));
mInfo = info;
}
@@ -27,11 +27,13 @@ import android.os.UserHandle;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.icons.CacheableShortcutInfo;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.util.ApplicationInfoWrapper;
import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
@@ -113,6 +115,8 @@ public class PopupPopulator {
final ComponentName activity = originalInfo.getTargetComponent();
final UserHandle user = originalInfo.user;
return () -> {
ApplicationInfoWrapper infoWrapper =
new ApplicationInfoWrapper(context, activity.getPackageName(), user);
List<ShortcutInfo> shortcuts = new ShortcutRequest(context, user)
.withContainer(activity)
.query(ShortcutRequest.PUBLISHED);
@@ -121,7 +125,7 @@ public class PopupPopulator {
for (int i = 0; i < shortcuts.size() && i < shortcutViews.size(); i++) {
final ShortcutInfo shortcut = shortcuts.get(i);
final WorkspaceItemInfo si = new WorkspaceItemInfo(shortcut, context);
cache.getShortcutIcon(si, shortcut);
cache.getShortcutIcon(si, new CacheableShortcutInfo(shortcut, infoWrapper));
si.rank = i;
si.container = CONTAINER_SHORTCUTS;
@@ -3,6 +3,7 @@ package com.android.launcher3.widget;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.graphics.Rect;
@@ -10,6 +11,8 @@ import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.UserHandle;
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
@@ -225,4 +228,10 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo
public Drawable getFullResIcon(IconCache cache) {
return cache.getFullResIcon(getActivityInfo());
}
@Nullable
@Override
public ApplicationInfo getApplicationInfo() {
return getActivityInfo().applicationInfo;
}
}
@@ -40,6 +40,7 @@ import com.android.launcher3.backuprestore.LauncherRestoreEventLogger
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError.Companion.MISSING_INFO
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError.Companion.MISSING_WIDGET_PROVIDER
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError.Companion.PROFILE_DELETED
import com.android.launcher3.icons.CacheableShortcutInfo
import com.android.launcher3.model.data.FolderInfo
import com.android.launcher3.model.data.IconRequestInfo
import com.android.launcher3.model.data.ItemInfo
@@ -97,7 +98,7 @@ class WorkspaceItemProcessorTest {
private var mUnlockedUsersArray: LongSparseArray<Boolean> = LongSparseArray()
private var mKeyToPinnedShortcutsMap: MutableMap<ShortcutKey, ShortcutInfo> = mutableMapOf()
private var mInstallingPkgs: HashMap<PackageUserKey, PackageInstaller.SessionInfo> = hashMapOf()
private var mAllDeepShortcuts: MutableList<ShortcutInfo> = mutableListOf()
private var mAllDeepShortcuts: MutableList<CacheableShortcutInfo> = mutableListOf()
private var mWidgetProvidersMap: MutableMap<ComponentKey, AppWidgetProviderInfo?> =
mutableMapOf()
private var mPendingPackages: MutableSet<PackageUserKey> = mutableSetOf()
@@ -194,7 +195,7 @@ class WorkspaceItemProcessorTest {
pendingPackages: MutableSet<PackageUserKey> = mPendingPackages,
unlockedUsers: LongSparseArray<Boolean> = mUnlockedUsersArray,
installingPkgs: HashMap<PackageUserKey, PackageInstaller.SessionInfo> = mInstallingPkgs,
allDeepShortcuts: MutableList<ShortcutInfo> = mAllDeepShortcuts,
allDeepShortcuts: MutableList<CacheableShortcutInfo> = mAllDeepShortcuts,
) =
WorkspaceItemProcessor(
c = cursor,
@@ -387,7 +388,8 @@ class WorkspaceItemProcessorTest {
.that(mockCursor.restoreFlag)
.isEqualTo(0)
assertThat(mIconRequestInfos).isEmpty()
assertThat(mAllDeepShortcuts).containsExactly(expectedShortcutInfo)
assertThat(mAllDeepShortcuts.size).isEqualTo(1)
assertThat(mAllDeepShortcuts[0].shortcutInfo).isEqualTo(expectedShortcutInfo)
verify(mockCursor).markRestored()
verify(mockCursor).checkAndAddItem(any(), any(), anyOrNull())
}
@@ -452,7 +454,8 @@ class WorkspaceItemProcessorTest {
.that(mockCursor.restoreFlag)
.isEqualTo(0)
assertThat(mIconRequestInfos).isEmpty()
assertThat(mAllDeepShortcuts).containsExactly(expectedShortcutInfo)
assertThat(mAllDeepShortcuts.size).isEqualTo(1)
assertThat(mAllDeepShortcuts[0].shortcutInfo).isEqualTo(expectedShortcutInfo)
verify(mockCursor).markRestored()
verify(mockCursor).checkAndAddItem(any(), any(), anyOrNull())
}
@@ -296,7 +296,7 @@ public final class WidgetsTableUtilsTest {
private final class TestShortcutConfigActivityInfo extends ShortcutConfigActivityInfo {
TestShortcutConfigActivityInfo(ComponentName componentName, UserHandle user) {
super(componentName, user);
super(componentName, user, mContext);
}
@Override
@@ -35,6 +35,7 @@ import com.android.launcher3.LauncherSettings.Favorites
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP
import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
import com.android.launcher3.icons.CacheableShortcutInfo
import com.android.launcher3.model.data.IconRequestInfo
import com.android.launcher3.model.data.LauncherAppWidgetInfo
import com.android.launcher3.model.data.LauncherAppWidgetInfo.FLAG_RESTORE_STARTED
@@ -84,7 +85,7 @@ class WorkspaceItemProcessorExtraTest {
private var mUnlockedUsersArray: LongSparseArray<Boolean> = LongSparseArray()
private var mKeyToPinnedShortcutsMap: MutableMap<ShortcutKey, ShortcutInfo> = mutableMapOf()
private var mInstallingPkgs: HashMap<PackageUserKey, PackageInstaller.SessionInfo> = hashMapOf()
private var mAllDeepShortcuts: MutableList<ShortcutInfo> = mutableListOf()
private var mAllDeepShortcuts: MutableList<CacheableShortcutInfo> = mutableListOf()
private var mWidgetProvidersMap: MutableMap<ComponentKey, AppWidgetProviderInfo?> =
mutableMapOf()
private var mPendingPackages: MutableSet<PackageUserKey> = mutableSetOf()
@@ -290,7 +291,7 @@ class WorkspaceItemProcessorExtraTest {
pendingPackages: MutableSet<PackageUserKey> = mPendingPackages,
unlockedUsers: LongSparseArray<Boolean> = mUnlockedUsersArray,
installingPkgs: HashMap<PackageUserKey, PackageInstaller.SessionInfo> = mInstallingPkgs,
allDeepShortcuts: MutableList<ShortcutInfo> = mAllDeepShortcuts,
allDeepShortcuts: MutableList<CacheableShortcutInfo> = mAllDeepShortcuts,
) =
WorkspaceItemProcessor(
c = cursor,