diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 4 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherAppWidgetHost.java | 20 | ||||
-rw-r--r-- | src/com/android/launcher3/Workspace.java | 17 | ||||
-rw-r--r-- | src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java | 13 | ||||
-rw-r--r-- | src/com/android/launcher3/icons/IconCache.java | 12 | ||||
-rw-r--r-- | src/com/android/launcher3/icons/LauncherIcons.java | 14 | ||||
-rw-r--r-- | src/com/android/launcher3/icons/ShortcutCachingLogic.java | 67 | ||||
-rw-r--r-- | src/com/android/launcher3/logging/FileLog.java | 5 | ||||
-rw-r--r-- | src/com/android/launcher3/model/LoaderTask.java | 30 | ||||
-rw-r--r-- | src/com/android/launcher3/util/ShortcutUtil.java | 86 | ||||
-rw-r--r-- | src/com/android/launcher3/views/FloatingIconView.java | 18 |
11 files changed, 224 insertions, 62 deletions
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index b559e093a..d667e8c0c 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -334,8 +334,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, UiFactory.onCreate(this); mAppWidgetManager = AppWidgetManagerCompat.getInstance(this); - - mAppWidgetHost = new LauncherAppWidgetHost(this); + mAppWidgetHost = new LauncherAppWidgetHost(this, + appWidgetId -> getWorkspace().removeWidget(appWidgetId)); mAppWidgetHost.startListening(); mLauncherView = LayoutInflater.from(this).inflate(R.layout.launcher, null); diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java index ffdd6b70b..80c5c3eed 100644 --- a/src/com/android/launcher3/LauncherAppWidgetHost.java +++ b/src/com/android/launcher3/LauncherAppWidgetHost.java @@ -35,6 +35,7 @@ import com.android.launcher3.widget.DeferredAppWidgetHostView; import com.android.launcher3.widget.LauncherAppWidgetHostView; import java.util.ArrayList; +import java.util.function.IntConsumer; /** @@ -56,9 +57,17 @@ public class LauncherAppWidgetHost extends AppWidgetHost { private final Context mContext; private int mFlags = FLAG_RESUMED; + private IntConsumer mAppWidgetRemovedCallback = null; + public LauncherAppWidgetHost(Context context) { + this(context, null); + } + + public LauncherAppWidgetHost(Context context, + IntConsumer appWidgetRemovedCallback) { super(context, APPWIDGET_HOST_ID); mContext = context; + mAppWidgetRemovedCallback = appWidgetRemovedCallback; } @Override @@ -211,7 +220,7 @@ public class LauncherAppWidgetHost extends AppWidgetHost { } view.setAppWidget(appWidgetId, appWidget); view.switchToErrorView(); - return view; + return view; } } } @@ -229,6 +238,15 @@ public class LauncherAppWidgetHost extends AppWidgetHost { info.initSpans(mContext); } + //TODO: make this override when SDK is updated + //@Override + protected void onAppWidgetRemoved(int appWidgetId) { + if (mAppWidgetRemovedCallback == null) { + return; + } + mAppWidgetRemovedCallback.accept(appWidgetId); + } + @Override public void deleteAppWidgetId(int appWidgetId) { super.deleteAppWidgetId(appWidgetId); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 56a896627..f9201d04c 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -2802,6 +2802,23 @@ public class Workspace extends PagedView<WorkspacePageIndicator> } /** + * Removed widget from workspace by appWidgetId + * @param appWidgetId + */ + public void removeWidget(int appWidgetId) { + mapOverItems((info, view) -> { + if (info instanceof LauncherAppWidgetInfo) { + LauncherAppWidgetInfo appWidgetInfo = (LauncherAppWidgetInfo) info; + if (appWidgetInfo.appWidgetId == appWidgetId) { + mLauncher.removeItem(view, appWidgetInfo, true); + return true; + } + } + return false; + }); + } + + /** * Removes all folder listeners */ public void removeFolderListeners() { diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java index 0c1303b64..0c12c60a0 100644 --- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java @@ -1,5 +1,7 @@ package com.android.launcher3.accessibility; +import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; + import static com.android.launcher3.LauncherState.NORMAL; import android.app.AlertDialog; @@ -30,14 +32,14 @@ import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.PendingAddItemInfo; import com.android.launcher3.R; -import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.Workspace; +import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.dragndrop.DragController.DragListener; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.folder.Folder; +import com.android.launcher3.keyboard.CustomActionsPopup; import com.android.launcher3.notification.NotificationListener; import com.android.launcher3.popup.PopupContainerWithArrow; -import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.touch.ItemLongClickListener; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.ShortcutUtil; @@ -164,6 +166,13 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme } public boolean performAction(final View host, final ItemInfo item, int action) { + if (action == ACTION_LONG_CLICK && ShortcutUtil.isDeepShortcut(item)) { + CustomActionsPopup popup = new CustomActionsPopup(mLauncher, host); + if (popup.canShow()) { + popup.show(); + return true; + } + } if (action == MOVE) { beginAccessibleDrag(host, item); } else if (action == ADD_TO_WORKSPACE) { diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java index 5fb833ced..a16349bde 100644 --- a/src/com/android/launcher3/icons/IconCache.java +++ b/src/com/android/launcher3/icons/IconCache.java @@ -26,6 +26,7 @@ import android.content.pm.LauncherActivityInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ShortcutInfo; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Process; @@ -48,6 +49,7 @@ import com.android.launcher3.icons.cache.BaseIconCache; import com.android.launcher3.icons.cache.CachingLogic; import com.android.launcher3.icons.cache.HandlerRunnable; import com.android.launcher3.model.PackageItemInfo; +import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.util.InstantAppResolver; import com.android.launcher3.util.Preconditions; @@ -62,6 +64,7 @@ public class IconCache extends BaseIconCache { private final CachingLogic<ComponentWithLabel> mComponentWithLabelCachingLogic; private final CachingLogic<LauncherActivityInfo> mLauncherActivityInfoCachingLogic; + private final CachingLogic<ShortcutInfo> mShortcutCachingLogic; private final LauncherAppsCompat mLauncherApps; private final UserManagerCompat mUserManager; @@ -75,6 +78,7 @@ public class IconCache extends BaseIconCache { inv.fillResIconDpi, inv.iconBitmapSize, true /* inMemoryCache */); mComponentWithLabelCachingLogic = new ComponentCachingLogic(context); mLauncherActivityInfoCachingLogic = LauncherActivityCachingLogic.newInstance(context); + mShortcutCachingLogic = new ShortcutCachingLogic(); mLauncherApps = LauncherAppsCompat.getInstance(mContext); mUserManager = UserManagerCompat.getInstance(mContext); mInstantAppResolver = InstantAppResolver.newInstance(mContext); @@ -173,6 +177,14 @@ public class IconCache extends BaseIconCache { } /** + * Fill in info with the icon and label for deep shortcut. + */ + public synchronized CacheEntry getDeepShortcutTitleAndIcon(ShortcutInfo info) { + return cacheLocked(ShortcutKey.fromInfo(info).componentName, info.getUserHandle(), + () -> info, mShortcutCachingLogic, false, false); + } + + /** * Fill in {@param info} with the icon and label. If the * corresponding activity is not found, it reverts to the package icon. */ diff --git a/src/com/android/launcher3/icons/LauncherIcons.java b/src/com/android/launcher3/icons/LauncherIcons.java index 763240885..c6949afc3 100644 --- a/src/com/android/launcher3/icons/LauncherIcons.java +++ b/src/com/android/launcher3/icons/LauncherIcons.java @@ -21,9 +21,10 @@ 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 com.android.launcher3.AppInfo; import com.android.launcher3.FastBitmapDrawable; import com.android.launcher3.InvariantDeviceProfile; @@ -31,14 +32,12 @@ import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; import com.android.launcher3.graphics.IconShape; +import com.android.launcher3.icons.cache.BaseIconCache; import com.android.launcher3.model.PackageItemInfo; -import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.util.Themes; import java.util.function.Supplier; -import androidx.annotation.Nullable; - /** * Wrapper class to provide access to {@link BaseIconFactory} and also to provide pool of this class * that are threadsafe. @@ -126,13 +125,12 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable { public BitmapInfo createShortcutIcon(ShortcutInfo shortcutInfo, boolean badged, @Nullable Supplier<ItemInfoWithIcon> fallbackIconProvider) { - Drawable unbadgedDrawable = DeepShortcutManager.getInstance(mContext) - .getShortcutIconDrawable(shortcutInfo, mFillResIconDpi); IconCache cache = LauncherAppState.getInstance(mContext).getIconCache(); + BaseIconCache.CacheEntry entry = cache.getDeepShortcutTitleAndIcon(shortcutInfo); final Bitmap unbadgedBitmap; - if (unbadgedDrawable != null) { - unbadgedBitmap = createScaledBitmapWithoutShadow(unbadgedDrawable, 0); + if (entry.icon != null) { + unbadgedBitmap = entry.icon; } else { if (fallbackIconProvider != null) { // Fallback icons are already badged and with appropriate shadow diff --git a/src/com/android/launcher3/icons/ShortcutCachingLogic.java b/src/com/android/launcher3/icons/ShortcutCachingLogic.java new file mode 100644 index 000000000..ee79b249c --- /dev/null +++ b/src/com/android/launcher3/icons/ShortcutCachingLogic.java @@ -0,0 +1,67 @@ +/* + * 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 android.content.ComponentName; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.ShortcutInfo; +import android.graphics.drawable.Drawable; +import android.os.UserHandle; + +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.icons.cache.CachingLogic; +import com.android.launcher3.shortcuts.DeepShortcutManager; +import com.android.launcher3.shortcuts.ShortcutKey; + +/** + * Caching logic for shortcuts. + */ +public class ShortcutCachingLogic implements CachingLogic<ShortcutInfo> { + + @Override + public ComponentName getComponent(ShortcutInfo info) { + return ShortcutKey.fromInfo(info).componentName; + } + + @Override + public UserHandle getUser(ShortcutInfo info) { + return info.getUserHandle(); + } + + @Override + public CharSequence getLabel(ShortcutInfo info) { + return info.getShortLabel(); + } + + @Override + public void loadIcon(Context context, ShortcutInfo info, BitmapInfo target) { + LauncherIcons li = LauncherIcons.obtain(context); + Drawable unbadgedDrawable = DeepShortcutManager.getInstance(context) + .getShortcutIconDrawable(info, LauncherAppState.getIDP(context).fillResIconDpi); + if (unbadgedDrawable != null) { + target.icon = li.createScaledBitmapWithoutShadow(unbadgedDrawable, 0); + } + li.recycle(); + } + + @Override + public long getLastUpdatedTime(ShortcutInfo shortcutInfo, PackageInfo info) { + if (shortcutInfo == null) return info.lastUpdateTime; + return Math.max(shortcutInfo.getLastChangedTimestamp(), info.lastUpdateTime); + } +} diff --git a/src/com/android/launcher3/logging/FileLog.java b/src/com/android/launcher3/logging/FileLog.java index 47a0f537c..923a89b1c 100644 --- a/src/com/android/launcher3/logging/FileLog.java +++ b/src/com/android/launcher3/logging/FileLog.java @@ -8,8 +8,6 @@ import android.os.Message; import android.util.Log; import android.util.Pair; -import com.android.launcher3.Utilities; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.IOUtils; import java.io.BufferedReader; @@ -32,8 +30,7 @@ import java.util.concurrent.TimeUnit; */ public final class FileLog { - protected static final boolean ENABLED = - FeatureFlags.IS_DOGFOOD_BUILD || Utilities.IS_DEBUG_DEVICE; + protected static final boolean ENABLED = true; private static final String FILE_NAME_PREFIX = "log-"; private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index 60e917d1d..c3f5bc7af 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -63,6 +63,7 @@ import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic; 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; import com.android.launcher3.provider.ImportDataTask; @@ -170,7 +171,8 @@ public class LoaderTask implements Runnable { TraceHelper.beginSection(TAG); try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) { TraceHelper.partitionSection(TAG, "step 1.1: loading workspace"); - loadWorkspace(); + List<ShortcutInfo> allShortcuts = new ArrayList<>(); + loadWorkspace(allShortcuts); verifyNotStopped(); TraceHelper.partitionSection(TAG, "step 1.2: bind workspace workspace"); @@ -189,18 +191,23 @@ public class LoaderTask implements Runnable { TraceHelper.partitionSection(TAG, "step 2.1: loading all apps"); List<LauncherActivityInfo> allActivityList = loadAllApps(); - TraceHelper.partitionSection(TAG, "step 2.2: Binding all apps"); + TraceHelper.partitionSection(TAG, "step 2.2: binding all apps"); verifyNotStopped(); mResults.bindAllApps(); verifyNotStopped(); - TraceHelper.partitionSection(TAG, "step 2.3: Update icon cache"); + TraceHelper.partitionSection(TAG, "step 2.3: save app icons in icon cache"); IconCacheUpdateHandler updateHandler = mIconCache.getUpdateHandler(); setIgnorePackages(updateHandler); updateHandler.updateIcons(allActivityList, LauncherActivityCachingLogic.newInstance(mApp.getContext()), mApp.getModel()::onPackageIconsUpdated); + verifyNotStopped(); + TraceHelper.partitionSection(TAG, "step 2.4: save shortcuts in icon cache"); + updateHandler.updateIcons(allShortcuts, new ShortcutCachingLogic(), + mApp.getModel()::onPackageIconsUpdated); + // Take a break TraceHelper.partitionSection(TAG, "step 2 completed, wait for idle"); waitForIdle(); @@ -208,12 +215,17 @@ public class LoaderTask implements Runnable { // third step TraceHelper.partitionSection(TAG, "step 3.1: loading deep shortcuts"); - loadDeepShortcuts(); + List<ShortcutInfo> allDeepShortcuts = loadDeepShortcuts(); verifyNotStopped(); TraceHelper.partitionSection(TAG, "step 3.2: bind deep shortcuts"); mResults.bindDeepShortcuts(); + verifyNotStopped(); + TraceHelper.partitionSection(TAG, "step 3.3: save deep shortcuts in icon cache"); + updateHandler.updateIcons(allDeepShortcuts, + new ShortcutCachingLogic(), (pkgs, user) -> { }); + // Take a break TraceHelper.partitionSection(TAG, "step 3 completed, wait for idle"); waitForIdle(); @@ -228,7 +240,7 @@ public class LoaderTask implements Runnable { mResults.bindWidgets(); verifyNotStopped(); - TraceHelper.partitionSection(TAG, "step 4.3: Update icon cache"); + TraceHelper.partitionSection(TAG, "step 4.3: save widgets in icon cache"); updateHandler.updateIcons(allWidgetsList, new ComponentCachingLogic(mApp.getContext()), mApp.getModel()::onWidgetLabelsUpdated); @@ -249,7 +261,7 @@ public class LoaderTask implements Runnable { this.notify(); } - private void loadWorkspace() { + private void loadWorkspace(List<ShortcutInfo> allDeepShortcuts) { final Context context = mApp.getContext(); final ContentResolver contentResolver = context.getContentResolver(); final PackageManagerHelper pmHelper = new PackageManagerHelper(context); @@ -498,6 +510,7 @@ public class LoaderTask implements Runnable { info.runtimeStatusFlags |= FLAG_DISABLED_SUSPENDED; } intent = info.intent; + allDeepShortcuts.add(pinnedShortcut); } else { // Create a shortcut info in disabled mode for now. info = c.loadSimpleWorkspaceItem(); @@ -843,7 +856,8 @@ public class LoaderTask implements Runnable { return allActivityList; } - private void loadDeepShortcuts() { + private List<ShortcutInfo> loadDeepShortcuts() { + List<ShortcutInfo> allShortcuts = new ArrayList<>(); mBgDataModel.deepShortcutMap.clear(); mBgDataModel.hasShortcutHostPermission = mShortcutManager.hasHostPermission(); if (mBgDataModel.hasShortcutHostPermission) { @@ -851,10 +865,12 @@ public class LoaderTask implements Runnable { if (mUserManager.isUserUnlocked(user)) { List<ShortcutInfo> shortcuts = mShortcutManager.queryForAllShortcuts(user); + allShortcuts.addAll(shortcuts); mBgDataModel.updateDeepShortcutCounts(null, user, shortcuts); } } } + return allShortcuts; } public static boolean isValidProvider(AppWidgetProviderInfo provider) { diff --git a/src/com/android/launcher3/util/ShortcutUtil.java b/src/com/android/launcher3/util/ShortcutUtil.java index 792d69fc3..af99713a1 100644 --- a/src/com/android/launcher3/util/ShortcutUtil.java +++ b/src/com/android/launcher3/util/ShortcutUtil.java @@ -23,37 +23,57 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.shortcuts.ShortcutKey; public class ShortcutUtil { - public static boolean supportsShortcuts(ItemInfo info) { - return isActive(info) && (isApp(info) || isPinnedShortcut(info)); - } - - public static boolean supportsDeepShortcuts(ItemInfo info) { - return isActive(info) && isApp(info); - } - - public static String getShortcutIdIfPinnedShortcut(ItemInfo info) { - return isActive(info) && isPinnedShortcut(info) ? - ShortcutKey.fromItemInfo(info).getId() : null; - } - - public static String[] getPersonKeysIfPinnedShortcut(ItemInfo info) { - return isActive(info) && isPinnedShortcut(info) ? - ((WorkspaceItemInfo) info).getPersonKeys() : Utilities.EMPTY_STRING_ARRAY; - } - - private static boolean isActive(ItemInfo info) { - boolean isLoading = info instanceof WorkspaceItemInfo - && ((WorkspaceItemInfo) info).hasPromiseIconUi(); - return !isLoading && !info.isDisabled() && !FeatureFlags.GO_DISABLE_WIDGETS; - } - - private static boolean isApp(ItemInfo info) { - return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; - } - - private static boolean isPinnedShortcut(ItemInfo info) { - return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT - && info.container != ItemInfo.NO_ID - && info instanceof WorkspaceItemInfo; - } + /** + * Returns true when we should show shortcut menu for the item. + */ + public static boolean supportsShortcuts(ItemInfo info) { + return isActive(info) && (isApp(info) || isPinnedShortcut(info)); + } + + /** + * Returns true when we should show depp shortcuts in shortcut menu for the item. + */ + public static boolean supportsDeepShortcuts(ItemInfo info) { + return isActive(info) && isApp(info); + } + + /** + * Returns the shortcut id if the item is a pinned shortcut. + */ + public static String getShortcutIdIfPinnedShortcut(ItemInfo info) { + return isActive(info) && isPinnedShortcut(info) + ? ShortcutKey.fromItemInfo(info).getId() : null; + } + + /** + * Returns the person keys associated with the item. (Has no function right now.) + */ + public static String[] getPersonKeysIfPinnedShortcut(ItemInfo info) { + return isActive(info) && isPinnedShortcut(info) + ? ((WorkspaceItemInfo) info).getPersonKeys() : Utilities.EMPTY_STRING_ARRAY; + } + + /** + * Returns true if the item is a deep shortcut. + */ + public static boolean isDeepShortcut(ItemInfo info) { + return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT + && info instanceof WorkspaceItemInfo; + } + + private static boolean isActive(ItemInfo info) { + boolean isLoading = info instanceof WorkspaceItemInfo + && ((WorkspaceItemInfo) info).hasPromiseIconUi(); + return !isLoading && !info.isDisabled() && !FeatureFlags.GO_DISABLE_WIDGETS; + } + + private static boolean isApp(ItemInfo info) { + return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; + } + + private static boolean isPinnedShortcut(ItemInfo info) { + return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT + && info.container != ItemInfo.NO_ID + && info instanceof WorkspaceItemInfo; + } }
\ No newline at end of file diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index 31458930c..3912b4468 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -720,7 +720,7 @@ public class FloatingIconView extends View implements */ @UiThread public static IconLoadResult fetchIcon(Launcher l, View v, ItemInfo info, boolean isOpening) { - IconLoadResult result = new IconLoadResult(); + IconLoadResult result = new IconLoadResult(info); MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> { RectF position = new RectF(); getLocationBoundsForView(l, v, isOpening, position); @@ -749,10 +749,13 @@ public class FloatingIconView extends View implements // Get the drawable on the background thread boolean shouldLoadIcon = originalView.getTag() instanceof ItemInfo && hideOriginal; - view.mIconLoadResult = sIconLoadResult; - if (shouldLoadIcon && view.mIconLoadResult == null) { - view.mIconLoadResult = fetchIcon(launcher, originalView, - (ItemInfo) originalView.getTag(), isOpening); + if (shouldLoadIcon) { + if (sIconLoadResult != null && sIconLoadResult.itemInfo == originalView.getTag()) { + view.mIconLoadResult = sIconLoadResult; + } else { + view.mIconLoadResult = fetchIcon(launcher, originalView, + (ItemInfo) originalView.getTag(), isOpening); + } } sIconLoadResult = null; @@ -894,10 +897,15 @@ public class FloatingIconView extends View implements } private static class IconLoadResult { + final ItemInfo itemInfo; Drawable drawable; Drawable badge; int iconOffset; Runnable onIconLoaded; boolean isIconLoaded; + + public IconLoadResult(ItemInfo itemInfo) { + this.itemInfo = itemInfo; + } } } |