Various icon cache fixes
> Multiple instances of LauncherIcon created when LauncherIcons refers IconCache which in turn creates new LauncherIcons > Widget icons are never cached as they were using low res icons > Shortcut drag icons are not loaded synchronously when using PinItemRequest flow > Wrong lastUpdatedTime is used in iconCache for shortcuts > IconUpdateHandler does not ignore managedUser promise icons Change-Id: Ie7eed68a30fad11d1861b6c70c380953a15ae1cf
This commit is contained in:
parent
a0912d502a
commit
18204e4eea
|
@ -22,7 +22,7 @@ import android.os.UserHandle;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.icons.ComponentWithLabel;
|
||||
import com.android.launcher3.icons.ComponentWithLabelAndIcon;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
import com.android.launcher3.widget.WidgetListRowEntry;
|
||||
|
||||
|
@ -59,7 +59,7 @@ public class WidgetsModel {
|
|||
* @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise
|
||||
* only widgets and shortcuts associated with the package/user are.
|
||||
*/
|
||||
public List<ComponentWithLabel> update(LauncherAppState app,
|
||||
public List<ComponentWithLabelAndIcon> update(LauncherAppState app,
|
||||
@Nullable PackageUserKey packageUser) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
|
@ -350,6 +350,17 @@ public class BaseIconFactory implements AutoCloseable {
|
|||
iconDpi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Badges the provided source with the badge info
|
||||
*/
|
||||
public BitmapInfo badgeBitmap(Bitmap source, BitmapInfo badgeInfo) {
|
||||
Bitmap icon = BitmapRenderer.createHardwareBitmap(mIconBitmapSize, mIconBitmapSize, (c) -> {
|
||||
getShadowGenerator().recreateIcon(source, c);
|
||||
badgeWithDrawable(c, new FixedSizeBitmapDrawable(badgeInfo.icon));
|
||||
});
|
||||
return BitmapInfo.of(icon, badgeInfo.color);
|
||||
}
|
||||
|
||||
private int extractColor(Bitmap bitmap) {
|
||||
return mDisableColorExtractor ? 0 : mColorExtractor.findDominantColorByHue(bitmap);
|
||||
}
|
||||
|
|
|
@ -281,7 +281,8 @@ public abstract class BaseIconCache {
|
|||
|
||||
ContentValues values = newContentValues(entry.bitmap, entry.title.toString(),
|
||||
componentName.getPackageName(), cachingLogic.getKeywords(object, mLocaleList));
|
||||
addIconToDB(values, componentName, info, userSerial);
|
||||
addIconToDB(values, componentName, info, userSerial,
|
||||
cachingLogic.getLastUpdatedTime(object, info));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -289,10 +290,10 @@ public abstract class BaseIconCache {
|
|||
* @param values {@link ContentValues} containing icon & title
|
||||
*/
|
||||
private void addIconToDB(ContentValues values, ComponentName key,
|
||||
PackageInfo info, long userSerial) {
|
||||
PackageInfo info, long userSerial, long lastUpdateTime) {
|
||||
values.put(IconDB.COLUMN_COMPONENT, key.flattenToString());
|
||||
values.put(IconDB.COLUMN_USER, userSerial);
|
||||
values.put(IconDB.COLUMN_LAST_UPDATED, info.lastUpdateTime);
|
||||
values.put(IconDB.COLUMN_LAST_UPDATED, lastUpdateTime);
|
||||
values.put(IconDB.COLUMN_VERSION, info.versionCode);
|
||||
mIconDb.insertOrReplace(values);
|
||||
}
|
||||
|
@ -362,7 +363,8 @@ public abstract class BaseIconCache {
|
|||
}
|
||||
if (object != null) {
|
||||
entry.title = cachingLogic.getLabel(object);
|
||||
entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
|
||||
entry.contentDescription = mPackageManager.getUserBadgedLabel(
|
||||
cachingLogic.getDescription(object, entry.title), user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -449,7 +451,8 @@ public abstract class BaseIconCache {
|
|||
// package updates.
|
||||
ContentValues values = newContentValues(
|
||||
iconInfo, entry.title.toString(), packageName, null);
|
||||
addIconToDB(values, cacheKey.componentName, info, getSerialNumberForUser(user));
|
||||
addIconToDB(values, cacheKey.componentName, info, getSerialNumberForUser(user),
|
||||
info.lastUpdateTime);
|
||||
|
||||
} catch (NameNotFoundException e) {
|
||||
if (DEBUG) Log.d(TAG, "Application not installed " + packageName);
|
||||
|
|
|
@ -34,6 +34,10 @@ public interface CachingLogic<T> {
|
|||
|
||||
CharSequence getLabel(T object);
|
||||
|
||||
default CharSequence getDescription(T object, CharSequence fallback) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
BitmapInfo loadIcon(Context context, T object);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.database.sqlite.SQLiteException;
|
|||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
|
@ -61,7 +62,7 @@ public class IconCacheUpdateHandler {
|
|||
private final HashMap<String, PackageInfo> mPkgInfoMap;
|
||||
private final BaseIconCache mIconCache;
|
||||
|
||||
private final HashMap<UserHandle, Set<String>> mPackagesToIgnore = new HashMap<>();
|
||||
private final ArrayMap<UserHandle, Set<String>> mPackagesToIgnore = new ArrayMap<>();
|
||||
|
||||
private final SparseBooleanArray mItemsToDelete = new SparseBooleanArray();
|
||||
private boolean mFilterMode = MODE_SET_INVALID_ITEMS;
|
||||
|
@ -77,8 +78,16 @@ public class IconCacheUpdateHandler {
|
|||
createPackageInfoMap();
|
||||
}
|
||||
|
||||
public void setPackagesToIgnore(UserHandle userHandle, Set<String> packages) {
|
||||
mPackagesToIgnore.put(userHandle, packages);
|
||||
/**
|
||||
* Sets a package to ignore for processing
|
||||
*/
|
||||
public void addPackagesToIgnore(UserHandle userHandle, String packageName) {
|
||||
Set<String> packages = mPackagesToIgnore.get(userHandle);
|
||||
if (packages == null) {
|
||||
packages = new HashSet<>();
|
||||
mPackagesToIgnore.put(userHandle, packages);
|
||||
}
|
||||
packages.add(packageName);
|
||||
}
|
||||
|
||||
private void createPackageInfoMap() {
|
||||
|
@ -181,6 +190,7 @@ public class IconCacheUpdateHandler {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (app == null) {
|
||||
if (mFilterMode == MODE_SET_INVALID_ITEMS) {
|
||||
mIconCache.remove(component, user);
|
||||
|
@ -263,6 +273,7 @@ public class IconCacheUpdateHandler {
|
|||
T app = mAppsToUpdate.pop();
|
||||
String pkg = mCachingLogic.getComponent(app).getPackageName();
|
||||
PackageInfo info = mPkgInfoMap.get(pkg);
|
||||
|
||||
mIconCache.addIconToDBAndMemCache(
|
||||
app, mCachingLogic, info, mUserSerial, true /*replace existing*/);
|
||||
mUpdatedPackages.add(pkg);
|
||||
|
|
|
@ -43,7 +43,6 @@ import com.android.launcher3.LauncherAppState;
|
|||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.allapps.AllAppsStore;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.util.InstantAppResolver;
|
||||
|
@ -170,14 +169,7 @@ public class DynamicItemCache {
|
|||
List<ShortcutInfo> details = shortcutKey.buildRequest(mContext).query(ShortcutRequest.ALL);
|
||||
if (!details.isEmpty()) {
|
||||
WorkspaceItemInfo si = new WorkspaceItemInfo(details.get(0), mContext);
|
||||
try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
|
||||
si.bitmap = li.createShortcutIcon(details.get(0), true /* badged */, null);
|
||||
} catch (Exception e) {
|
||||
if (DEBUG) {
|
||||
Log.e(TAG, "Error loading shortcut icon for " + shortcutKey.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
mIconCache.getShortcutIcon(si, details.get(0));
|
||||
return si;
|
||||
}
|
||||
if (DEBUG) {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package com.android.launcher3;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
import static com.android.launcher3.util.ShortcutUtil.fetchAndUpdateShortcutIconAsync;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
|
@ -44,7 +43,6 @@ import android.util.Pair;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.icons.BitmapInfo;
|
||||
import com.android.launcher3.icons.GraphicsUtils;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
|
@ -61,7 +59,6 @@ import org.json.JSONStringer;
|
|||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -491,13 +488,8 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
|||
return Pair.create(si, null);
|
||||
} else if (shortcutInfo != null) {
|
||||
WorkspaceItemInfo itemInfo = new WorkspaceItemInfo(shortcutInfo, mContext);
|
||||
if (FeatureFlags.ENABLE_DEEP_SHORTCUT_ICON_CACHE.get()) {
|
||||
fetchAndUpdateShortcutIconAsync(mContext, itemInfo, shortcutInfo, true);
|
||||
} else {
|
||||
LauncherIcons li = LauncherIcons.obtain(mContext);
|
||||
itemInfo.bitmap = li.createShortcutIcon(shortcutInfo);
|
||||
li.recycle();
|
||||
}
|
||||
LauncherAppState.getInstance(mContext).getIconCache().getShortcutIcon(
|
||||
itemInfo, shortcutInfo);
|
||||
return Pair.create(itemInfo, shortcutInfo);
|
||||
} else if (providerInfo != null) {
|
||||
LauncherAppWidgetProviderInfo info = LauncherAppWidgetProviderInfo
|
||||
|
|
|
@ -7,10 +7,12 @@ import android.content.Context;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Parcel;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import com.android.launcher3.icons.ComponentWithLabel;
|
||||
import com.android.launcher3.icons.ComponentWithLabelAndIcon;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
|
||||
/**
|
||||
* This class is a thin wrapper around the framework AppWidgetProviderInfo class. This class affords
|
||||
|
@ -19,7 +21,7 @@ import com.android.launcher3.icons.ComponentWithLabel;
|
|||
* as opposed to a widget instance, and so should not be confused with {@link LauncherAppWidgetInfo}
|
||||
*/
|
||||
public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo
|
||||
implements ComponentWithLabel {
|
||||
implements ComponentWithLabelAndIcon {
|
||||
|
||||
public static final String CLS_CUSTOM_WIDGET_PREFIX = "#custom-widget-";
|
||||
|
||||
|
@ -111,4 +113,9 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo
|
|||
public final UserHandle getUser() {
|
||||
return getProfile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getFullResIcon(IconCache cache) {
|
||||
return cache.getFullResIcon(provider.getPackageName(), icon);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ import androidx.annotation.WorkerThread;
|
|||
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.logging.FileLog;
|
||||
import com.android.launcher3.model.AddWorkspaceItemsTask;
|
||||
import com.android.launcher3.model.AllAppsList;
|
||||
|
@ -573,9 +572,7 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
|
|||
public void updateAndBindWorkspaceItem(WorkspaceItemInfo si, ShortcutInfo info) {
|
||||
updateAndBindWorkspaceItem(() -> {
|
||||
si.updateFromDeepShortcutInfo(info, mApp.getContext());
|
||||
LauncherIcons li = LauncherIcons.obtain(mApp.getContext());
|
||||
si.bitmap = li.createShortcutIcon(info);
|
||||
li.recycle();
|
||||
mApp.getIconCache().getShortcutIcon(si, info);
|
||||
return si;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -584,9 +584,8 @@ public final class Utilities {
|
|||
return new FixedSizeEmptyDrawable(iconSize);
|
||||
}
|
||||
ShortcutInfo si = (ShortcutInfo) obj;
|
||||
LauncherIcons li = LauncherIcons.obtain(appState.getContext());
|
||||
Bitmap badge = li.getShortcutInfoBadge(si, appState.getIconCache()).bitmap.icon;
|
||||
li.recycle();
|
||||
Bitmap badge = LauncherAppState.getInstance(appState.getContext())
|
||||
.getIconCache().getShortcutInfoBadge(si).icon;
|
||||
float badgeSize = LauncherIcons.getBadgeSizeForIconSize(iconSize);
|
||||
float insetFraction = (iconSize - badgeSize) / iconSize;
|
||||
return new InsetDrawable(new FastBitmapDrawable(badge),
|
||||
|
|
|
@ -31,7 +31,7 @@ public interface ComponentWithLabel {
|
|||
CharSequence getLabel(PackageManager pm);
|
||||
|
||||
|
||||
class ComponentCachingLogic implements CachingLogic<ComponentWithLabel> {
|
||||
class ComponentCachingLogic<T extends ComponentWithLabel> implements CachingLogic<T> {
|
||||
|
||||
private final PackageManager mPackageManager;
|
||||
private final boolean mAddToMemCache;
|
||||
|
@ -42,22 +42,22 @@ public interface ComponentWithLabel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ComponentName getComponent(ComponentWithLabel object) {
|
||||
public ComponentName getComponent(T object) {
|
||||
return object.getComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserHandle getUser(ComponentWithLabel object) {
|
||||
public UserHandle getUser(T object) {
|
||||
return object.getUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getLabel(ComponentWithLabel object) {
|
||||
public CharSequence getLabel(T object) {
|
||||
return object.getLabel(mPackageManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BitmapInfo loadIcon(Context context, ComponentWithLabel object) {
|
||||
public BitmapInfo loadIcon(Context context, T object) {
|
||||
return BitmapInfo.LOW_RES_INFO;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
|
||||
/**
|
||||
* Extension of ComponentWithLabel to also support loading icons
|
||||
*/
|
||||
public interface ComponentWithLabelAndIcon extends ComponentWithLabel {
|
||||
|
||||
/**
|
||||
* Provide an icon for this object
|
||||
*/
|
||||
Drawable getFullResIcon(IconCache cache);
|
||||
|
||||
class ComponentWithIconCachingLogic extends ComponentCachingLogic<ComponentWithLabelAndIcon> {
|
||||
|
||||
public ComponentWithIconCachingLogic(Context context, boolean addToMemCache) {
|
||||
super(context, addToMemCache);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public BitmapInfo loadIcon(Context context, ComponentWithLabelAndIcon object) {
|
||||
Drawable d = object.getFullResIcon(LauncherAppState.getInstance(context)
|
||||
.getIconCache());
|
||||
if (d == null) {
|
||||
return super.loadIcon(context, object);
|
||||
}
|
||||
try (LauncherIcons li = LauncherIcons.obtain(context)) {
|
||||
return li.createBadgedIconBitmap(d, object.getUser(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ package com.android.launcher3.icons;
|
|||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
|
@ -56,6 +57,7 @@ import com.android.launcher3.util.InstantAppResolver;
|
|||
import com.android.launcher3.util.PackageUserKey;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
|
@ -65,6 +67,9 @@ public class IconCache extends BaseIconCache {
|
|||
|
||||
private static final String TAG = "Launcher.IconCache";
|
||||
|
||||
private final Predicate<ItemInfoWithIcon> mIsUsingFallbackIconCheck = w -> w.bitmap != null
|
||||
&& w.bitmap.isNullOrLowRes() && !isDefaultIcon(w.bitmap, w.user);
|
||||
|
||||
private final CachingLogic<ComponentWithLabel> mComponentWithLabelCachingLogic;
|
||||
private final CachingLogic<LauncherActivityInfo> mLauncherActivityInfoCachingLogic;
|
||||
private final CachingLogic<ShortcutInfo> mShortcutCachingLogic;
|
||||
|
@ -179,6 +184,77 @@ public class IconCache extends BaseIconCache {
|
|||
getTitleAndIcon(info, () -> activityInfo, false, useLowResIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in {@param info} with the icon for {@param si}
|
||||
*/
|
||||
public void getShortcutIcon(ItemInfoWithIcon info, ShortcutInfo si) {
|
||||
getShortcutIcon(info, si, true, mIsUsingFallbackIconCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in {@param info} with an unbadged icon for {@param si}
|
||||
*/
|
||||
public void getUnbadgedShortcutIcon(ItemInfoWithIcon info, ShortcutInfo si) {
|
||||
getShortcutIcon(info, si, false, mIsUsingFallbackIconCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in {@param info} with the icon and label for {@param 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,
|
||||
@NonNull Predicate<T> fallbackIconCheck) {
|
||||
getShortcutIcon(info, si, true /* use badged */, fallbackIconCheck);
|
||||
}
|
||||
|
||||
private synchronized <T extends ItemInfoWithIcon> void getShortcutIcon(T info, ShortcutInfo si,
|
||||
boolean useBadged, @NonNull Predicate<T> fallbackIconCheck) {
|
||||
BitmapInfo bitmapInfo;
|
||||
if (FeatureFlags.ENABLE_DEEP_SHORTCUT_ICON_CACHE.get()) {
|
||||
bitmapInfo = cacheLocked(ShortcutKey.fromInfo(si).componentName, si.getUserHandle(),
|
||||
() -> si, mShortcutCachingLogic, false, false).bitmap;
|
||||
} else {
|
||||
// If caching is disabled, load the full icon
|
||||
bitmapInfo = mShortcutCachingLogic.loadIcon(mContext, si);
|
||||
}
|
||||
if (bitmapInfo.isNullOrLowRes()) {
|
||||
bitmapInfo = getDefaultIcon(si.getUserHandle());
|
||||
}
|
||||
|
||||
if (isDefaultIcon(bitmapInfo, si.getUserHandle()) && fallbackIconCheck.test(info)) {
|
||||
return;
|
||||
}
|
||||
info.bitmap = bitmapInfo;
|
||||
if (useBadged) {
|
||||
BitmapInfo badgeInfo = getShortcutInfoBadge(si);
|
||||
try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
|
||||
info.bitmap = li.badgeBitmap(info.bitmap.icon, badgeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the badging info for the shortcut
|
||||
*/
|
||||
public BitmapInfo getShortcutInfoBadge(ShortcutInfo shortcutInfo) {
|
||||
ComponentName cn = shortcutInfo.getActivity();
|
||||
if (cn != null) {
|
||||
// Get the app info for the source activity.
|
||||
AppInfo appInfo = new AppInfo();
|
||||
appInfo.user = shortcutInfo.getUserHandle();
|
||||
appInfo.componentName = cn;
|
||||
appInfo.intent = new Intent(Intent.ACTION_MAIN)
|
||||
.addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
.setComponent(cn);
|
||||
getTitleAndIcon(appInfo, false);
|
||||
return appInfo.bitmap;
|
||||
} else {
|
||||
PackageItemInfo pkgInfo = new PackageItemInfo(shortcutInfo.getPackage());
|
||||
getTitleAndIconForApp(pkgInfo, false);
|
||||
return pkgInfo.bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in info with the icon and label for deep shortcut.
|
||||
*/
|
||||
|
|
|
@ -16,28 +16,11 @@
|
|||
|
||||
package com.android.launcher3.icons;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Process;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.AppInfo;
|
||||
import com.android.launcher3.FastBitmapDrawable;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.ItemInfoWithIcon;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.graphics.IconShape;
|
||||
import com.android.launcher3.model.PackageItemInfo;
|
||||
import com.android.launcher3.util.Themes;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Wrapper class to provide access to {@link BaseIconFactory} and also to provide pool of this class
|
||||
|
@ -111,114 +94,4 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable {
|
|||
public void close() {
|
||||
recycle();
|
||||
}
|
||||
|
||||
// below methods should also migrate to BaseIconFactory
|
||||
public BitmapInfo createShortcutIcon(ShortcutInfo shortcutInfo) {
|
||||
return createShortcutIcon(shortcutInfo, true /* badged */);
|
||||
}
|
||||
|
||||
public BitmapInfo createShortcutIcon(ShortcutInfo shortcutInfo, boolean badged) {
|
||||
return createShortcutIcon(shortcutInfo, badged, null);
|
||||
}
|
||||
|
||||
public BitmapInfo createShortcutIcon(ShortcutInfo shortcutInfo, boolean badged,
|
||||
@Nullable Supplier<ItemInfoWithIcon> fallbackIconProvider) {
|
||||
if (FeatureFlags.ENABLE_DEEP_SHORTCUT_ICON_CACHE.get()) {
|
||||
return createShortcutIconCached(shortcutInfo, badged, true, fallbackIconProvider);
|
||||
} else {
|
||||
return createShortcutIconLegacy(shortcutInfo, badged, fallbackIconProvider);
|
||||
}
|
||||
}
|
||||
|
||||
public BitmapInfo createShortcutIconLegacy(ShortcutInfo shortcutInfo, boolean badged,
|
||||
@Nullable Supplier<ItemInfoWithIcon> fallbackIconProvider) {
|
||||
Drawable unbadgedDrawable = ShortcutCachingLogic.getIcon(
|
||||
mContext, shortcutInfo, mFillResIconDpi);
|
||||
IconCache cache = LauncherAppState.getInstance(mContext).getIconCache();
|
||||
final Bitmap unbadgedBitmap;
|
||||
if (unbadgedDrawable != null) {
|
||||
unbadgedBitmap = createScaledBitmapWithoutShadow(unbadgedDrawable, 0);
|
||||
} else {
|
||||
if (fallbackIconProvider != null) {
|
||||
// Fallback icons are already badged and with appropriate shadow
|
||||
ItemInfoWithIcon fullIcon = fallbackIconProvider.get();
|
||||
if (fullIcon != null && fullIcon.bitmap != null) {
|
||||
return fullIcon.bitmap;
|
||||
}
|
||||
}
|
||||
unbadgedBitmap = cache.getDefaultIcon(Process.myUserHandle()).icon;
|
||||
}
|
||||
|
||||
if (!badged) {
|
||||
return BitmapInfo.of(unbadgedBitmap, Themes.getColorAccent(mContext));
|
||||
}
|
||||
|
||||
final Bitmap unbadgedfinal = unbadgedBitmap;
|
||||
final ItemInfoWithIcon badge = getShortcutInfoBadge(shortcutInfo, cache);
|
||||
|
||||
Bitmap icon = BitmapRenderer.createHardwareBitmap(mIconBitmapSize, mIconBitmapSize, (c) -> {
|
||||
getShadowGenerator().recreateIcon(unbadgedfinal, c);
|
||||
badgeWithDrawable(c, new FastBitmapDrawable(badge.bitmap));
|
||||
});
|
||||
return BitmapInfo.of(icon, badge.bitmap.color);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public BitmapInfo createShortcutIconCached(ShortcutInfo shortcutInfo, boolean badged,
|
||||
boolean useCache, @Nullable Supplier<ItemInfoWithIcon> fallbackIconProvider) {
|
||||
IconCache cache = LauncherAppState.getInstance(mContext).getIconCache();
|
||||
final BitmapInfo bitmapInfo;
|
||||
if (useCache) {
|
||||
bitmapInfo = cache.getDeepShortcutTitleAndIcon(shortcutInfo).bitmap;
|
||||
} else {
|
||||
bitmapInfo = new ShortcutCachingLogic().loadIcon(mContext, shortcutInfo);
|
||||
}
|
||||
final Bitmap unbadgedBitmap;
|
||||
if (bitmapInfo.icon != null) {
|
||||
unbadgedBitmap = bitmapInfo.icon;
|
||||
} else {
|
||||
if (fallbackIconProvider != null) {
|
||||
// Fallback icons are already badged and with appropriate shadow
|
||||
ItemInfoWithIcon fullIcon = fallbackIconProvider.get();
|
||||
if (fullIcon != null && fullIcon.bitmap != null) {
|
||||
return fullIcon.bitmap;
|
||||
}
|
||||
}
|
||||
unbadgedBitmap = cache.getDefaultIcon(Process.myUserHandle()).icon;
|
||||
}
|
||||
|
||||
if (!badged) {
|
||||
return BitmapInfo.of(unbadgedBitmap, Themes.getColorAccent(mContext));
|
||||
}
|
||||
|
||||
final Bitmap unbadgedfinal = unbadgedBitmap;
|
||||
final ItemInfoWithIcon badge = getShortcutInfoBadge(shortcutInfo, cache);
|
||||
|
||||
Bitmap icon = BitmapRenderer.createHardwareBitmap(mIconBitmapSize, mIconBitmapSize, (c) -> {
|
||||
getShadowGenerator().recreateIcon(unbadgedfinal, c);
|
||||
badgeWithDrawable(c, new FastBitmapDrawable(badge.bitmap));
|
||||
});
|
||||
return BitmapInfo.of(icon, badge.bitmap.color);
|
||||
}
|
||||
|
||||
public ItemInfoWithIcon getShortcutInfoBadge(ShortcutInfo shortcutInfo, IconCache cache) {
|
||||
ComponentName cn = shortcutInfo.getActivity();
|
||||
String badgePkg = shortcutInfo.getPackage();
|
||||
boolean hasBadgePkgSet = !badgePkg.equals(shortcutInfo.getPackage());
|
||||
if (cn != null && !hasBadgePkgSet) {
|
||||
// Get the app info for the source activity.
|
||||
AppInfo appInfo = new AppInfo();
|
||||
appInfo.user = shortcutInfo.getUserHandle();
|
||||
appInfo.componentName = cn;
|
||||
appInfo.intent = new Intent(Intent.ACTION_MAIN)
|
||||
.addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
.setComponent(cn);
|
||||
cache.getTitleAndIcon(appInfo, false);
|
||||
return appInfo;
|
||||
} else {
|
||||
PackageItemInfo pkgInfo = new PackageItemInfo(badgePkg);
|
||||
cache.getTitleAndIconForApp(pkgInfo, false);
|
||||
return pkgInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ 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;
|
||||
|
@ -57,6 +58,12 @@ public class ShortcutCachingLogic implements CachingLogic<ShortcutInfo> {
|
|||
return info.getShortLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getDescription(ShortcutInfo object, CharSequence fallback) {
|
||||
CharSequence label = object.getLongLabel();
|
||||
return TextUtils.isEmpty(label) ? fallback : label;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public BitmapInfo loadIcon(Context context, ShortcutInfo info) {
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package com.android.launcher3.model;
|
||||
|
||||
import static android.graphics.BitmapFactory.decodeByteArray;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
|
@ -26,7 +28,6 @@ import android.content.pm.LauncherApps;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWrapper;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.BaseColumns;
|
||||
import android.text.TextUtils;
|
||||
|
@ -166,37 +167,30 @@ public class LoaderCursor extends CursorWrapper {
|
|||
*/
|
||||
protected boolean loadIcon(WorkspaceItemInfo info) {
|
||||
try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
|
||||
return loadIcon(info, li);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the icon from the cursor and updates the {@param info} if the icon is an app resource.
|
||||
*/
|
||||
protected boolean loadIcon(WorkspaceItemInfo info, LauncherIcons li) {
|
||||
if (itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
|
||||
String packageName = getString(iconPackageIndex);
|
||||
String resourceName = getString(iconResourceIndex);
|
||||
if (!TextUtils.isEmpty(packageName) || !TextUtils.isEmpty(resourceName)) {
|
||||
info.iconResource = new ShortcutIconResource();
|
||||
info.iconResource.packageName = packageName;
|
||||
info.iconResource.resourceName = resourceName;
|
||||
BitmapInfo iconInfo = li.createIconBitmap(info.iconResource);
|
||||
if (iconInfo != null) {
|
||||
info.bitmap = iconInfo;
|
||||
return true;
|
||||
if (itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
|
||||
String packageName = getString(iconPackageIndex);
|
||||
String resourceName = getString(iconResourceIndex);
|
||||
if (!TextUtils.isEmpty(packageName) || !TextUtils.isEmpty(resourceName)) {
|
||||
info.iconResource = new ShortcutIconResource();
|
||||
info.iconResource.packageName = packageName;
|
||||
info.iconResource.resourceName = resourceName;
|
||||
BitmapInfo iconInfo = li.createIconBitmap(info.iconResource);
|
||||
if (iconInfo != null) {
|
||||
info.bitmap = iconInfo;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Failed to load from resource, try loading from DB.
|
||||
byte[] data = getBlob(iconIndex);
|
||||
try {
|
||||
info.bitmap = li.createIconBitmap(BitmapFactory.decodeByteArray(data, 0, data.length));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to decode byte array for info " + info, e);
|
||||
return false;
|
||||
// Failed to load from resource, try loading from DB.
|
||||
byte[] data = getBlob(iconIndex);
|
||||
try {
|
||||
info.bitmap = li.createIconBitmap(decodeByteArray(data, 0, data.length));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to decode byte array for info " + info, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ import android.content.pm.LauncherApps;
|
|||
import android.content.pm.PackageInstaller;
|
||||
import android.content.pm.PackageInstaller.SessionInfo;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
|
@ -50,7 +49,6 @@ import com.android.launcher3.AppInfo;
|
|||
import com.android.launcher3.FolderInfo;
|
||||
import com.android.launcher3.InstallShortcutReceiver;
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.ItemInfoWithIcon;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherAppWidgetInfo;
|
||||
import com.android.launcher3.LauncherModel;
|
||||
|
@ -61,11 +59,10 @@ import com.android.launcher3.config.FeatureFlags;
|
|||
import com.android.launcher3.folder.Folder;
|
||||
import com.android.launcher3.folder.FolderGridOrganizer;
|
||||
import com.android.launcher3.folder.FolderNameProvider;
|
||||
import com.android.launcher3.icons.ComponentWithLabel;
|
||||
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
|
||||
import com.android.launcher3.icons.ComponentWithLabelAndIcon;
|
||||
import com.android.launcher3.icons.ComponentWithLabelAndIcon.ComponentWithIconCachingLogic;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.icons.LauncherActivityCachingLogic;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.icons.ShortcutCachingLogic;
|
||||
import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
|
||||
import com.android.launcher3.logging.FileLog;
|
||||
|
@ -94,7 +91,6 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Runnable for the thread that loads the contents of the launcher:
|
||||
|
@ -263,7 +259,8 @@ public class LoaderTask implements Runnable {
|
|||
verifyNotStopped();
|
||||
|
||||
// fourth step
|
||||
List<ComponentWithLabel> allWidgetsList = mBgDataModel.widgetsModel.update(mApp, null);
|
||||
List<ComponentWithLabelAndIcon> allWidgetsList =
|
||||
mBgDataModel.widgetsModel.update(mApp, null);
|
||||
logger.addSplit("load widgets");
|
||||
|
||||
verifyNotStopped();
|
||||
|
@ -271,8 +268,9 @@ public class LoaderTask implements Runnable {
|
|||
logger.addSplit("bindWidgets");
|
||||
verifyNotStopped();
|
||||
|
||||
updateHandler.updateIcons(allWidgetsList, new ComponentCachingLogic(
|
||||
mApp.getContext(), true), mApp.getModel()::onWidgetLabelsUpdated);
|
||||
updateHandler.updateIcons(allWidgetsList,
|
||||
new ComponentWithIconCachingLogic(mApp.getContext(), true),
|
||||
mApp.getModel()::onWidgetLabelsUpdated);
|
||||
logger.addSplit("save widgets in icon cache");
|
||||
|
||||
// fifth step
|
||||
|
@ -544,17 +542,10 @@ public class LoaderTask implements Runnable {
|
|||
continue;
|
||||
}
|
||||
info = new WorkspaceItemInfo(pinnedShortcut, context);
|
||||
final WorkspaceItemInfo finalInfo = info;
|
||||
|
||||
LauncherIcons li = LauncherIcons.obtain(context);
|
||||
// If the pinned deep shortcut is no longer published,
|
||||
// use the last saved icon instead of the default.
|
||||
Supplier<ItemInfoWithIcon> fallbackIconProvider = () ->
|
||||
c.loadIcon(finalInfo, li) ? finalInfo : null;
|
||||
info.bitmap = li.createShortcutIcon(
|
||||
pinnedShortcut, true /* badged */,
|
||||
fallbackIconProvider);
|
||||
li.recycle();
|
||||
mIconCache.getShortcutIcon(info, pinnedShortcut, c::loadIcon);
|
||||
|
||||
if (pmHelper.isAppSuspended(
|
||||
pinnedShortcut.getPackage(), info.user)) {
|
||||
info.runtimeStatusFlags |= FLAG_DISABLED_SUSPENDED;
|
||||
|
@ -854,23 +845,23 @@ public class LoaderTask implements Runnable {
|
|||
|
||||
private void setIgnorePackages(IconCacheUpdateHandler updateHandler) {
|
||||
// Ignore packages which have a promise icon.
|
||||
HashSet<String> packagesToIgnore = new HashSet<>();
|
||||
synchronized (mBgDataModel) {
|
||||
for (ItemInfo info : mBgDataModel.itemsIdMap) {
|
||||
if (info instanceof WorkspaceItemInfo) {
|
||||
WorkspaceItemInfo si = (WorkspaceItemInfo) info;
|
||||
if (si.isPromise() && si.getTargetComponent() != null) {
|
||||
packagesToIgnore.add(si.getTargetComponent().getPackageName());
|
||||
updateHandler.addPackagesToIgnore(
|
||||
si.user, si.getTargetComponent().getPackageName());
|
||||
}
|
||||
} else if (info instanceof LauncherAppWidgetInfo) {
|
||||
LauncherAppWidgetInfo lawi = (LauncherAppWidgetInfo) info;
|
||||
if (lawi.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) {
|
||||
packagesToIgnore.add(lawi.providerName.getPackageName());
|
||||
updateHandler.addPackagesToIgnore(
|
||||
lawi.user, lawi.providerName.getPackageName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
updateHandler.setPackagesToIgnore(Process.myUserHandle(), packagesToIgnore);
|
||||
}
|
||||
|
||||
private List<LauncherActivityInfo> loadAllApps() {
|
||||
|
|
|
@ -23,7 +23,6 @@ import com.android.launcher3.ItemInfo;
|
|||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
|
@ -89,12 +88,7 @@ public class ShortcutsChangedTask extends BaseModelUpdateTask {
|
|||
}
|
||||
for (final WorkspaceItemInfo workspaceItemInfo : workspaceItemInfos) {
|
||||
workspaceItemInfo.updateFromDeepShortcutInfo(fullDetails, context);
|
||||
// If the shortcut is pinned but no longer has an icon in the system,
|
||||
// keep the current icon instead of reverting to the default icon.
|
||||
LauncherIcons li = LauncherIcons.obtain(context);
|
||||
workspaceItemInfo.bitmap = li.createShortcutIcon(
|
||||
fullDetails, true, () -> workspaceItemInfo);
|
||||
li.recycle();
|
||||
app.getIconCache().getShortcutIcon(workspaceItemInfo, fullDetails);
|
||||
updatedWorkspaceItemInfos.add(workspaceItemInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import com.android.launcher3.ItemInfo;
|
|||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest.QueryResult;
|
||||
|
@ -89,11 +88,7 @@ public class UserLockStateChangedTask extends BaseModelUpdateTask {
|
|||
}
|
||||
si.runtimeStatusFlags &= ~FLAG_DISABLED_LOCKED_USER;
|
||||
si.updateFromDeepShortcutInfo(shortcut, context);
|
||||
// If the shortcut is pinned but no longer has an icon in the system,
|
||||
// keep the current icon instead of reverting to the default icon.
|
||||
LauncherIcons li = LauncherIcons.obtain(context);
|
||||
si.bitmap = li.createShortcutIcon(shortcut, true, () -> si);
|
||||
li.recycle();
|
||||
app.getIconCache().getShortcutIcon(si, shortcut);
|
||||
} else {
|
||||
si.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package com.android.launcher3.pm;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
import static com.android.launcher3.util.ShortcutUtil.fetchAndUpdateShortcutIconAsync;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
|
@ -32,8 +31,7 @@ import androidx.annotation.Nullable;
|
|||
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.icons.ShortcutCachingLogic;
|
||||
|
||||
public class PinRequestHelper {
|
||||
|
||||
|
@ -82,16 +80,10 @@ public class PinRequestHelper {
|
|||
|
||||
ShortcutInfo si = request.getShortcutInfo();
|
||||
WorkspaceItemInfo info = new WorkspaceItemInfo(si, context);
|
||||
// Apply the unbadged icon and fetch the actual icon asynchronously.
|
||||
if (FeatureFlags.ENABLE_DEEP_SHORTCUT_ICON_CACHE.get()) {
|
||||
fetchAndUpdateShortcutIconAsync(context, info, si, false);
|
||||
} else {
|
||||
LauncherIcons li = LauncherIcons.obtain(context);
|
||||
info.bitmap = li.createShortcutIcon(si, false /* badged */);
|
||||
li.recycle();
|
||||
LauncherAppState.getInstance(context).getModel()
|
||||
.updateAndBindWorkspaceItem(info, si);
|
||||
}
|
||||
// Apply the unbadged icon synchronously using the caching logic directly and
|
||||
// fetch the actual icon asynchronously.
|
||||
info.bitmap = new ShortcutCachingLogic().loadIcon(context, si);
|
||||
LauncherAppState.getInstance(context).getModel().updateAndBindWorkspaceItem(info, si);
|
||||
return info;
|
||||
} else {
|
||||
return null;
|
||||
|
|
|
@ -41,7 +41,7 @@ import com.android.launcher3.LauncherSettings;
|
|||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.icons.ComponentWithLabel;
|
||||
import com.android.launcher3.icons.ComponentWithLabelAndIcon;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
|
||||
|
@ -51,7 +51,7 @@ import java.util.List;
|
|||
/**
|
||||
* Wrapper class for representing a shortcut configure activity.
|
||||
*/
|
||||
public abstract class ShortcutConfigActivityInfo implements ComponentWithLabel {
|
||||
public abstract class ShortcutConfigActivityInfo implements ComponentWithLabelAndIcon {
|
||||
|
||||
private static final String TAG = "SCActivityInfo";
|
||||
|
||||
|
@ -77,6 +77,7 @@ public abstract class ShortcutConfigActivityInfo implements ComponentWithLabel {
|
|||
return LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Drawable getFullResIcon(IconCache cache);
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,8 +26,9 @@ import androidx.annotation.VisibleForTesting;
|
|||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.notification.NotificationInfo;
|
||||
import com.android.launcher3.notification.NotificationKeyData;
|
||||
import com.android.launcher3.notification.NotificationListener;
|
||||
|
@ -153,13 +154,11 @@ public class PopupPopulator {
|
|||
String shortcutIdToDeDupe = notificationKeys.isEmpty() ? null
|
||||
: notificationKeys.get(0).shortcutId;
|
||||
shortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts, shortcutIdToDeDupe);
|
||||
IconCache cache = LauncherAppState.getInstance(launcher).getIconCache();
|
||||
for (int i = 0; i < shortcuts.size() && i < shortcutViews.size(); i++) {
|
||||
final ShortcutInfo shortcut = shortcuts.get(i);
|
||||
final WorkspaceItemInfo si = new WorkspaceItemInfo(shortcut, launcher);
|
||||
// Use unbadged icon for the menu.
|
||||
LauncherIcons li = LauncherIcons.obtain(launcher);
|
||||
si.bitmap = li.createShortcutIcon(shortcut, false /* badged */);
|
||||
li.recycle();
|
||||
cache.getUnbadgedShortcutIcon(si, shortcut);
|
||||
si.rank = i;
|
||||
|
||||
final DeepShortcutView view = shortcutViews.get(i);
|
||||
|
|
|
@ -15,19 +15,10 @@
|
|||
*/
|
||||
package com.android.launcher3.util;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.model.WidgetsModel;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
|
||||
|
@ -70,21 +61,6 @@ public class ShortcutUtil {
|
|||
&& info instanceof WorkspaceItemInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the shortcut icon in background, then update the UI.
|
||||
*/
|
||||
public static void fetchAndUpdateShortcutIconAsync(
|
||||
@NonNull Context context, @NonNull WorkspaceItemInfo info, @NonNull ShortcutInfo si,
|
||||
boolean badged) {
|
||||
MODEL_EXECUTOR.execute(() -> {
|
||||
try (LauncherIcons li = LauncherIcons.obtain(context)) {
|
||||
info.bitmap = li.createShortcutIcon(si, badged, null);
|
||||
LauncherAppState.getInstance(context).getModel()
|
||||
.updateAndBindWorkspaceItem(info, si);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isActive(ItemInfo info) {
|
||||
boolean isLoading = info instanceof WorkspaceItemInfo
|
||||
&& ((WorkspaceItemInfo) info).hasPromiseIconUi();
|
||||
|
|
|
@ -21,7 +21,7 @@ import com.android.launcher3.LauncherAppWidgetProviderInfo;
|
|||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.compat.AlphabeticIndexCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.icons.ComponentWithLabel;
|
||||
import com.android.launcher3.icons.ComponentWithLabelAndIcon;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
|
||||
import com.android.launcher3.util.MultiHashMap;
|
||||
|
@ -85,12 +85,13 @@ public class WidgetsModel {
|
|||
* @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise
|
||||
* only widgets and shortcuts associated with the package/user are.
|
||||
*/
|
||||
public List<ComponentWithLabel> update(LauncherAppState app, @Nullable PackageUserKey packageUser) {
|
||||
public List<ComponentWithLabelAndIcon> update(
|
||||
LauncherAppState app, @Nullable PackageUserKey packageUser) {
|
||||
Preconditions.assertWorkerThread();
|
||||
|
||||
Context context = app.getContext();
|
||||
final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
|
||||
List<ComponentWithLabel> updatedItems = new ArrayList<>();
|
||||
List<ComponentWithLabelAndIcon> updatedItems = new ArrayList<>();
|
||||
try {
|
||||
InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
|
||||
PackageManager pm = app.getContext().getPackageManager();
|
||||
|
|
Loading…
Reference in New Issue