diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher3/IconCache.java | 16 | ||||
-rw-r--r-- | src/com/android/launcher3/InstallShortcutReceiver.java | 6 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherBackupHelper.java | 47 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherModel.java | 113 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherProvider.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/ShortcutInfo.java | 5 | ||||
-rw-r--r-- | src/com/android/launcher3/Utilities.java | 17 | ||||
-rw-r--r-- | src/com/android/launcher3/util/CursorIconInfo.java | 70 |
8 files changed, 178 insertions, 98 deletions
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java index 91b242854..14ad33799 100644 --- a/src/com/android/launcher3/IconCache.java +++ b/src/com/android/launcher3/IconCache.java @@ -46,10 +46,12 @@ import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.util.ComponentKey; 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.Locale; +import java.util.Set; import java.util.Stack; /** @@ -215,7 +217,7 @@ public class IconCache { new String[] {packageName + "/%", Long.toString(userSerial)}); } - public void updateDbIcons() { + public void updateDbIcons(Set<String> ignorePackagesForMainUser) { // Remove all active icon update tasks. mWorkerHandler.removeCallbacksAndMessages(ICON_UPDATE_TOKEN); @@ -231,7 +233,8 @@ public class IconCache { // Update icon cache. This happens in segments and {@link #onPackageIconsUpdated} // is called by the icon cache when the job is complete. - updateDBIcons(user, apps); + updateDBIcons(user, apps, UserHandleCompat.myUserHandle().equals(user) + ? ignorePackagesForMainUser : Collections.<String>emptySet()); } } @@ -240,7 +243,8 @@ public class IconCache { * the DB and are updated. * @return The set of packages for which icons have updated. */ - private void updateDBIcons(UserHandleCompat user, List<LauncherActivityInfoCompat> apps) { + private void updateDBIcons(UserHandleCompat user, List<LauncherActivityInfoCompat> apps, + Set<String> ignorePackages) { long userSerial = mUserManager.getSerialNumberForUser(user); PackageManager pm = mContext.getPackageManager(); HashMap<String, PackageInfo> pkgInfoMap = new HashMap<String, PackageInfo>(); @@ -275,8 +279,10 @@ public class IconCache { ComponentName component = ComponentName.unflattenFromString(cn); PackageInfo info = pkgInfoMap.get(component.getPackageName()); if (info == null) { - remove(component, user); - itemsToRemove.add(c.getInt(rowIndex)); + if (!ignorePackages.contains(component.getPackageName())) { + remove(component, user); + itemsToRemove.add(c.getInt(rowIndex)); + } continue; } if ((info.applicationInfo.flags & ApplicationInfo.FLAG_IS_DATA_ONLY) != 0) { diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index 448cc1dfd..3fc8fc0a9 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -432,10 +432,4 @@ public class InstallShortcutReceiver extends BroadcastReceiver { .fromResolveInfo(info, original.mContext); return new PendingInstallShortcutInfo(launcherInfo, original.mContext); } - - public static boolean isLauncherActivity(Intent intent, Context context) { - Intent data = new Intent().putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent); - PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, context); - return convertToLauncherActivityIfPossible(info).isLuncherActivity(); - } } diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java index dc0bccc3c..f2097366a 100644 --- a/src/com/android/launcher3/LauncherBackupHelper.java +++ b/src/com/android/launcher3/LauncherBackupHelper.java @@ -771,22 +771,7 @@ public class LauncherBackupHelper implements BackupHelper { favorite.spanX = c.getInt(SPANX_INDEX); favorite.spanY = c.getInt(SPANY_INDEX); favorite.iconType = c.getInt(ICON_TYPE_INDEX); - if (favorite.iconType == Favorites.ICON_TYPE_RESOURCE) { - String iconPackage = c.getString(ICON_PACKAGE_INDEX); - if (!TextUtils.isEmpty(iconPackage)) { - favorite.iconPackage = iconPackage; - } - String iconResource = c.getString(ICON_RESOURCE_INDEX); - if (!TextUtils.isEmpty(iconResource)) { - favorite.iconResource = iconResource; - } - } - if (favorite.iconType == Favorites.ICON_TYPE_BITMAP) { - byte[] blob = c.getBlob(ICON_INDEX); - if (blob != null && blob.length > 0) { - favorite.icon = blob; - } - } + String title = c.getString(TITLE_INDEX); if (!TextUtils.isEmpty(title)) { favorite.title = title; @@ -809,6 +794,22 @@ public class LauncherBackupHelper implements BackupHelper { if (!TextUtils.isEmpty(appWidgetProvider)) { favorite.appWidgetProvider = appWidgetProvider; } + } else if (favorite.itemType == Favorites.ITEM_TYPE_SHORTCUT) { + if (favorite.iconType == Favorites.ICON_TYPE_RESOURCE) { + String iconPackage = c.getString(ICON_PACKAGE_INDEX); + if (!TextUtils.isEmpty(iconPackage)) { + favorite.iconPackage = iconPackage; + } + String iconResource = c.getString(ICON_RESOURCE_INDEX); + if (!TextUtils.isEmpty(iconResource)) { + favorite.iconResource = iconResource; + } + } + + byte[] blob = c.getBlob(ICON_INDEX); + if (blob != null && blob.length > 0) { + favorite.icon = blob; + } } if (isReplaceableHotseatItem(favorite)) { @@ -852,14 +853,16 @@ public class LauncherBackupHelper implements BackupHelper { values.put(Favorites.CELLY, favorite.cellY); values.put(Favorites.SPANX, favorite.spanX); values.put(Favorites.SPANY, favorite.spanY); - values.put(Favorites.ICON_TYPE, favorite.iconType); - if (favorite.iconType == Favorites.ICON_TYPE_RESOURCE) { - values.put(Favorites.ICON_PACKAGE, favorite.iconPackage); - values.put(Favorites.ICON_RESOURCE, favorite.iconResource); - } - if (favorite.iconType == Favorites.ICON_TYPE_BITMAP) { + + if (favorite.itemType == Favorites.ITEM_TYPE_SHORTCUT) { + values.put(Favorites.ICON_TYPE, favorite.iconType); + if (favorite.iconType == Favorites.ICON_TYPE_RESOURCE) { + values.put(Favorites.ICON_PACKAGE, favorite.iconPackage); + values.put(Favorites.ICON_RESOURCE, favorite.iconResource); + } values.put(Favorites.ICON, favorite.icon); } + if (!TextUtils.isEmpty(favorite.title)) { values.put(Favorites.TITLE, favorite.title); } else { diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index f09ad7599..7414a2204 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -57,6 +57,7 @@ import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.model.WidgetsModel; import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.util.CursorIconInfo; import com.android.launcher3.util.LongArrayMap; import com.android.launcher3.util.ManagedProfileHeuristic; import com.android.launcher3.util.Thunk; @@ -903,11 +904,10 @@ public class LauncherModel extends BroadcastReceiver @Thunk boolean shortcutExists(Context context, Intent intent, UserHandleCompat user) { assertWorkspaceLoaded(); final String intentWithPkg, intentWithoutPkg; - final String packageName; if (intent.getComponent() != null) { // If component is not null, an intent with null package will produce // the same result and should also be a match. - packageName = intent.getComponent().getPackageName(); + String packageName = intent.getComponent().getPackageName(); if (intent.getPackage() != null) { intentWithPkg = intent.toUri(0); intentWithoutPkg = new Intent(intent).setPackage(null).toUri(0); @@ -918,15 +918,16 @@ public class LauncherModel extends BroadcastReceiver } else { intentWithPkg = intent.toUri(0); intentWithoutPkg = intent.toUri(0); - packageName = intent.getPackage(); } synchronized (sBgLock) { for (ItemInfo item : sBgItemsIdMap) { if (item instanceof ShortcutInfo) { ShortcutInfo info = (ShortcutInfo) item; - if (info.getIntent() != null && info.user.equals(user)) { - String s = info.getIntent().toUri(0); + Intent targetIntent = info.promisedIntent == null + ? info.intent : info.promisedIntent; + if (targetIntent != null && info.user.equals(user)) { + String s = targetIntent.toUri(0); if (intentWithPkg.equals(s) || intentWithoutPkg.equals(s)) { return true; } @@ -1793,13 +1794,6 @@ public class LauncherModel extends BroadcastReceiver (LauncherSettings.Favorites.INTENT); final int titleIndex = c.getColumnIndexOrThrow (LauncherSettings.Favorites.TITLE); - final int iconTypeIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.ICON_TYPE); - final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); - final int iconPackageIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.ICON_PACKAGE); - final int iconResourceIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.ICON_RESOURCE); final int containerIndex = c.getColumnIndexOrThrow( LauncherSettings.Favorites.CONTAINER); final int itemTypeIndex = c.getColumnIndexOrThrow( @@ -1826,6 +1820,7 @@ public class LauncherModel extends BroadcastReceiver LauncherSettings.Favorites.PROFILE_ID); final int optionsIndex = c.getColumnIndexOrThrow( LauncherSettings.Favorites.OPTIONS); + final CursorIconInfo cursorIconInfo = new CursorIconInfo(c); final LongSparseArray<UserHandleCompat> allUsers = new LongSparseArray<>(); for (UserHandleCompat user : mUserManager.getUserProfiles()) { @@ -1991,7 +1986,8 @@ public class LauncherModel extends BroadcastReceiver if (itemReplaced) { if (user.equals(UserHandleCompat.myUserHandle())) { info = getAppShortcutInfo(manager, intent, user, context, null, - iconIndex, titleIndex, false, useLowResIcon); + cursorIconInfo.iconIndex, titleIndex, + false, useLowResIcon); } else { // Don't replace items for other profiles. itemsToRemove.add(id); @@ -2003,7 +1999,7 @@ public class LauncherModel extends BroadcastReceiver "constructing info for partially restored package", true); info = getRestoredItemInfo(c, titleIndex, intent, - promiseType); + promiseType, cursorIconInfo, context); intent = getRestoredItemIntent(c, context, intent); } else { // Don't restore items for other profiles. @@ -2013,11 +2009,10 @@ public class LauncherModel extends BroadcastReceiver } else if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { info = getAppShortcutInfo(manager, intent, user, context, c, - iconIndex, titleIndex, allowMissingTarget, useLowResIcon); + cursorIconInfo.iconIndex, titleIndex, + allowMissingTarget, useLowResIcon); } else { - info = getShortcutInfo(c, context, iconTypeIndex, - iconPackageIndex, iconResourceIndex, iconIndex, - titleIndex); + info = getShortcutInfo(c, context, titleIndex, cursorIconInfo); // App shortcuts that used to be automatically added to Launcher // didn't always have the correct intent flags set, so do that @@ -2043,6 +2038,9 @@ public class LauncherModel extends BroadcastReceiver info.spanX = 1; info.spanY = 1; info.intent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber); + if (info.promisedIntent != null) { + info.promisedIntent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber); + } info.isDisabled = disabledState; if (isSafeMode && !Utilities.isSystemApp(context, intent)) { info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE; @@ -2687,7 +2685,7 @@ public class LauncherModel extends BroadcastReceiver return; } } - mIconCache.updateDbIcons(); + updateIconCache(); synchronized (LoaderTask.this) { if (mStopped) { return; @@ -2699,6 +2697,27 @@ public class LauncherModel extends BroadcastReceiver } } + private void updateIconCache() { + // Ignore packages which have a promise icon. + HashSet<String> packagesToIgnore = new HashSet<>(); + synchronized (sBgLock) { + for (ItemInfo info : sBgItemsIdMap) { + if (info instanceof ShortcutInfo) { + ShortcutInfo si = (ShortcutInfo) info; + if (si.isPromise() && si.getTargetComponent() != null) { + packagesToIgnore.add(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()); + } + } + } + } + mIconCache.updateDbIcons(packagesToIgnore); + } + private void onlyBindAllApps() { final Callbacks oldCallbacks = mCallbacks.get(); if (oldCallbacks == null) { @@ -3360,20 +3379,27 @@ public class LauncherModel extends BroadcastReceiver * Make an ShortcutInfo object for a restored application or shortcut item that points * to a package that is not yet installed on the system. */ - public ShortcutInfo getRestoredItemInfo(Cursor cursor, int titleIndex, Intent intent, - int promiseType) { + public ShortcutInfo getRestoredItemInfo(Cursor c, int titleIndex, Intent intent, + int promiseType, CursorIconInfo iconInfo, Context context) { final ShortcutInfo info = new ShortcutInfo(); info.user = UserHandleCompat.myUserHandle(); - mIconCache.getTitleAndIcon(info, intent, info.user, false /* useLowResIcon */); + + Bitmap icon = iconInfo.loadIcon(c, info, context); + // the fallback icon + if (icon == null) { + mIconCache.getTitleAndIcon(info, intent, info.user, false /* useLowResIcon */); + } else { + info.setIcon(icon); + } if ((promiseType & ShortcutInfo.FLAG_RESTORED_ICON) != 0) { - String title = (cursor != null) ? cursor.getString(titleIndex) : null; + String title = (c != null) ? c.getString(titleIndex) : null; if (!TextUtils.isEmpty(title)) { info.title = Utilities.trim(title); } } else if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) { if (TextUtils.isEmpty(info.title)) { - info.title = (cursor != null) ? Utilities.trim(cursor.getString(titleIndex)) : ""; + info.title = (c != null) ? Utilities.trim(c.getString(titleIndex)) : ""; } } else { throw new InvalidParameterException("Invalid restoreType " + promiseType); @@ -3506,10 +3532,7 @@ public class LauncherModel extends BroadcastReceiver * Make an ShortcutInfo object for a shortcut that isn't an application. */ @Thunk ShortcutInfo getShortcutInfo(Cursor c, Context context, - int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex, - int titleIndex) { - - Bitmap icon = null; + int titleIndex, CursorIconInfo iconInfo) { final ShortcutInfo info = new ShortcutInfo(); // Non-app shortcuts are only supported for current user. info.user = UserHandleCompat.myUserHandle(); @@ -3519,39 +3542,11 @@ public class LauncherModel extends BroadcastReceiver info.title = Utilities.trim(c.getString(titleIndex)); - int iconType = c.getInt(iconTypeIndex); - switch (iconType) { - case LauncherSettings.Favorites.ICON_TYPE_RESOURCE: - String packageName = c.getString(iconPackageIndex); - String resourceName = c.getString(iconResourceIndex); - info.customIcon = false; - // the resource - icon = Utilities.createIconBitmap(packageName, resourceName, context); - // the db - if (icon == null) { - icon = Utilities.createIconBitmap(c, iconIndex, context); - } - // the fallback icon - if (icon == null) { - icon = mIconCache.getDefaultIcon(info.user); - info.usingFallbackIcon = true; - } - break; - case LauncherSettings.Favorites.ICON_TYPE_BITMAP: - icon = Utilities.createIconBitmap(c, iconIndex, context); - if (icon == null) { - icon = mIconCache.getDefaultIcon(info.user); - info.customIcon = false; - info.usingFallbackIcon = true; - } else { - info.customIcon = true; - } - break; - default: + Bitmap icon = iconInfo.loadIcon(c, info, context); + // the fallback icon + if (icon == null) { icon = mIconCache.getDefaultIcon(info.user); info.usingFallbackIcon = true; - info.customIcon = false; - break; } info.setIcon(icon); return info; diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index 3ebc30737..ee72aea81 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -766,7 +766,7 @@ public class LauncherProvider extends ContentProvider { continue; } - if (!InstallShortcutReceiver.isLauncherActivity(intent, mContext)) { + if (!Utilities.isLauncherAppTarget(intent)) { continue; } diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java index a9a8216a9..56c0b9d2f 100644 --- a/src/com/android/launcher3/ShortcutInfo.java +++ b/src/com/android/launcher3/ShortcutInfo.java @@ -76,8 +76,9 @@ public class ShortcutInfo extends ItemInfo { /** * Indicates whether the icon comes from an application's resource (if false) * or from a custom Bitmap (if true.) + * TODO: remove this flag */ - boolean customIcon; + public boolean customIcon; /** * Indicates whether we're using the default fallback icon instead of something from the @@ -94,7 +95,7 @@ public class ShortcutInfo extends ItemInfo { * If isShortcut=true and customIcon=false, this contains a reference to the * shortcut icon as an application's resource. */ - Intent.ShortcutIconResource iconResource; + public Intent.ShortcutIconResource iconResource; /** * The application icon. diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index af118d7f6..0d13c6990 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -45,6 +45,7 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.PaintDrawable; import android.os.Build; +import android.os.Bundle; import android.os.Process; import android.text.TextUtils; import android.util.DisplayMetrics; @@ -62,6 +63,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; import java.util.Locale; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -676,14 +678,23 @@ public final class Utilities { * @param launchIntent The intent that will be launched when the shortcut is clicked. */ public static boolean isLauncherAppTarget(Intent launchIntent) { - return launchIntent != null + if (launchIntent != null && Intent.ACTION_MAIN.equals(launchIntent.getAction()) && launchIntent.getComponent() != null && launchIntent.getCategories() != null && launchIntent.getCategories().size() == 1 && launchIntent.hasCategory(Intent.CATEGORY_LAUNCHER) - && launchIntent.getExtras() == null - && TextUtils.isEmpty(launchIntent.getDataString()); + && TextUtils.isEmpty(launchIntent.getDataString())) { + // An app target can either have no extra or have ItemInfo.EXTRA_PROFILE. + Bundle extras = launchIntent.getExtras(); + if (extras == null) { + return true; + } else { + Set<String> keys = extras.keySet(); + return keys.size() == 1 && keys.contains(ItemInfo.EXTRA_PROFILE); + } + }; + return false; } public static float dpiFromPx(int size, DisplayMetrics metrics){ diff --git a/src/com/android/launcher3/util/CursorIconInfo.java b/src/com/android/launcher3/util/CursorIconInfo.java new file mode 100644 index 000000000..cdf9e3c60 --- /dev/null +++ b/src/com/android/launcher3/util/CursorIconInfo.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015 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.util; + +import android.content.Context; +import android.content.Intent.ShortcutIconResource; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.text.TextUtils; + +import com.android.launcher3.LauncherSettings; +import com.android.launcher3.ShortcutInfo; +import com.android.launcher3.Utilities; + +/** + * Utility class to load icon from a cursor. + */ +public class CursorIconInfo { + public final int iconTypeIndex; + public final int iconPackageIndex; + public final int iconResourceIndex; + public final int iconIndex; + + public CursorIconInfo(Cursor c) { + iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE); + iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); + iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE); + iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE); + } + + public Bitmap loadIcon(Cursor c, ShortcutInfo info, Context context) { + Bitmap icon = null; + int iconType = c.getInt(iconTypeIndex); + switch (iconType) { + case LauncherSettings.Favorites.ICON_TYPE_RESOURCE: + String packageName = c.getString(iconPackageIndex); + String resourceName = c.getString(iconResourceIndex); + if (!TextUtils.isEmpty(packageName) || !TextUtils.isEmpty(resourceName)) { + info.iconResource = new ShortcutIconResource(); + info.iconResource.packageName = packageName; + info.iconResource.resourceName = resourceName; + icon = Utilities.createIconBitmap(packageName, resourceName, context); + } + if (icon == null) { + // Failed to load from resource, try loading from DB. + icon = Utilities.createIconBitmap(c, iconIndex, context); + } + break; + case LauncherSettings.Favorites.ICON_TYPE_BITMAP: + icon = Utilities.createIconBitmap(c, iconIndex, context); + info.customIcon = icon != null; + break; + } + return icon; + } +} |