From 7622d6da0e0e7ddc2893249bd489da7b140b437f Mon Sep 17 00:00:00 2001 From: Pinyao Ting Date: Fri, 2 Dec 2022 17:07:51 -0800 Subject: Implement a global maximum on number of shortcuts an app can publish Currently there is a limit on the number of shortcuts an app can publish in respect to each launcher activity. This CL further implements a global maximum of total number of shortcuts an app can publish to mitigate from any potential system health issue. Bug: 250576066 Test: manual Change-Id: I94b4e39475c7585ec67f15df1256fdf0b65f3bec Merged-In: I94b4e39475c7585ec67f15df1256fdf0b65f3bec --- .../com/android/server/pm/ShortcutPackage.java | 8 +++- .../com/android/server/pm/ShortcutService.java | 49 ++++++++++++++++++---- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index b4bd086af272..e99539e7ddb0 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -1479,9 +1479,15 @@ class ShortcutPackage extends ShortcutPackageItem { } // Then make sure none of the activities have more than the max number of shortcuts. + int total = 0; for (int i = counts.size() - 1; i >= 0; i--) { - service.enforceMaxActivityShortcuts(counts.valueAt(i)); + int count = counts.valueAt(i); + service.enforceMaxActivityShortcuts(count); + total += count; } + + // Finally make sure that the app doesn't have more than the max number of shortcuts. + service.enforceMaxAppShortcuts(total); } /** diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 62d6717e847a..7e5613fd892f 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -179,6 +179,9 @@ public class ShortcutService extends IShortcutService.Stub { @VisibleForTesting static final int DEFAULT_MAX_SHORTCUTS_PER_ACTIVITY = 15; + @VisibleForTesting + static final int DEFAULT_MAX_SHORTCUTS_PER_APP = 60; + @VisibleForTesting static final int DEFAULT_MAX_ICON_DIMENSION_DP = 96; @@ -253,6 +256,11 @@ public class ShortcutService extends IShortcutService.Stub { */ String KEY_MAX_SHORTCUTS = "max_shortcuts"; + /** + * Key name for the max dynamic shortcuts per app. (int) + */ + String KEY_MAX_SHORTCUTS_PER_APP = "max_shortcuts_per_app"; + /** * Key name for icon compression quality, 0-100. */ @@ -324,10 +332,15 @@ public class ShortcutService extends IShortcutService.Stub { private final SparseArray mShortcutNonPersistentUsers = new SparseArray<>(); + /** + * Max number of dynamic + manifest shortcuts that each activity can have at a time. + */ + private int mMaxShortcutsPerActivity; + /** * Max number of dynamic + manifest shortcuts that each application can have at a time. */ - private int mMaxShortcuts; + private int mMaxShortcutsPerApp; /** * Max number of updating API calls that each application can make during the interval. @@ -787,9 +800,12 @@ public class ShortcutService extends IShortcutService.Stub { mMaxUpdatesPerInterval = Math.max(0, (int) parser.getLong( ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL, DEFAULT_MAX_UPDATES_PER_INTERVAL)); - mMaxShortcuts = Math.max(0, (int) parser.getLong( + mMaxShortcutsPerActivity = Math.max(0, (int) parser.getLong( ConfigConstants.KEY_MAX_SHORTCUTS, DEFAULT_MAX_SHORTCUTS_PER_ACTIVITY)); + mMaxShortcutsPerApp = Math.max(0, (int) parser.getLong( + ConfigConstants.KEY_MAX_SHORTCUTS_PER_APP, DEFAULT_MAX_SHORTCUTS_PER_APP)); + final int iconDimensionDp = Math.max(1, injectIsLowRamDevice() ? (int) parser.getLong( ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM, @@ -1745,16 +1761,33 @@ public class ShortcutService extends IShortcutService.Stub { * {@link #getMaxActivityShortcuts()}. */ void enforceMaxActivityShortcuts(int numShortcuts) { - if (numShortcuts > mMaxShortcuts) { + if (numShortcuts > mMaxShortcutsPerActivity) { throw new IllegalArgumentException("Max number of dynamic shortcuts exceeded"); } } + /** + * @throws IllegalArgumentException if {@code numShortcuts} is bigger than + * {@link #getMaxAppShortcuts()}. + */ + void enforceMaxAppShortcuts(int numShortcuts) { + if (numShortcuts > mMaxShortcutsPerApp) { + throw new IllegalArgumentException("Max number of dynamic shortcuts per app exceeded"); + } + } + /** * Return the max number of dynamic + manifest shortcuts for each launcher icon. */ int getMaxActivityShortcuts() { - return mMaxShortcuts; + return mMaxShortcutsPerActivity; + } + + /** + * Return the max number of dynamic + manifest shortcuts for each launcher icon. + */ + int getMaxAppShortcuts() { + return mMaxShortcutsPerApp; } /** @@ -2213,6 +2246,8 @@ public class ShortcutService extends IShortcutService.Stub { ps.ensureNotImmutable(shortcut.getId(), /*ignoreInvisible=*/ true); fillInDefaultActivity(Arrays.asList(shortcut)); + enforceMaxAppShortcuts(ps.getShortcutCount()); + if (!shortcut.hasRank()) { shortcut.setRank(0); } @@ -2771,7 +2806,7 @@ public class ShortcutService extends IShortcutService.Stub { throws RemoteException { verifyCaller(packageName, userId); - return mMaxShortcuts; + return mMaxShortcutsPerActivity; } @Override @@ -4823,7 +4858,7 @@ public class ShortcutService extends IShortcutService.Stub { pw.print(" maxUpdatesPerInterval: "); pw.println(mMaxUpdatesPerInterval); pw.print(" maxShortcutsPerActivity: "); - pw.println(mMaxShortcuts); + pw.println(mMaxShortcutsPerActivity); pw.println(); mStatLogger.dump(pw, " "); @@ -5311,7 +5346,7 @@ public class ShortcutService extends IShortcutService.Stub { @VisibleForTesting int getMaxShortcutsForTest() { - return mMaxShortcuts; + return mMaxShortcutsPerActivity; } @VisibleForTesting -- cgit v1.2.3-59-g8ed1b