summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java8
-rw-r--r--iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java6
-rw-r--r--src/com/android/launcher3/icons/IconCache.java12
-rw-r--r--src/com/android/launcher3/icons/LauncherIcons.java14
-rw-r--r--src/com/android/launcher3/icons/ShortcutCachingLogic.java67
-rw-r--r--src/com/android/launcher3/model/LoaderTask.java30
6 files changed, 119 insertions, 18 deletions
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
index 09f59b84c..16bc7ae83 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
@@ -17,6 +17,7 @@ package com.android.launcher3.icons.cache;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageInfo;
import android.os.LocaleList;
import android.os.UserHandle;
@@ -41,4 +42,11 @@ public interface CachingLogic<T> {
default String getKeywords(T object, LocaleList localeList) {
return null;
}
+
+ /**
+ * Returns the timestamp the entry was last updated in cache.
+ */
+ default long getLastUpdatedTime(T object, PackageInfo info) {
+ return info.lastUpdateTime;
+ }
}
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java b/iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java
index 3c71bd027..bcdbce5e2 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java
@@ -171,8 +171,9 @@ public class IconCacheUpdateHandler {
long updateTime = c.getLong(indexLastUpdate);
int version = c.getInt(indexVersion);
T app = componentMap.remove(component);
- if (version == info.versionCode && updateTime == info.lastUpdateTime &&
- TextUtils.equals(c.getString(systemStateIndex),
+ if (version == info.versionCode
+ && updateTime == cachingLogic.getLastUpdatedTime(app, info)
+ && TextUtils.equals(c.getString(systemStateIndex),
mIconCache.getIconSystemState(info.packageName))) {
if (mFilterMode == MODE_CLEAR_VALID_ITEMS) {
@@ -231,7 +232,6 @@ public class IconCacheUpdateHandler {
}
}
-
/**
* A runnable that updates invalid icons and adds missing icons in the DB for the provided
* LauncherActivityInfo list. Items are updated/added one at a time, so that the
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index a8ff23275..50b5222d3 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;
@@ -49,6 +50,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;
@@ -63,6 +65,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;
@@ -76,6 +79,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);
@@ -174,6 +178,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/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) {