diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 39e28c0b0c..a75edb7156 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -71,10 +71,10 @@ import com.android.launcher3.util.FlagOp; import com.android.launcher3.util.GridOccupancy; import com.android.launcher3.util.LongArrayMap; import com.android.launcher3.util.ManagedProfileHeuristic; +import com.android.launcher3.util.MultiHashMap; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.StringFilter; -import com.android.launcher3.util.MultiHashMap; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.ViewOnDrawExecutor; @@ -1942,7 +1942,16 @@ public class LauncherModel extends BroadcastReceiver List fullDetails = mDeepShortcutManager .queryForFullDetails(packageName, Collections.singletonList(shortcutId), user); - if (fullDetails != null && !fullDetails.isEmpty()) { + if (fullDetails == null || fullDetails.isEmpty()) { + // There are no details for the shortcut. If this is due + // to a SecurityException, keep it in the database so + // we can restore the icon when the launcher regains + // permission. Otherwise remove the icon from the db. + if (!mDeepShortcutManager.wasLastCallSuccess()) { + itemsToRemove.add(id); + continue; + } + } else { pinnedShortcut = fullDetails.get(0); shouldPin = true; } diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java index 8bceda7f12..d1f0c5c272 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java @@ -25,7 +25,6 @@ import android.content.pm.ShortcutInfo; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.os.UserHandle; import android.util.Log; import com.android.launcher3.ItemInfo; @@ -33,7 +32,6 @@ import com.android.launcher3.LauncherSettings; import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserHandleCompat; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -53,6 +51,7 @@ public class DeepShortcutManager { FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_MANIFEST; private final LauncherApps mLauncherApps; + private boolean mWasLastCallSuccess; public DeepShortcutManager(Context context, ShortcutCache shortcutCache) { mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE); @@ -63,6 +62,10 @@ public class DeepShortcutManager { || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; } + public boolean wasLastCallSuccess() { + return mWasLastCallSuccess; + } + public void onShortcutsChanged(List shortcuts) { // mShortcutCache.removeShortcuts(shortcuts); } @@ -100,8 +103,10 @@ public class DeepShortcutManager { pinnedIds.remove(id); try { mLauncherApps.pinShortcuts(packageName, pinnedIds, user.getUser()); + mWasLastCallSuccess = true; } catch (SecurityException e) { - Log.e(TAG, Log.getStackTraceString(e)); + Log.w(TAG, "Failed to unpin shortcut", e); + mWasLastCallSuccess = false; } } } @@ -120,8 +125,10 @@ public class DeepShortcutManager { pinnedIds.add(id); try { mLauncherApps.pinShortcuts(packageName, pinnedIds, user.getUser()); + mWasLastCallSuccess = true; } catch (SecurityException e) { - Log.e(TAG, Log.getStackTraceString(e)); + Log.w(TAG, "Failed to pin shortcut", e); + mWasLastCallSuccess = false; } } } @@ -131,16 +138,12 @@ public class DeepShortcutManager { Bundle startActivityOptions, UserHandleCompat user) { if (Utilities.isNycMR1OrAbove()) { try { - // TODO: remove reflection once updated SDK is ready. - // mLauncherApps.startShortcut(packageName, id, sourceBounds, - // startActivityOptions, user.getUser()); - mLauncherApps.getClass().getMethod("startShortcut", String.class, String.class, - Rect.class, Bundle.class, UserHandle.class).invoke(mLauncherApps, - packageName, id, sourceBounds, startActivityOptions, user.getUser()); + mLauncherApps.startShortcut(packageName, id, sourceBounds, + startActivityOptions, user.getUser()); + mWasLastCallSuccess = true; } catch (SecurityException e) { - Log.e(TAG, Log.getStackTraceString(e)); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); + Log.e(TAG, "Failed to start shortcut", e); + mWasLastCallSuccess = false; } } } @@ -149,10 +152,13 @@ public class DeepShortcutManager { public Drawable getShortcutIconDrawable(ShortcutInfoCompat shortcutInfo, int density) { if (Utilities.isNycMR1OrAbove()) { try { - return mLauncherApps.getShortcutIconDrawable(shortcutInfo.getShortcutInfo(), - density); + Drawable icon = mLauncherApps.getShortcutIconDrawable( + shortcutInfo.getShortcutInfo(), density); + mWasLastCallSuccess = true; + return icon; } catch (SecurityException e) { - Log.e(TAG, Log.getStackTraceString(e)); + Log.e(TAG, "Failed to get shortcut icon", e); + mWasLastCallSuccess = false; } } return null; @@ -200,8 +206,10 @@ public class DeepShortcutManager { List shortcutInfos = null; try { shortcutInfos = mLauncherApps.getShortcuts(q, user.getUser()); + mWasLastCallSuccess = true; } catch (SecurityException e) { - Log.e(TAG, Log.getStackTraceString(e)); + Log.e(TAG, "Failed to query for shortcuts", e); + mWasLastCallSuccess = false; } if (shortcutInfos == null) { return Collections.EMPTY_LIST;