Merge "Removing additional rpc due to icon cache update" into ub-launcher3-master

This commit is contained in:
Sunny Goyal 2018-09-24 16:43:18 +00:00 committed by Android (Google) Code Review
commit f7ed9c0f2c
24 changed files with 303 additions and 222 deletions

View File

@ -26,6 +26,7 @@ import android.util.Log;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.ItemInfoMatcher;

View File

@ -40,8 +40,8 @@ import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.widget.TextView;
import com.android.launcher3.IconCache.IconLoadRequest;
import com.android.launcher3.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.icons.IconCache.IconLoadRequest;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.Launcher.OnResumeCallback;
import com.android.launcher3.badge.BadgeInfo;
import com.android.launcher3.badge.BadgeRenderer;

View File

@ -87,6 +87,7 @@ import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.FolderIconPreviewVerifier;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.keyboard.CustomActionsPopup;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logging.FileLog;

View File

@ -29,6 +29,7 @@ import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Preconditions;

View File

@ -39,6 +39,7 @@ import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.AddWorkspaceItemsTask;
import com.android.launcher3.model.BaseModelUpdateTask;
import com.android.launcher3.model.BgDataModel;

View File

@ -25,6 +25,7 @@ import android.text.TextUtils;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.util.ContentWriter;

View File

@ -33,6 +33,7 @@ import com.android.launcher3.compat.ShortcutConfigActivityInfo;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.graphics.ShadowGenerator;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;

View File

@ -27,7 +27,7 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.SparseArray;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.config.FeatureFlags;

View File

@ -32,7 +32,7 @@ import android.os.UserHandle;
import android.util.Log;
import android.widget.Toast;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;

View File

@ -28,7 +28,7 @@ import android.os.Build;
import android.os.Process;
import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;

View File

@ -44,7 +44,7 @@ import android.os.UserHandle;
import com.android.launcher3.AppInfo;
import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.LauncherAppState;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.launcher3;
package com.android.launcher3.icons;
import static com.android.launcher3.graphics.BitmapInfo.LOW_RES_ICON;
@ -38,11 +38,19 @@ import android.graphics.drawable.Drawable;
import android.os.Build.VERSION;
import android.os.Handler;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import com.android.launcher3.AppInfo;
import com.android.launcher3.IconProvider;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.graphics.BitmapInfo;
@ -54,14 +62,9 @@ import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Provider;
import com.android.launcher3.util.SQLiteCacheHelper;
import com.android.launcher3.util.Thunk;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import androidx.annotation.NonNull;
import androidx.core.graphics.ColorUtils;
@ -81,8 +84,6 @@ public class IconCache {
private static final boolean DEBUG = false;
private static final boolean DEBUG_IGNORE_CACHE = false;
@Thunk static final Object ICON_UPDATE_TOKEN = new Object();
public static class CacheEntry extends BitmapInfo {
public CharSequence title = "";
public CharSequence contentDescription = "";
@ -93,20 +94,21 @@ public class IconCache {
}
private final HashMap<UserHandle, BitmapInfo> mDefaultIcons = new HashMap<>();
@Thunk final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
private final Context mContext;
private final PackageManager mPackageManager;
private final IconProvider mIconProvider;
@Thunk final UserManagerCompat mUserManager;
private final LauncherAppsCompat mLauncherApps;
final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
final Context mContext;
final PackageManager mPackageManager;
final IconProvider mIconProvider;
final UserManagerCompat mUserManager;
final LauncherAppsCompat mLauncherApps;
private final HashMap<ComponentKey, CacheEntry> mCache =
new HashMap<>(INITIAL_ICON_CACHE_CAPACITY);
private final InstantAppResolver mInstantAppResolver;
private final int mIconDpi;
@Thunk final IconDB mIconDb;
@Thunk final Handler mWorkerHandler;
final IconDB mIconDb;
final Handler mWorkerHandler;
private final BitmapFactory.Options mDecodeOptions;
@ -247,115 +249,9 @@ public class IconCache {
new String[]{packageName + "/%", Long.toString(userSerial)});
}
public void updateDbIcons(Set<String> ignorePackagesForMainUser) {
// Remove all active icon update tasks.
mWorkerHandler.removeCallbacksAndMessages(ICON_UPDATE_TOKEN);
public IconCacheUpdateHandler getUpdateHandler() {
mIconProvider.updateSystemStateString(mContext);
for (UserHandle user : mUserManager.getUserProfiles()) {
// Query for the set of apps
final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
// Fail if we don't have any apps
// TODO: Fix this. Only fail for the current user.
if (apps == null || apps.isEmpty()) {
return;
}
// Update icon cache. This happens in segments and {@link #onPackageIconsUpdated}
// is called by the icon cache when the job is complete.
updateDBIcons(user, apps, Process.myUserHandle().equals(user)
? ignorePackagesForMainUser : Collections.<String>emptySet());
}
}
/**
* Updates the persistent DB, such that only entries corresponding to {@param apps} remain in
* the DB and are updated.
* @return The set of packages for which icons have updated.
*/
private void updateDBIcons(UserHandle user, List<LauncherActivityInfo> apps,
Set<String> ignorePackages) {
long userSerial = mUserManager.getSerialNumberForUser(user);
PackageManager pm = mContext.getPackageManager();
HashMap<String, PackageInfo> pkgInfoMap = new HashMap<>();
for (PackageInfo info : pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES)) {
pkgInfoMap.put(info.packageName, info);
}
HashMap<ComponentName, LauncherActivityInfo> componentMap = new HashMap<>();
for (LauncherActivityInfo app : apps) {
componentMap.put(app.getComponentName(), app);
}
HashSet<Integer> itemsToRemove = new HashSet<>();
Stack<LauncherActivityInfo> appsToUpdate = new Stack<>();
Cursor c = null;
try {
c = mIconDb.query(
new String[]{IconDB.COLUMN_ROWID, IconDB.COLUMN_COMPONENT,
IconDB.COLUMN_LAST_UPDATED, IconDB.COLUMN_VERSION,
IconDB.COLUMN_SYSTEM_STATE},
IconDB.COLUMN_USER + " = ? ",
new String[]{Long.toString(userSerial)});
final int indexComponent = c.getColumnIndex(IconDB.COLUMN_COMPONENT);
final int indexLastUpdate = c.getColumnIndex(IconDB.COLUMN_LAST_UPDATED);
final int indexVersion = c.getColumnIndex(IconDB.COLUMN_VERSION);
final int rowIndex = c.getColumnIndex(IconDB.COLUMN_ROWID);
final int systemStateIndex = c.getColumnIndex(IconDB.COLUMN_SYSTEM_STATE);
while (c.moveToNext()) {
String cn = c.getString(indexComponent);
ComponentName component = ComponentName.unflattenFromString(cn);
PackageInfo info = pkgInfoMap.get(component.getPackageName());
if (info == null) {
if (!ignorePackages.contains(component.getPackageName())) {
remove(component, user);
itemsToRemove.add(c.getInt(rowIndex));
}
continue;
}
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_IS_DATA_ONLY) != 0) {
// Application is not present
continue;
}
long updateTime = c.getLong(indexLastUpdate);
int version = c.getInt(indexVersion);
LauncherActivityInfo app = componentMap.remove(component);
if (version == info.versionCode && updateTime == info.lastUpdateTime &&
TextUtils.equals(c.getString(systemStateIndex),
mIconProvider.getIconSystemState(info.packageName))) {
continue;
}
if (app == null) {
remove(component, user);
itemsToRemove.add(c.getInt(rowIndex));
} else {
appsToUpdate.add(app);
}
}
} catch (SQLiteException e) {
Log.d(TAG, "Error reading icon cache", e);
// Continue updating whatever we have read so far
} finally {
if (c != null) {
c.close();
}
}
if (!itemsToRemove.isEmpty()) {
mIconDb.delete(
Utilities.createDbSelectionQuery(IconDB.COLUMN_ROWID, itemsToRemove), null);
}
// Insert remaining apps.
if (!componentMap.isEmpty() || !appsToUpdate.isEmpty()) {
Stack<LauncherActivityInfo> appsToAdd = new Stack<>();
appsToAdd.addAll(componentMap.values());
new SerializedIconUpdateTask(userSerial, pkgInfoMap,
appsToAdd, appsToUpdate).scheduleNext();
}
return new IconCacheUpdateHandler(this);
}
/**
@ -363,8 +259,9 @@ public class IconCache {
* @param replaceExisting if true, it will recreate the bitmap even if it already exists in
* the memory. This is useful then the previous bitmap was created using
* old data.
* package private
*/
@Thunk synchronized void addIconToDBAndMemCache(LauncherActivityInfo app,
synchronized void addIconToDBAndMemCache(LauncherActivityInfo app,
PackageInfo info, long userSerial, boolean replaceExisting) {
final ComponentKey key = new ComponentKey(app.getComponentName(), app.getUser());
CacheEntry entry = null;
@ -744,81 +641,23 @@ public class IconCache {
}
}
/**
* 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
* worker thread doesn't get blocked.
*/
@Thunk class SerializedIconUpdateTask implements Runnable {
private final long mUserSerial;
private final HashMap<String, PackageInfo> mPkgInfoMap;
private final Stack<LauncherActivityInfo> mAppsToAdd;
private final Stack<LauncherActivityInfo> mAppsToUpdate;
private final HashSet<String> mUpdatedPackages = new HashSet<>();
@Thunk SerializedIconUpdateTask(long userSerial, HashMap<String, PackageInfo> pkgInfoMap,
Stack<LauncherActivityInfo> appsToAdd,
Stack<LauncherActivityInfo> appsToUpdate) {
mUserSerial = userSerial;
mPkgInfoMap = pkgInfoMap;
mAppsToAdd = appsToAdd;
mAppsToUpdate = appsToUpdate;
}
@Override
public void run() {
if (!mAppsToUpdate.isEmpty()) {
LauncherActivityInfo app = mAppsToUpdate.pop();
String pkg = app.getComponentName().getPackageName();
PackageInfo info = mPkgInfoMap.get(pkg);
addIconToDBAndMemCache(app, info, mUserSerial, true /*replace existing*/);
mUpdatedPackages.add(pkg);
if (mAppsToUpdate.isEmpty() && !mUpdatedPackages.isEmpty()) {
// No more app to update. Notify model.
LauncherAppState.getInstance(mContext).getModel().onPackageIconsUpdated(
mUpdatedPackages, mUserManager.getUserForSerialNumber(mUserSerial));
}
// Let it run one more time.
scheduleNext();
} else if (!mAppsToAdd.isEmpty()) {
LauncherActivityInfo app = mAppsToAdd.pop();
PackageInfo info = mPkgInfoMap.get(app.getComponentName().getPackageName());
// We do not check the mPkgInfoMap when generating the mAppsToAdd. Although every
// app should have package info, this is not guaranteed by the api
if (info != null) {
addIconToDBAndMemCache(app, info, mUserSerial, false /*replace existing*/);
}
if (!mAppsToAdd.isEmpty()) {
scheduleNext();
}
}
}
public void scheduleNext() {
mWorkerHandler.postAtTime(this, ICON_UPDATE_TOKEN, SystemClock.uptimeMillis() + 1);
}
}
private static final class IconDB extends SQLiteCacheHelper {
static final class IconDB extends SQLiteCacheHelper {
private final static int RELEASE_VERSION = 25;
private final static String TABLE_NAME = "icons";
private final static String COLUMN_ROWID = "rowid";
private final static String COLUMN_COMPONENT = "componentName";
private final static String COLUMN_USER = "profileId";
private final static String COLUMN_LAST_UPDATED = "lastUpdated";
private final static String COLUMN_VERSION = "version";
private final static String COLUMN_ICON = "icon";
private final static String COLUMN_ICON_COLOR = "icon_color";
private final static String COLUMN_LABEL = "label";
private final static String COLUMN_SYSTEM_STATE = "system_state";
public final static String TABLE_NAME = "icons";
public final static String COLUMN_ROWID = "rowid";
public final static String COLUMN_COMPONENT = "componentName";
public final static String COLUMN_USER = "profileId";
public final static String COLUMN_LAST_UPDATED = "lastUpdated";
public final static String COLUMN_VERSION = "version";
public final static String COLUMN_ICON = "icon";
public final static String COLUMN_ICON_COLOR = "icon_color";
public final static String COLUMN_LABEL = "label";
public final static String COLUMN_SYSTEM_STATE = "system_state";
private final static String[] COLUMNS_HIGH_RES = new String[] {
public final static String[] COLUMNS_HIGH_RES = new String[] {
IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL, IconDB.COLUMN_ICON };
private final static String[] COLUMNS_LOW_RES = new String[] {
public final static String[] COLUMNS_LOW_RES = new String[] {
IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL };
public IconDB(Context context, int iconPixelSize) {

View File

@ -0,0 +1,223 @@
/*
* Copyright (C) 2018 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.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.IconCache.IconDB;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
/**
* Utility class to handle updating the Icon cache
*/
public class IconCacheUpdateHandler {
private static final String TAG = "IconCacheUpdateHandler";
private static final Object ICON_UPDATE_TOKEN = new Object();
private final HashMap<String, PackageInfo> mPkgInfoMap;
private final IconCache mIconCache;
private final HashMap<UserHandle, Set<String>> mPackagesToIgnore = new HashMap<>();
IconCacheUpdateHandler(IconCache cache) {
mIconCache = cache;
mPkgInfoMap = new HashMap<>();
// Remove all active icon update tasks.
mIconCache.mWorkerHandler.removeCallbacksAndMessages(ICON_UPDATE_TOKEN);
createPackageInfoMap();
}
public void setPackagesToIgnore(UserHandle userHandle, Set<String> packages) {
mPackagesToIgnore.put(userHandle, packages);
}
private void createPackageInfoMap() {
PackageManager pm = mIconCache.mPackageManager;
HashMap<String, PackageInfo> pkgInfoMap = new HashMap<>();
for (PackageInfo info : pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES)) {
pkgInfoMap.put(info.packageName, info);
}
}
/**
* Updates the persistent DB, such that only entries corresponding to {@param apps} remain in
* the DB and are updated.
* @return The set of packages for which icons have updated.
*/
public void updateIcons(List<LauncherActivityInfo> apps) {
if (apps.isEmpty()) {
return;
}
UserHandle user = apps.get(0).getUser();
Set<String> ignorePackages = mPackagesToIgnore.get(user);
if (ignorePackages == null) {
ignorePackages = Collections.emptySet();
}
long userSerial = mIconCache.mUserManager.getSerialNumberForUser(user);
HashMap<ComponentName, LauncherActivityInfo> componentMap = new HashMap<>();
for (LauncherActivityInfo app : apps) {
componentMap.put(app.getComponentName(), app);
}
HashSet<Integer> itemsToRemove = new HashSet<>();
Stack<LauncherActivityInfo> appsToUpdate = new Stack<>();
try (Cursor c = mIconCache.mIconDb.query(
new String[]{IconDB.COLUMN_ROWID, IconDB.COLUMN_COMPONENT,
IconDB.COLUMN_LAST_UPDATED, IconDB.COLUMN_VERSION,
IconDB.COLUMN_SYSTEM_STATE},
IconDB.COLUMN_USER + " = ? ",
new String[]{Long.toString(userSerial)})) {
final int indexComponent = c.getColumnIndex(IconDB.COLUMN_COMPONENT);
final int indexLastUpdate = c.getColumnIndex(IconDB.COLUMN_LAST_UPDATED);
final int indexVersion = c.getColumnIndex(IconDB.COLUMN_VERSION);
final int rowIndex = c.getColumnIndex(IconDB.COLUMN_ROWID);
final int systemStateIndex = c.getColumnIndex(IconDB.COLUMN_SYSTEM_STATE);
while (c.moveToNext()) {
String cn = c.getString(indexComponent);
ComponentName component = ComponentName.unflattenFromString(cn);
PackageInfo info = mPkgInfoMap.get(component.getPackageName());
if (info == null) {
if (!ignorePackages.contains(component.getPackageName())) {
mIconCache.remove(component, user);
itemsToRemove.add(c.getInt(rowIndex));
}
continue;
}
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_IS_DATA_ONLY) != 0) {
// Application is not present
continue;
}
long updateTime = c.getLong(indexLastUpdate);
int version = c.getInt(indexVersion);
LauncherActivityInfo app = componentMap.remove(component);
if (version == info.versionCode && updateTime == info.lastUpdateTime &&
TextUtils.equals(c.getString(systemStateIndex),
mIconCache.mIconProvider.getIconSystemState(info.packageName))) {
continue;
}
if (app == null) {
mIconCache.remove(component, user);
itemsToRemove.add(c.getInt(rowIndex));
} else {
appsToUpdate.add(app);
}
}
} catch (SQLiteException e) {
Log.d(TAG, "Error reading icon cache", e);
// Continue updating whatever we have read so far
}
if (!itemsToRemove.isEmpty()) {
mIconCache.mIconDb.delete(
Utilities.createDbSelectionQuery(IconDB.COLUMN_ROWID, itemsToRemove), null);
}
// Insert remaining apps.
if (!componentMap.isEmpty() || !appsToUpdate.isEmpty()) {
Stack<LauncherActivityInfo> appsToAdd = new Stack<>();
appsToAdd.addAll(componentMap.values());
new SerializedIconUpdateTask(userSerial, user, appsToAdd, appsToUpdate).scheduleNext();
}
}
/**
* 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
* worker thread doesn't get blocked.
*/
private class SerializedIconUpdateTask implements Runnable {
private final long mUserSerial;
private final UserHandle mUserHandle;
private final Stack<LauncherActivityInfo> mAppsToAdd;
private final Stack<LauncherActivityInfo> mAppsToUpdate;
private final HashSet<String> mUpdatedPackages = new HashSet<>();
SerializedIconUpdateTask(long userSerial, UserHandle userHandle,
Stack<LauncherActivityInfo> appsToAdd, Stack<LauncherActivityInfo> appsToUpdate) {
mUserHandle = userHandle;
mUserSerial = userSerial;
mAppsToAdd = appsToAdd;
mAppsToUpdate = appsToUpdate;
}
@Override
public void run() {
if (!mAppsToUpdate.isEmpty()) {
LauncherActivityInfo app = mAppsToUpdate.pop();
String pkg = app.getComponentName().getPackageName();
PackageInfo info = mPkgInfoMap.get(pkg);
mIconCache.addIconToDBAndMemCache(
app, info, mUserSerial, true /*replace existing*/);
mUpdatedPackages.add(pkg);
if (mAppsToUpdate.isEmpty() && !mUpdatedPackages.isEmpty()) {
// No more app to update. Notify model.
LauncherAppState.getInstance(mIconCache.mContext).getModel()
.onPackageIconsUpdated(mUpdatedPackages, mUserHandle);
}
// Let it run one more time.
scheduleNext();
} else if (!mAppsToAdd.isEmpty()) {
LauncherActivityInfo app = mAppsToAdd.pop();
PackageInfo info = mPkgInfoMap.get(app.getComponentName().getPackageName());
// We do not check the mPkgInfoMap when generating the mAppsToAdd. Although every
// app should have package info, this is not guaranteed by the api
if (info != null) {
mIconCache.addIconToDBAndMemCache(
app, info, mUserSerial, false /*replace existing*/);
}
if (!mAppsToAdd.isEmpty()) {
scheduleNext();
}
}
}
public void scheduleNext() {
mIconCache.mWorkerHandler.postAtTime(this, ICON_UPDATE_TOKEN,
SystemClock.uptimeMillis() + 1);
}
}
}

View File

@ -20,7 +20,7 @@ import android.os.UserHandle;
import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppInfo;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel.CallbackTask;

View File

@ -32,7 +32,7 @@ import android.util.Log;
import android.util.LongSparseArray;
import com.android.launcher3.AppInfo;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;

View File

@ -43,7 +43,8 @@ import android.util.MutableInt;
import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppInfo;
import com.android.launcher3.FolderInfo;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCacheUpdateHandler;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InstallShortcutReceiver;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
@ -182,7 +183,7 @@ public class LoaderTask implements Runnable {
// second step
TraceHelper.partitionSection(TAG, "step 2.1: loading all apps");
loadAllApps();
List<List<LauncherActivityInfo>> activityListPerUser = loadAllApps();
TraceHelper.partitionSection(TAG, "step 2.2: Binding all apps");
verifyNotStopped();
@ -190,7 +191,9 @@ public class LoaderTask implements Runnable {
verifyNotStopped();
TraceHelper.partitionSection(TAG, "step 2.3: Update icon cache");
updateIconCache();
IconCacheUpdateHandler updateHandler = mIconCache.getUpdateHandler();
setIgnorePackages(updateHandler);
updateIconCacheForApps(updateHandler, activityListPerUser);
// Take a break
TraceHelper.partitionSection(TAG, "step 2 completed, wait for idle");
@ -774,7 +777,7 @@ public class LoaderTask implements Runnable {
}
}
private void updateIconCache() {
private void setIgnorePackages(IconCacheUpdateHandler updateHandler) {
// Ignore packages which have a promise icon.
HashSet<String> packagesToIgnore = new HashSet<>();
synchronized (mBgDataModel) {
@ -792,12 +795,20 @@ public class LoaderTask implements Runnable {
}
}
}
mIconCache.updateDbIcons(packagesToIgnore);
updateHandler.setPackagesToIgnore(Process.myUserHandle(), packagesToIgnore);
}
private void loadAllApps() {
final List<UserHandle> profiles = mUserManager.getUserProfiles();
private void updateIconCacheForApps(IconCacheUpdateHandler updateHandler,
List<List<LauncherActivityInfo>> activityListPerUser) {
int userCount = activityListPerUser.size();
for (int i = 0; i < userCount; i++) {
updateHandler.updateIcons(activityListPerUser.get(i));
}
}
private List<List<LauncherActivityInfo>> loadAllApps() {
final List<UserHandle> profiles = mUserManager.getUserProfiles();
List<List<LauncherActivityInfo>> activityListPerUser = new ArrayList<>();
// Clear the list of apps
mBgAllAppsList.clear();
for (UserHandle user : profiles) {
@ -806,7 +817,7 @@ public class LoaderTask implements Runnable {
// Fail if we don't have any apps
// TODO: Fix this. Only fail for the current user.
if (apps == null || apps.isEmpty()) {
return;
return activityListPerUser;
}
boolean quietMode = mUserManager.isQuietModeEnabled(user);
// Create the ApplicationInfos
@ -815,6 +826,7 @@ public class LoaderTask implements Runnable {
// This builds the icon bitmaps.
mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
}
activityListPerUser.add(apps);
}
if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) {
@ -827,6 +839,7 @@ public class LoaderTask implements Runnable {
}
mBgAllAppsList.added = new ArrayList<>();
return activityListPerUser;
}
private void loadDeepShortcuts() {

View File

@ -24,7 +24,7 @@ import android.util.Log;
import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppInfo;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InstallShortcutReceiver;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;

View File

@ -11,7 +11,7 @@ import android.os.UserHandle;
import android.util.Log;
import com.android.launcher3.AppFilter;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo;

View File

@ -33,8 +33,8 @@ import android.view.View.OnClickListener;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.IconCache;
import com.android.launcher3.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.R;

View File

@ -18,7 +18,7 @@ package com.android.launcher3.widget;
import android.util.Log;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.widget.WidgetsListAdapter.WidgetListRowEntryComparator;

View File

@ -23,7 +23,7 @@ import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.R;
import com.android.launcher3.WidgetPreviewLoader;
import com.android.launcher3.model.WidgetItem;

View File

@ -24,7 +24,7 @@ import androidx.test.rule.provider.ProviderTestRule;
import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppFilter;
import com.android.launcher3.AppInfo;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;

View File

@ -10,7 +10,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;

View File

@ -29,7 +29,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import android.view.LayoutInflater;
import com.android.launcher3.IconCache;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.WidgetPreviewLoader;