Loading core/java/android/content/pm/LauncherApps.java +4 −2 Original line number Diff line number Diff line Loading @@ -507,7 +507,8 @@ public class LauncherApps { /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been added or updated. * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery, * Executor) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. Loading @@ -525,7 +526,8 @@ public class LauncherApps { /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been removed. * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery, * Executor) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. Loading services/core/java/com/android/server/pm/LauncherAppsService.java +29 −53 Original line number Diff line number Diff line Loading @@ -746,9 +746,8 @@ public class LauncherAppsService extends SystemService { } UserHandle user = UserHandle.of(injectCallingUserId()); if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PackageManager.PERMISSION_GRANTED) { if (injectHasInteractAcrossUsersFullPermission(injectBinderCallingPid(), injectBinderCallingUid())) { user = null; } Loading Loading @@ -1053,29 +1052,6 @@ public class LauncherAppsService extends SystemService { } public static class ShortcutChangeHandler implements LauncherApps.ShortcutChangeCallback { static class QueryInfo { final long mChangedSince; final String mPackage; final List<String> mShortcutIds; final List<LocusId> mLocusIds; final ComponentName mActivity; final int mQueryFlags; final UserHandle mCallbackUser; QueryInfo(long changedSince, String packageName, List<String> shortcutIds, List<LocusId> locusIds, ComponentName activity, int flags, UserHandle callbackUser) { mChangedSince = changedSince; mPackage = packageName; mShortcutIds = shortcutIds; mLocusIds = locusIds; mActivity = activity; mQueryFlags = flags; mCallbackUser = callbackUser; } } private final UserManagerInternal mUserManagerInternal; ShortcutChangeHandler(UserManagerInternal userManager) { Loading @@ -1088,9 +1064,7 @@ public class LauncherAppsService extends SystemService { public synchronized void addShortcutChangeCallback(IShortcutChangeCallback callback, ShortcutQueryWrapper query, UserHandle user) { mCallbacks.unregister(callback); mCallbacks.register(callback, new QueryInfo(query.getChangedSince(), query.getPackage(), query.getShortcutIds(), query.getLocusIds(), query.getActivity(), query.getQueryFlags(), user)); mCallbacks.register(callback, new Pair<>(query, user)); } public synchronized void removeShortcutChangeCallback( Loading @@ -1116,16 +1090,19 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < count; i++) { final IShortcutChangeCallback callback = mCallbacks.getBroadcastItem(i); final QueryInfo query = (QueryInfo) mCallbacks.getBroadcastCookie(i); final Pair<ShortcutQueryWrapper, UserHandle> cookie = (Pair<ShortcutQueryWrapper, UserHandle>) mCallbacks.getBroadcastCookie(i); if (query.mCallbackUser != null && !hasUserAccess(query.mCallbackUser, user)) { final UserHandle callbackUser = cookie.second; if (callbackUser != null && !hasUserAccess(callbackUser, user)) { // Callback owner does not have access to the shortcuts' user. continue; } // Filter the list by query, if any matches exists, send via callback. List<ShortcutInfo> matchedList = filterShortcutsByQuery(packageName, shortcuts, query); List<ShortcutInfo> matchedList = filterShortcutsByQuery(packageName, shortcuts, cookie.first, shortcutsRemoved); if (!CollectionUtils.isEmpty(matchedList)) { try { if (shortcutsRemoved) { Loading @@ -1143,21 +1120,25 @@ public class LauncherAppsService extends SystemService { } public static List<ShortcutInfo> filterShortcutsByQuery(String packageName, List<ShortcutInfo> shortcuts, QueryInfo query) { if (query.mPackage != null && query.mPackage != packageName) { List<ShortcutInfo> shortcuts, ShortcutQueryWrapper query, boolean shortcutsRemoved) { final long changedSince = query.getChangedSince(); final String queryPackage = query.getPackage(); final List<String> shortcutIds = query.getShortcutIds(); final List<LocusId> locusIds = query.getLocusIds(); final ComponentName activity = query.getActivity(); final int flags = query.getQueryFlags(); if (queryPackage != null && !queryPackage.equals(packageName)) { return null; } List<ShortcutInfo> matches = new ArrayList<>(); final boolean matchDynamic = (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0; final boolean matchPinned = (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0; final boolean matchManifest = (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0; final boolean matchCached = (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_CACHED) != 0; final boolean matchDynamic = (flags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0; final boolean matchPinned = (flags & ShortcutQuery.FLAG_MATCH_PINNED) != 0; final boolean matchManifest = (flags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0; final boolean matchCached = (flags & ShortcutQuery.FLAG_MATCH_CACHED) != 0; final int shortcutFlags = (matchDynamic ? ShortcutInfo.FLAG_DYNAMIC : 0) | (matchPinned ? ShortcutInfo.FLAG_PINNED : 0) | (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0) Loading @@ -1166,24 +1147,19 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < shortcuts.size(); i++) { final ShortcutInfo si = shortcuts.get(i); if (query.mActivity != null && !query.mActivity.equals(si.getActivity())) { if (activity != null && !activity.equals(si.getActivity())) { continue; } if (query.mChangedSince != 0 && query.mChangedSince > si.getLastChangedTimestamp()) { if (changedSince != 0 && changedSince > si.getLastChangedTimestamp()) { continue; } if (query.mShortcutIds != null && !query.mShortcutIds.contains(si.getId())) { if (shortcutIds != null && !shortcutIds.contains(si.getId())) { continue; } if (query.mLocusIds != null && !query.mLocusIds.contains(si.getLocusId())) { if (locusIds != null && !locusIds.contains(si.getLocusId())) { continue; } if ((shortcutFlags & si.getFlags()) != 0) { if (shortcutsRemoved || (shortcutFlags & si.getFlags()) != 0) { matches.add(si); } } Loading services/core/java/com/android/server/pm/ShortcutPackage.java +63 −37 Original line number Diff line number Diff line Loading @@ -256,7 +256,7 @@ class ShortcutPackage extends ShortcutPackageItem { if (shortcut != null) { mShortcutUser.mService.removeIconLocked(shortcut); shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_MANIFEST); | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED); } return shortcut; } Loading @@ -281,8 +281,10 @@ class ShortcutPackage extends ShortcutPackageItem { * invisible. * * It checks the max number of dynamic shortcuts. * * @return True if it replaced an existing shortcut, False otherwise. */ public void addOrReplaceDynamicShortcut(@NonNull ShortcutInfo newShortcut) { public boolean addOrReplaceDynamicShortcut(@NonNull ShortcutInfo newShortcut) { Preconditions.checkArgument(newShortcut.isEnabled(), "add/setDynamicShortcuts() cannot publish disabled shortcuts"); Loading @@ -291,38 +293,59 @@ class ShortcutPackage extends ShortcutPackageItem { final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId()); final boolean replaced; final boolean wasPinned; final boolean wasCached; if (oldShortcut == null) { replaced = false; wasPinned = false; wasCached = false; } else { // It's an update case. // Make sure the target is updatable. (i.e. should be mutable.) oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false); replaced = true; wasPinned = oldShortcut.isPinned(); wasCached = oldShortcut.isCached(); } // If it was originally pinned, the new one should be pinned too. if (wasPinned) { newShortcut.addFlags(ShortcutInfo.FLAG_PINNED); } if (wasCached) { newShortcut.addFlags(ShortcutInfo.FLAG_CACHED); } forceReplaceShortcutInner(newShortcut); return replaced; } /** * Push a shortcut. If the max number of dynamic shortcuts is already reached, remove the * shortcut with the lowest rank before adding the new shortcut. * * Any shortcut that gets altered (removed or changed) as a result of this push operation will * be included and returned in changedShortcuts. * * @return True if a shortcut had to be removed to complete this operation, False otherwise. */ public boolean pushDynamicShortcut(@NonNull ShortcutInfo newShortcut) { public boolean pushDynamicShortcut(@NonNull ShortcutInfo newShortcut, @NonNull List<ShortcutInfo> changedShortcuts) { Preconditions.checkArgument(newShortcut.isEnabled(), "pushDynamicShortcuts() cannot publish disabled shortcuts"); newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC); changedShortcuts.clear(); final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId()); boolean wasPinned = false; boolean wasCached = false; boolean deleted = false; if (oldShortcut == null) { final ShortcutService service = mShortcutUser.mService; Loading @@ -343,10 +366,11 @@ class ShortcutPackage extends ShortcutPackageItem { // All shortcuts are manifest shortcuts and cannot be removed. Slog.e(TAG, "Failed to remove manifest shortcut while pushing dynamic shortcut " + newShortcut.getId()); return false; return true; // poppedShortcuts is empty which indicates a failure. } deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true); changedShortcuts.add(shortcut); deleted = deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true) != null; } } else { // It's an update case. Loading @@ -354,15 +378,19 @@ class ShortcutPackage extends ShortcutPackageItem { oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false); wasPinned = oldShortcut.isPinned(); wasCached = oldShortcut.isCached(); } // If it was originally pinned, the new one should be pinned too. // If it was originally pinned or cached, the new one should be pinned or cached too. if (wasPinned) { newShortcut.addFlags(ShortcutInfo.FLAG_PINNED); } if (wasCached) { newShortcut.addFlags(ShortcutInfo.FLAG_CACHED); } forceReplaceShortcutInner(newShortcut); return true; return deleted; } /** Loading @@ -371,8 +399,7 @@ class ShortcutPackage extends ShortcutPackageItem { * @return List of removed shortcuts. */ private List<ShortcutInfo> removeOrphans() { ArrayList<String> removeList = null; // Lazily initialize. List<ShortcutInfo> removedShortcuts = null; List<ShortcutInfo> removeList = null; for (int i = mShortcuts.size() - 1; i >= 0; i--) { final ShortcutInfo si = mShortcuts.valueAt(i); Loading @@ -381,18 +408,16 @@ class ShortcutPackage extends ShortcutPackageItem { if (removeList == null) { removeList = new ArrayList<>(); removedShortcuts = new ArrayList<>(); } removeList.add(si.getId()); removedShortcuts.add(si); removeList.add(si); } if (removeList != null) { for (int i = removeList.size() - 1; i >= 0; i--) { forceDeleteShortcutInner(removeList.get(i)); forceDeleteShortcutInner(removeList.get(i).getId()); } } return removedShortcuts; return removeList; } /** Loading Loading @@ -424,68 +449,69 @@ class ShortcutPackage extends ShortcutPackageItem { * Remove a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut * is pinned or cached, it'll remain as a pinned or cached shortcut, and is still enabled. * * @return true if it's removed, or false if it was not actually removed because it is either * @return The deleted shortcut, or null if it was not actually removed because it is either * pinned or cached. */ public boolean deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) { final ShortcutInfo removed = deleteOrDisableWithId( public ShortcutInfo deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) { return deleteOrDisableWithId( shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible, ShortcutInfo.DISABLED_REASON_NOT_DISABLED); return removed == null; } /** * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut * is pinned, it'll remain as a pinned shortcut, but will be disabled. * * @return true if it's actually removed because it wasn't pinned, or false if it's still * pinned. * @return Shortcut if the disabled shortcut got removed because it wasn't pinned. Or null if * it's still pinned. */ private boolean disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible, private ShortcutInfo disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible, int disabledReason) { final ShortcutInfo disabled = deleteOrDisableWithId( shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false, ignoreInvisible, disabledReason); return disabled == null; return deleteOrDisableWithId(shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false, ignoreInvisible, disabledReason); } /** * Remove a long lived shortcut by ID. If the shortcut is pinned, it'll remain as a pinned * shortcut, and is still enabled. * * @return true if it's actually removed because it wasn't pinned, or false if it's still * pinned. * @return The deleted shortcut, or null if it was not actually removed because it's pinned. */ public boolean deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) { public ShortcutInfo deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) { final ShortcutInfo shortcut = mShortcuts.get(shortcutId); if (shortcut != null) { shortcut.clearFlags(ShortcutInfo.FLAG_CACHED); } final ShortcutInfo removed = deleteOrDisableWithId( return deleteOrDisableWithId( shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible, ShortcutInfo.DISABLED_REASON_NOT_DISABLED); return removed == null; } /** * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut * is pinned, it'll remain as a pinned shortcut but will be disabled. * * @return Shortcut if the disabled shortcut got removed because it wasn't pinned. Or null if * it's still pinned. */ public void disableWithId(@NonNull String shortcutId, String disabledMessage, public ShortcutInfo disableWithId(@NonNull String shortcutId, String disabledMessage, int disabledMessageResId, boolean overrideImmutable, boolean ignoreInvisible, int disabledReason) { final ShortcutInfo disabled = deleteOrDisableWithId(shortcutId, /* disable =*/ true, final ShortcutInfo deleted = deleteOrDisableWithId(shortcutId, /* disable =*/ true, overrideImmutable, ignoreInvisible, disabledReason); // If disabled id still exists, it is pinned and we need to update the disabled message. final ShortcutInfo disabled = mShortcuts.get(shortcutId); if (disabled != null) { if (disabledMessage != null) { disabled.setDisabledMessage(disabledMessage); } else if (disabledMessageResId != 0) { disabled.setDisabledMessageResId(disabledMessageResId); mShortcutUser.mService.fixUpShortcutResourceNamesAndValues(disabled); } } return deleted; } @Nullable Loading Loading @@ -521,10 +547,10 @@ class ShortcutPackage extends ShortcutPackageItem { oldShortcut.setActivity(null); } return oldShortcut; return null; } else { forceDeleteShortcutInner(shortcutId); return null; return oldShortcut; } } Loading Loading @@ -1005,7 +1031,7 @@ class ShortcutPackage extends ShortcutPackageItem { "%s is no longer main activity. Disabling shorcut %s.", getPackageName(), si.getId())); if (disableDynamicWithId(si.getId(), /*ignoreInvisible*/ false, ShortcutInfo.DISABLED_REASON_APP_CHANGED)) { ShortcutInfo.DISABLED_REASON_APP_CHANGED) != null) { continue; // Actually removed. } // Still pinned, so fall-through and possibly update the resources. Loading services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java +3 −5 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Loading Loading @@ -513,10 +513,6 @@ class ShortcutRequestPinProcessor { launcher.addPinnedShortcut(appPackageName, appUserId, shortcutId, /*forPinRequest=*/ true); if (changedShortcuts == null) { changedShortcuts = new ArrayList<>(1); } changedShortcuts.add(original); if (current == null) { if (DEBUG) { Loading @@ -526,6 +522,8 @@ class ShortcutRequestPinProcessor { } ps.adjustRanks(); // Shouldn't be needed, but just in case. changedShortcuts = Collections.singletonList(ps.findShortcutById(shortcutId)); } mService.verifyStates(); Loading services/core/java/com/android/server/pm/ShortcutService.java +193 −69 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/content/pm/LauncherApps.java +4 −2 Original line number Diff line number Diff line Loading @@ -507,7 +507,8 @@ public class LauncherApps { /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been added or updated. * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery, * Executor) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. Loading @@ -525,7 +526,8 @@ public class LauncherApps { /** * Indicates that one or more shortcuts, that match the {@link ShortcutQuery} used to * register this callback, have been removed. * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery) * @see LauncherApps#registerShortcutChangeCallback(ShortcutChangeCallback, ShortcutQuery, * Executor) * * <p>Only the applications that are allowed to access the shortcut information, * as defined in {@link #hasShortcutHostPermission()}, will receive it. Loading
services/core/java/com/android/server/pm/LauncherAppsService.java +29 −53 Original line number Diff line number Diff line Loading @@ -746,9 +746,8 @@ public class LauncherAppsService extends SystemService { } UserHandle user = UserHandle.of(injectCallingUserId()); if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PackageManager.PERMISSION_GRANTED) { if (injectHasInteractAcrossUsersFullPermission(injectBinderCallingPid(), injectBinderCallingUid())) { user = null; } Loading Loading @@ -1053,29 +1052,6 @@ public class LauncherAppsService extends SystemService { } public static class ShortcutChangeHandler implements LauncherApps.ShortcutChangeCallback { static class QueryInfo { final long mChangedSince; final String mPackage; final List<String> mShortcutIds; final List<LocusId> mLocusIds; final ComponentName mActivity; final int mQueryFlags; final UserHandle mCallbackUser; QueryInfo(long changedSince, String packageName, List<String> shortcutIds, List<LocusId> locusIds, ComponentName activity, int flags, UserHandle callbackUser) { mChangedSince = changedSince; mPackage = packageName; mShortcutIds = shortcutIds; mLocusIds = locusIds; mActivity = activity; mQueryFlags = flags; mCallbackUser = callbackUser; } } private final UserManagerInternal mUserManagerInternal; ShortcutChangeHandler(UserManagerInternal userManager) { Loading @@ -1088,9 +1064,7 @@ public class LauncherAppsService extends SystemService { public synchronized void addShortcutChangeCallback(IShortcutChangeCallback callback, ShortcutQueryWrapper query, UserHandle user) { mCallbacks.unregister(callback); mCallbacks.register(callback, new QueryInfo(query.getChangedSince(), query.getPackage(), query.getShortcutIds(), query.getLocusIds(), query.getActivity(), query.getQueryFlags(), user)); mCallbacks.register(callback, new Pair<>(query, user)); } public synchronized void removeShortcutChangeCallback( Loading @@ -1116,16 +1090,19 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < count; i++) { final IShortcutChangeCallback callback = mCallbacks.getBroadcastItem(i); final QueryInfo query = (QueryInfo) mCallbacks.getBroadcastCookie(i); final Pair<ShortcutQueryWrapper, UserHandle> cookie = (Pair<ShortcutQueryWrapper, UserHandle>) mCallbacks.getBroadcastCookie(i); if (query.mCallbackUser != null && !hasUserAccess(query.mCallbackUser, user)) { final UserHandle callbackUser = cookie.second; if (callbackUser != null && !hasUserAccess(callbackUser, user)) { // Callback owner does not have access to the shortcuts' user. continue; } // Filter the list by query, if any matches exists, send via callback. List<ShortcutInfo> matchedList = filterShortcutsByQuery(packageName, shortcuts, query); List<ShortcutInfo> matchedList = filterShortcutsByQuery(packageName, shortcuts, cookie.first, shortcutsRemoved); if (!CollectionUtils.isEmpty(matchedList)) { try { if (shortcutsRemoved) { Loading @@ -1143,21 +1120,25 @@ public class LauncherAppsService extends SystemService { } public static List<ShortcutInfo> filterShortcutsByQuery(String packageName, List<ShortcutInfo> shortcuts, QueryInfo query) { if (query.mPackage != null && query.mPackage != packageName) { List<ShortcutInfo> shortcuts, ShortcutQueryWrapper query, boolean shortcutsRemoved) { final long changedSince = query.getChangedSince(); final String queryPackage = query.getPackage(); final List<String> shortcutIds = query.getShortcutIds(); final List<LocusId> locusIds = query.getLocusIds(); final ComponentName activity = query.getActivity(); final int flags = query.getQueryFlags(); if (queryPackage != null && !queryPackage.equals(packageName)) { return null; } List<ShortcutInfo> matches = new ArrayList<>(); final boolean matchDynamic = (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0; final boolean matchPinned = (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0; final boolean matchManifest = (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0; final boolean matchCached = (query.mQueryFlags & ShortcutQuery.FLAG_MATCH_CACHED) != 0; final boolean matchDynamic = (flags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0; final boolean matchPinned = (flags & ShortcutQuery.FLAG_MATCH_PINNED) != 0; final boolean matchManifest = (flags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0; final boolean matchCached = (flags & ShortcutQuery.FLAG_MATCH_CACHED) != 0; final int shortcutFlags = (matchDynamic ? ShortcutInfo.FLAG_DYNAMIC : 0) | (matchPinned ? ShortcutInfo.FLAG_PINNED : 0) | (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0) Loading @@ -1166,24 +1147,19 @@ public class LauncherAppsService extends SystemService { for (int i = 0; i < shortcuts.size(); i++) { final ShortcutInfo si = shortcuts.get(i); if (query.mActivity != null && !query.mActivity.equals(si.getActivity())) { if (activity != null && !activity.equals(si.getActivity())) { continue; } if (query.mChangedSince != 0 && query.mChangedSince > si.getLastChangedTimestamp()) { if (changedSince != 0 && changedSince > si.getLastChangedTimestamp()) { continue; } if (query.mShortcutIds != null && !query.mShortcutIds.contains(si.getId())) { if (shortcutIds != null && !shortcutIds.contains(si.getId())) { continue; } if (query.mLocusIds != null && !query.mLocusIds.contains(si.getLocusId())) { if (locusIds != null && !locusIds.contains(si.getLocusId())) { continue; } if ((shortcutFlags & si.getFlags()) != 0) { if (shortcutsRemoved || (shortcutFlags & si.getFlags()) != 0) { matches.add(si); } } Loading
services/core/java/com/android/server/pm/ShortcutPackage.java +63 −37 Original line number Diff line number Diff line Loading @@ -256,7 +256,7 @@ class ShortcutPackage extends ShortcutPackageItem { if (shortcut != null) { mShortcutUser.mService.removeIconLocked(shortcut); shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_MANIFEST); | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED); } return shortcut; } Loading @@ -281,8 +281,10 @@ class ShortcutPackage extends ShortcutPackageItem { * invisible. * * It checks the max number of dynamic shortcuts. * * @return True if it replaced an existing shortcut, False otherwise. */ public void addOrReplaceDynamicShortcut(@NonNull ShortcutInfo newShortcut) { public boolean addOrReplaceDynamicShortcut(@NonNull ShortcutInfo newShortcut) { Preconditions.checkArgument(newShortcut.isEnabled(), "add/setDynamicShortcuts() cannot publish disabled shortcuts"); Loading @@ -291,38 +293,59 @@ class ShortcutPackage extends ShortcutPackageItem { final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId()); final boolean replaced; final boolean wasPinned; final boolean wasCached; if (oldShortcut == null) { replaced = false; wasPinned = false; wasCached = false; } else { // It's an update case. // Make sure the target is updatable. (i.e. should be mutable.) oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false); replaced = true; wasPinned = oldShortcut.isPinned(); wasCached = oldShortcut.isCached(); } // If it was originally pinned, the new one should be pinned too. if (wasPinned) { newShortcut.addFlags(ShortcutInfo.FLAG_PINNED); } if (wasCached) { newShortcut.addFlags(ShortcutInfo.FLAG_CACHED); } forceReplaceShortcutInner(newShortcut); return replaced; } /** * Push a shortcut. If the max number of dynamic shortcuts is already reached, remove the * shortcut with the lowest rank before adding the new shortcut. * * Any shortcut that gets altered (removed or changed) as a result of this push operation will * be included and returned in changedShortcuts. * * @return True if a shortcut had to be removed to complete this operation, False otherwise. */ public boolean pushDynamicShortcut(@NonNull ShortcutInfo newShortcut) { public boolean pushDynamicShortcut(@NonNull ShortcutInfo newShortcut, @NonNull List<ShortcutInfo> changedShortcuts) { Preconditions.checkArgument(newShortcut.isEnabled(), "pushDynamicShortcuts() cannot publish disabled shortcuts"); newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC); changedShortcuts.clear(); final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId()); boolean wasPinned = false; boolean wasCached = false; boolean deleted = false; if (oldShortcut == null) { final ShortcutService service = mShortcutUser.mService; Loading @@ -343,10 +366,11 @@ class ShortcutPackage extends ShortcutPackageItem { // All shortcuts are manifest shortcuts and cannot be removed. Slog.e(TAG, "Failed to remove manifest shortcut while pushing dynamic shortcut " + newShortcut.getId()); return false; return true; // poppedShortcuts is empty which indicates a failure. } deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true); changedShortcuts.add(shortcut); deleted = deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true) != null; } } else { // It's an update case. Loading @@ -354,15 +378,19 @@ class ShortcutPackage extends ShortcutPackageItem { oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false); wasPinned = oldShortcut.isPinned(); wasCached = oldShortcut.isCached(); } // If it was originally pinned, the new one should be pinned too. // If it was originally pinned or cached, the new one should be pinned or cached too. if (wasPinned) { newShortcut.addFlags(ShortcutInfo.FLAG_PINNED); } if (wasCached) { newShortcut.addFlags(ShortcutInfo.FLAG_CACHED); } forceReplaceShortcutInner(newShortcut); return true; return deleted; } /** Loading @@ -371,8 +399,7 @@ class ShortcutPackage extends ShortcutPackageItem { * @return List of removed shortcuts. */ private List<ShortcutInfo> removeOrphans() { ArrayList<String> removeList = null; // Lazily initialize. List<ShortcutInfo> removedShortcuts = null; List<ShortcutInfo> removeList = null; for (int i = mShortcuts.size() - 1; i >= 0; i--) { final ShortcutInfo si = mShortcuts.valueAt(i); Loading @@ -381,18 +408,16 @@ class ShortcutPackage extends ShortcutPackageItem { if (removeList == null) { removeList = new ArrayList<>(); removedShortcuts = new ArrayList<>(); } removeList.add(si.getId()); removedShortcuts.add(si); removeList.add(si); } if (removeList != null) { for (int i = removeList.size() - 1; i >= 0; i--) { forceDeleteShortcutInner(removeList.get(i)); forceDeleteShortcutInner(removeList.get(i).getId()); } } return removedShortcuts; return removeList; } /** Loading Loading @@ -424,68 +449,69 @@ class ShortcutPackage extends ShortcutPackageItem { * Remove a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut * is pinned or cached, it'll remain as a pinned or cached shortcut, and is still enabled. * * @return true if it's removed, or false if it was not actually removed because it is either * @return The deleted shortcut, or null if it was not actually removed because it is either * pinned or cached. */ public boolean deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) { final ShortcutInfo removed = deleteOrDisableWithId( public ShortcutInfo deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) { return deleteOrDisableWithId( shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible, ShortcutInfo.DISABLED_REASON_NOT_DISABLED); return removed == null; } /** * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut * is pinned, it'll remain as a pinned shortcut, but will be disabled. * * @return true if it's actually removed because it wasn't pinned, or false if it's still * pinned. * @return Shortcut if the disabled shortcut got removed because it wasn't pinned. Or null if * it's still pinned. */ private boolean disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible, private ShortcutInfo disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible, int disabledReason) { final ShortcutInfo disabled = deleteOrDisableWithId( shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false, ignoreInvisible, disabledReason); return disabled == null; return deleteOrDisableWithId(shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false, ignoreInvisible, disabledReason); } /** * Remove a long lived shortcut by ID. If the shortcut is pinned, it'll remain as a pinned * shortcut, and is still enabled. * * @return true if it's actually removed because it wasn't pinned, or false if it's still * pinned. * @return The deleted shortcut, or null if it was not actually removed because it's pinned. */ public boolean deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) { public ShortcutInfo deleteLongLivedWithId(@NonNull String shortcutId, boolean ignoreInvisible) { final ShortcutInfo shortcut = mShortcuts.get(shortcutId); if (shortcut != null) { shortcut.clearFlags(ShortcutInfo.FLAG_CACHED); } final ShortcutInfo removed = deleteOrDisableWithId( return deleteOrDisableWithId( shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible, ShortcutInfo.DISABLED_REASON_NOT_DISABLED); return removed == null; } /** * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut * is pinned, it'll remain as a pinned shortcut but will be disabled. * * @return Shortcut if the disabled shortcut got removed because it wasn't pinned. Or null if * it's still pinned. */ public void disableWithId(@NonNull String shortcutId, String disabledMessage, public ShortcutInfo disableWithId(@NonNull String shortcutId, String disabledMessage, int disabledMessageResId, boolean overrideImmutable, boolean ignoreInvisible, int disabledReason) { final ShortcutInfo disabled = deleteOrDisableWithId(shortcutId, /* disable =*/ true, final ShortcutInfo deleted = deleteOrDisableWithId(shortcutId, /* disable =*/ true, overrideImmutable, ignoreInvisible, disabledReason); // If disabled id still exists, it is pinned and we need to update the disabled message. final ShortcutInfo disabled = mShortcuts.get(shortcutId); if (disabled != null) { if (disabledMessage != null) { disabled.setDisabledMessage(disabledMessage); } else if (disabledMessageResId != 0) { disabled.setDisabledMessageResId(disabledMessageResId); mShortcutUser.mService.fixUpShortcutResourceNamesAndValues(disabled); } } return deleted; } @Nullable Loading Loading @@ -521,10 +547,10 @@ class ShortcutPackage extends ShortcutPackageItem { oldShortcut.setActivity(null); } return oldShortcut; return null; } else { forceDeleteShortcutInner(shortcutId); return null; return oldShortcut; } } Loading Loading @@ -1005,7 +1031,7 @@ class ShortcutPackage extends ShortcutPackageItem { "%s is no longer main activity. Disabling shorcut %s.", getPackageName(), si.getId())); if (disableDynamicWithId(si.getId(), /*ignoreInvisible*/ false, ShortcutInfo.DISABLED_REASON_APP_CHANGED)) { ShortcutInfo.DISABLED_REASON_APP_CHANGED) != null) { continue; // Actually removed. } // Still pinned, so fall-through and possibly update the resources. Loading
services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java +3 −5 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Loading Loading @@ -513,10 +513,6 @@ class ShortcutRequestPinProcessor { launcher.addPinnedShortcut(appPackageName, appUserId, shortcutId, /*forPinRequest=*/ true); if (changedShortcuts == null) { changedShortcuts = new ArrayList<>(1); } changedShortcuts.add(original); if (current == null) { if (DEBUG) { Loading @@ -526,6 +522,8 @@ class ShortcutRequestPinProcessor { } ps.adjustRanks(); // Shouldn't be needed, but just in case. changedShortcuts = Collections.singletonList(ps.findShortcutById(shortcutId)); } mService.verifyStates(); Loading
services/core/java/com/android/server/pm/ShortcutService.java +193 −69 File changed.Preview size limit exceeded, changes collapsed. Show changes