Loading services/core/java/com/android/server/pm/ShortcutPackage.java +180 −148 Original line number Diff line number Diff line Loading @@ -166,18 +166,19 @@ class ShortcutPackage extends ShortcutPackageItem { * An in-memory copy of shortcuts for this package that was loaded from xml, keyed on IDs. */ @GuardedBy("mLock") final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>(); private final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>(); /** * A temporary copy of shortcuts that are to be cleared once persisted into AppSearch, keyed on * IDs. */ @GuardedBy("mLock") private ArrayMap<String, ShortcutInfo> mTransientShortcuts = new ArrayMap<>(0); private final ArrayMap<String, ShortcutInfo> mTransientShortcuts = new ArrayMap<>(0); /** * All the share targets from the package */ @GuardedBy("mLock") private final ArrayList<ShareTargetInfo> mShareTargets = new ArrayList<>(0); /** Loading Loading @@ -231,8 +232,10 @@ class ShortcutPackage extends ShortcutPackageItem { } public int getShortcutCount() { synchronized (mLock) { return mShortcuts.size(); } } @Override protected boolean canRestoreAnyVersion() { Loading Loading @@ -272,8 +275,10 @@ class ShortcutPackage extends ShortcutPackageItem { @Nullable public ShortcutInfo findShortcutById(@Nullable final String id) { if (id == null) return null; synchronized (mLock) { return mShortcuts.get(id); } } public boolean isShortcutExistsAndInvisibleToPublisher(String id) { ShortcutInfo si = findShortcutById(id); Loading Loading @@ -347,12 +352,15 @@ class ShortcutPackage extends ShortcutPackageItem { * Delete a shortcut by ID. This will *always* remove it even if it's immutable or invisible. */ private ShortcutInfo forceDeleteShortcutInner(@NonNull String id) { final ShortcutInfo shortcut = mShortcuts.remove(id); final ShortcutInfo shortcut; synchronized (mLock) { shortcut = mShortcuts.remove(id); if (shortcut != null) { removeIcon(shortcut); shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED_ALL); } } return shortcut; } Loading Loading @@ -524,6 +532,7 @@ class ShortcutPackage extends ShortcutPackageItem { public List<ShortcutInfo> deleteAllDynamicShortcuts() { final long now = mShortcutUser.mService.injectCurrentTimeMillis(); boolean changed = false; synchronized (mLock) { for (int i = mShortcuts.size() - 1; i >= 0; i--) { ShortcutInfo si = mShortcuts.valueAt(i); if (si.isDynamic() && si.isVisibleToPublisher()) { Loading @@ -534,6 +543,7 @@ class ShortcutPackage extends ShortcutPackageItem { si.setRank(0); // It may still be pinned, so clear the rank. } } } removeAllShortcutsAsync(); if (changed) { return removeOrphans(); Loading Loading @@ -874,6 +884,7 @@ class ShortcutPackage extends ShortcutPackageItem { */ public List<ShortcutManager.ShareShortcutInfo> getMatchingShareTargets( @NonNull IntentFilter filter) { synchronized (mLock) { final List<ShareTargetInfo> matchedTargets = new ArrayList<>(); for (int i = 0; i < mShareTargets.size(); i++) { final ShareTargetInfo target = mShareTargets.get(i); Loading Loading @@ -924,10 +935,13 @@ class ShortcutPackage extends ShortcutPackageItem { } return result; } } public boolean hasShareTargets() { synchronized (mLock) { return !mShareTargets.isEmpty(); } } /** * Returns the number of shortcuts that can be used as a share target in the ShareSheet. Such Loading @@ -935,6 +949,7 @@ class ShortcutPackage extends ShortcutPackageItem { * the app's Xml resource. */ int getSharingShortcutCount() { synchronized (mLock) { if (mShareTargets.isEmpty()) { return 0; } Loading Loading @@ -968,6 +983,7 @@ class ShortcutPackage extends ShortcutPackageItem { } return sharingShortcutCount; } } /** * Return the filenames (excluding path names) of icon bitmap files from this package. Loading Loading @@ -1090,19 +1106,25 @@ class ShortcutPackage extends ShortcutPackageItem { // Now prepare to publish manifest shortcuts. List<ShortcutInfo> newManifestShortcutList = null; final int shareTargetSize; synchronized (mLock) { try { shareTargetSize = mShareTargets.size(); newManifestShortcutList = ShortcutParser.parseShortcuts(mShortcutUser.mService, getPackageName(), getPackageUserId(), mShareTargets); } catch (IOException | XmlPullParserException e) { Slog.e(TAG, "Failed to load shortcuts from AndroidManifest.xml.", e); } } final int manifestShortcutSize = newManifestShortcutList == null ? 0 : newManifestShortcutList.size(); if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, String.format("Package %s has %d manifest shortcut(s), and %d share target(s)", getPackageName(), manifestShortcutSize, mShareTargets.size())); String.format( "Package %s has %d manifest shortcut(s), and %d share target(s)", getPackageName(), manifestShortcutSize, shareTargetSize)); } if (isNewApp && (manifestShortcutSize == 0)) { // If it's a new app, and it doesn't have manifest shortcuts, then nothing to do. Loading Loading @@ -1701,6 +1723,7 @@ class ShortcutPackage extends ShortcutPackageItem { @Override public void saveToXml(@NonNull TypedXmlSerializer out, boolean forBackup) throws IOException, XmlPullParserException { synchronized (mLock) { final int size = mShortcuts.size(); final int shareTargetSize = mShareTargets.size(); Loading @@ -1714,15 +1737,14 @@ class ShortcutPackage extends ShortcutPackageItem { ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount); ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime); if (!forBackup) { synchronized (mLock) { ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, (mIsAppSearchSchemaUpToDate) ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, mIsAppSearchSchemaUpToDate ? AppSearchShortcutInfo.SCHEMA_VERSION : 0); } } getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup); for (int j = 0; j < size; j++) { saveShortcut(out, mShortcuts.valueAt(j), forBackup, getPackageInfo().isBackupAllowed()); saveShortcut( out, mShortcuts.valueAt(j), forBackup, getPackageInfo().isBackupAllowed()); } if (!forBackup) { Loading @@ -1733,6 +1755,7 @@ class ShortcutPackage extends ShortcutPackageItem { out.endTag(null, TAG_ROOT); } } private void saveShortcut(TypedXmlSerializer out, ShortcutInfo si, boolean forBackup, boolean appSupportsBackup) Loading Loading @@ -1917,11 +1940,10 @@ class ShortcutPackage extends ShortcutPackageItem { synchronized (ret.mLock) { ret.mIsAppSearchSchemaUpToDate = ShortcutService.parseIntAttribute( parser, ATTR_SCHEMA_VERSON, 0) == AppSearchShortcutInfo.SCHEMA_VERSION; } ret.mApiCallCount = ShortcutService.parseIntAttribute(parser, ATTR_CALL_COUNT); ret.mLastResetTime = ShortcutService.parseLongAttribute(parser, ATTR_LAST_RESET); final int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT Loading Loading @@ -1950,6 +1972,7 @@ class ShortcutPackage extends ShortcutPackageItem { } ShortcutService.warnForInvalidTag(depth, tag); } } return ret; } Loading Loading @@ -2152,8 +2175,10 @@ class ShortcutPackage extends ShortcutPackageItem { @VisibleForTesting List<ShareTargetInfo> getAllShareTargetsForTest() { synchronized (mLock) { return new ArrayList<>(mShareTargets); } } @Override public void verifyStates() { Loading Loading @@ -2291,16 +2316,20 @@ class ShortcutPackage extends ShortcutPackageItem { private void saveShortcut(@NonNull final Collection<ShortcutInfo> shortcuts) { Objects.requireNonNull(shortcuts); synchronized (mLock) { for (ShortcutInfo si : shortcuts) { mShortcuts.put(si.getId(), si); } } } @Nullable List<ShortcutInfo> findAll(@NonNull final Collection<String> ids) { synchronized (mLock) { return ids.stream().map(mShortcuts::get) .filter(Objects::nonNull).collect(Collectors.toList()); } } private void forEachShortcut(@NonNull final Consumer<ShortcutInfo> cb) { forEachShortcutStopWhen(si -> { Loading @@ -2318,6 +2347,7 @@ class ShortcutPackage extends ShortcutPackageItem { private void forEachShortcutStopWhen( @NonNull final Function<ShortcutInfo, Boolean> cb) { synchronized (mLock) { for (int i = mShortcuts.size() - 1; i >= 0; i--) { final ShortcutInfo si = mShortcuts.valueAt(i); if (cb.apply(si)) { Loading @@ -2325,6 +2355,7 @@ class ShortcutPackage extends ShortcutPackageItem { } } } } @NonNull private AndroidFuture<AppSearchSession> setupSchema( Loading Loading @@ -2461,6 +2492,7 @@ class ShortcutPackage extends ShortcutPackageItem { }))); } @GuardedBy("mLock") @Override void scheduleSaveToAppSearchLocked() { final Map<String, ShortcutInfo> copy = new ArrayMap<>(mShortcuts); Loading Loading
services/core/java/com/android/server/pm/ShortcutPackage.java +180 −148 Original line number Diff line number Diff line Loading @@ -166,18 +166,19 @@ class ShortcutPackage extends ShortcutPackageItem { * An in-memory copy of shortcuts for this package that was loaded from xml, keyed on IDs. */ @GuardedBy("mLock") final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>(); private final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>(); /** * A temporary copy of shortcuts that are to be cleared once persisted into AppSearch, keyed on * IDs. */ @GuardedBy("mLock") private ArrayMap<String, ShortcutInfo> mTransientShortcuts = new ArrayMap<>(0); private final ArrayMap<String, ShortcutInfo> mTransientShortcuts = new ArrayMap<>(0); /** * All the share targets from the package */ @GuardedBy("mLock") private final ArrayList<ShareTargetInfo> mShareTargets = new ArrayList<>(0); /** Loading Loading @@ -231,8 +232,10 @@ class ShortcutPackage extends ShortcutPackageItem { } public int getShortcutCount() { synchronized (mLock) { return mShortcuts.size(); } } @Override protected boolean canRestoreAnyVersion() { Loading Loading @@ -272,8 +275,10 @@ class ShortcutPackage extends ShortcutPackageItem { @Nullable public ShortcutInfo findShortcutById(@Nullable final String id) { if (id == null) return null; synchronized (mLock) { return mShortcuts.get(id); } } public boolean isShortcutExistsAndInvisibleToPublisher(String id) { ShortcutInfo si = findShortcutById(id); Loading Loading @@ -347,12 +352,15 @@ class ShortcutPackage extends ShortcutPackageItem { * Delete a shortcut by ID. This will *always* remove it even if it's immutable or invisible. */ private ShortcutInfo forceDeleteShortcutInner(@NonNull String id) { final ShortcutInfo shortcut = mShortcuts.remove(id); final ShortcutInfo shortcut; synchronized (mLock) { shortcut = mShortcuts.remove(id); if (shortcut != null) { removeIcon(shortcut); shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED_ALL); } } return shortcut; } Loading Loading @@ -524,6 +532,7 @@ class ShortcutPackage extends ShortcutPackageItem { public List<ShortcutInfo> deleteAllDynamicShortcuts() { final long now = mShortcutUser.mService.injectCurrentTimeMillis(); boolean changed = false; synchronized (mLock) { for (int i = mShortcuts.size() - 1; i >= 0; i--) { ShortcutInfo si = mShortcuts.valueAt(i); if (si.isDynamic() && si.isVisibleToPublisher()) { Loading @@ -534,6 +543,7 @@ class ShortcutPackage extends ShortcutPackageItem { si.setRank(0); // It may still be pinned, so clear the rank. } } } removeAllShortcutsAsync(); if (changed) { return removeOrphans(); Loading Loading @@ -874,6 +884,7 @@ class ShortcutPackage extends ShortcutPackageItem { */ public List<ShortcutManager.ShareShortcutInfo> getMatchingShareTargets( @NonNull IntentFilter filter) { synchronized (mLock) { final List<ShareTargetInfo> matchedTargets = new ArrayList<>(); for (int i = 0; i < mShareTargets.size(); i++) { final ShareTargetInfo target = mShareTargets.get(i); Loading Loading @@ -924,10 +935,13 @@ class ShortcutPackage extends ShortcutPackageItem { } return result; } } public boolean hasShareTargets() { synchronized (mLock) { return !mShareTargets.isEmpty(); } } /** * Returns the number of shortcuts that can be used as a share target in the ShareSheet. Such Loading @@ -935,6 +949,7 @@ class ShortcutPackage extends ShortcutPackageItem { * the app's Xml resource. */ int getSharingShortcutCount() { synchronized (mLock) { if (mShareTargets.isEmpty()) { return 0; } Loading Loading @@ -968,6 +983,7 @@ class ShortcutPackage extends ShortcutPackageItem { } return sharingShortcutCount; } } /** * Return the filenames (excluding path names) of icon bitmap files from this package. Loading Loading @@ -1090,19 +1106,25 @@ class ShortcutPackage extends ShortcutPackageItem { // Now prepare to publish manifest shortcuts. List<ShortcutInfo> newManifestShortcutList = null; final int shareTargetSize; synchronized (mLock) { try { shareTargetSize = mShareTargets.size(); newManifestShortcutList = ShortcutParser.parseShortcuts(mShortcutUser.mService, getPackageName(), getPackageUserId(), mShareTargets); } catch (IOException | XmlPullParserException e) { Slog.e(TAG, "Failed to load shortcuts from AndroidManifest.xml.", e); } } final int manifestShortcutSize = newManifestShortcutList == null ? 0 : newManifestShortcutList.size(); if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, String.format("Package %s has %d manifest shortcut(s), and %d share target(s)", getPackageName(), manifestShortcutSize, mShareTargets.size())); String.format( "Package %s has %d manifest shortcut(s), and %d share target(s)", getPackageName(), manifestShortcutSize, shareTargetSize)); } if (isNewApp && (manifestShortcutSize == 0)) { // If it's a new app, and it doesn't have manifest shortcuts, then nothing to do. Loading Loading @@ -1701,6 +1723,7 @@ class ShortcutPackage extends ShortcutPackageItem { @Override public void saveToXml(@NonNull TypedXmlSerializer out, boolean forBackup) throws IOException, XmlPullParserException { synchronized (mLock) { final int size = mShortcuts.size(); final int shareTargetSize = mShareTargets.size(); Loading @@ -1714,15 +1737,14 @@ class ShortcutPackage extends ShortcutPackageItem { ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount); ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime); if (!forBackup) { synchronized (mLock) { ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, (mIsAppSearchSchemaUpToDate) ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, mIsAppSearchSchemaUpToDate ? AppSearchShortcutInfo.SCHEMA_VERSION : 0); } } getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup); for (int j = 0; j < size; j++) { saveShortcut(out, mShortcuts.valueAt(j), forBackup, getPackageInfo().isBackupAllowed()); saveShortcut( out, mShortcuts.valueAt(j), forBackup, getPackageInfo().isBackupAllowed()); } if (!forBackup) { Loading @@ -1733,6 +1755,7 @@ class ShortcutPackage extends ShortcutPackageItem { out.endTag(null, TAG_ROOT); } } private void saveShortcut(TypedXmlSerializer out, ShortcutInfo si, boolean forBackup, boolean appSupportsBackup) Loading Loading @@ -1917,11 +1940,10 @@ class ShortcutPackage extends ShortcutPackageItem { synchronized (ret.mLock) { ret.mIsAppSearchSchemaUpToDate = ShortcutService.parseIntAttribute( parser, ATTR_SCHEMA_VERSON, 0) == AppSearchShortcutInfo.SCHEMA_VERSION; } ret.mApiCallCount = ShortcutService.parseIntAttribute(parser, ATTR_CALL_COUNT); ret.mLastResetTime = ShortcutService.parseLongAttribute(parser, ATTR_LAST_RESET); final int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT Loading Loading @@ -1950,6 +1972,7 @@ class ShortcutPackage extends ShortcutPackageItem { } ShortcutService.warnForInvalidTag(depth, tag); } } return ret; } Loading Loading @@ -2152,8 +2175,10 @@ class ShortcutPackage extends ShortcutPackageItem { @VisibleForTesting List<ShareTargetInfo> getAllShareTargetsForTest() { synchronized (mLock) { return new ArrayList<>(mShareTargets); } } @Override public void verifyStates() { Loading Loading @@ -2291,16 +2316,20 @@ class ShortcutPackage extends ShortcutPackageItem { private void saveShortcut(@NonNull final Collection<ShortcutInfo> shortcuts) { Objects.requireNonNull(shortcuts); synchronized (mLock) { for (ShortcutInfo si : shortcuts) { mShortcuts.put(si.getId(), si); } } } @Nullable List<ShortcutInfo> findAll(@NonNull final Collection<String> ids) { synchronized (mLock) { return ids.stream().map(mShortcuts::get) .filter(Objects::nonNull).collect(Collectors.toList()); } } private void forEachShortcut(@NonNull final Consumer<ShortcutInfo> cb) { forEachShortcutStopWhen(si -> { Loading @@ -2318,6 +2347,7 @@ class ShortcutPackage extends ShortcutPackageItem { private void forEachShortcutStopWhen( @NonNull final Function<ShortcutInfo, Boolean> cb) { synchronized (mLock) { for (int i = mShortcuts.size() - 1; i >= 0; i--) { final ShortcutInfo si = mShortcuts.valueAt(i); if (cb.apply(si)) { Loading @@ -2325,6 +2355,7 @@ class ShortcutPackage extends ShortcutPackageItem { } } } } @NonNull private AndroidFuture<AppSearchSession> setupSchema( Loading Loading @@ -2461,6 +2492,7 @@ class ShortcutPackage extends ShortcutPackageItem { }))); } @GuardedBy("mLock") @Override void scheduleSaveToAppSearchLocked() { final Map<String, ShortcutInfo> copy = new ArrayMap<>(mShortcuts); Loading