From 42e379fa4967a4841931310b9308e5ff66e2be00 Mon Sep 17 00:00:00 2001 From: Pinyao Ting Date: Thu, 30 Nov 2023 23:12:39 +0000 Subject: [PATCH] Added throttle when reporting shortcut usage Bug: 304290201 Test: manual (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:76121eb73d4c40829d5513b073871333520fe0a2) Merged-In: I96370cbd4f6a55f894c1a93307e5f82dfd394652 Change-Id: I96370cbd4f6a55f894c1a93307e5f82dfd394652 --- .../android/server/pm/ShortcutPackage.java | 35 +++++++++++++++++++ .../android/server/pm/ShortcutService.java | 12 +++---- .../server/pm/ShortcutManagerTest2.java | 2 ++ 3 files changed, 41 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 38d69ed287e1c..b8d0120f3db62 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -19,17 +19,20 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.ComponentName; +import android.app.usage.UsageStatsManagerInternal; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.ShortcutInfo; import android.content.res.Resources; import android.os.PersistableBundle; +import android.os.SystemClock; import android.text.format.Formatter; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.Slog; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; @@ -103,6 +106,11 @@ class ShortcutPackage extends ShortcutPackageItem { private static final String KEY_BITMAPS = "bitmaps"; private static final String KEY_BITMAP_BYTES = "bitmapBytes"; + @VisibleForTesting + public static final int REPORT_USAGE_BUFFER_SIZE = 3; + + private final Object mLock = new Object(); + /** * All the shortcuts from the package, keyed on IDs. */ @@ -122,6 +130,9 @@ class ShortcutPackage extends ShortcutPackageItem { private long mLastKnownForegroundElapsedTime; + @GuardedBy("mLock") + private List mLastReportedTime = new ArrayList<>(); + private ShortcutPackage(ShortcutUser shortcutUser, int packageUserId, String packageName, ShortcutPackageInfo spi) { super(shortcutUser, packageUserId, packageName, @@ -1144,6 +1155,30 @@ public boolean hasNonManifestShortcuts() { return false; } + void reportShortcutUsed(@NonNull final UsageStatsManagerInternal usageStatsManagerInternal, + @NonNull final String shortcutId) { + synchronized (mLock) { + final long currentTS = SystemClock.elapsedRealtime(); + final ShortcutService s = mShortcutUser.mService; + if (mLastReportedTime.isEmpty() + || mLastReportedTime.size() < REPORT_USAGE_BUFFER_SIZE) { + mLastReportedTime.add(currentTS); + } else if (currentTS - mLastReportedTime.get(0) > s.mSaveDelayMillis) { + mLastReportedTime.remove(0); + mLastReportedTime.add(currentTS); + } else { + return; + } + final long token = s.injectClearCallingIdentity(); + try { + usageStatsManagerInternal.reportShortcutUsage(getPackageName(), shortcutId, + getUser().getUserId()); + } finally { + s.injectRestoreCallingIdentity(token); + } + } + } + public void dump(@NonNull PrintWriter pw, @NonNull String prefix) { pw.println(); diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 944f75345df6f..02b923384a836 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -290,7 +290,7 @@ public boolean test(PackageInfo pi) { private CompressFormat mIconPersistFormat; private int mIconPersistQuality; - private int mSaveDelayMillis; + int mSaveDelayMillis; private final IPackageManager mIPackageManager; private final PackageManagerInternal mPackageManagerInternal; @@ -2041,10 +2041,11 @@ public void reportShortcutUsed(String packageName, String shortcutId, int userId shortcutId, packageName, userId)); } + final ShortcutPackage ps; synchronized (mLock) { throwIfUserLockedL(userId); - final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId); + ps = getPackageShortcutsForPublisherLocked(packageName, userId); if (ps.findShortcutById(shortcutId) == null) { Log.w(TAG, String.format("reportShortcutUsed: package %s doesn't have shortcut %s", @@ -2053,12 +2054,7 @@ public void reportShortcutUsed(String packageName, String shortcutId, int userId } } - final long token = injectClearCallingIdentity(); - try { - mUsageStatsManagerInternal.reportShortcutUsage(packageName, shortcutId, userId); - } finally { - injectRestoreCallingIdentity(token); - } + ps.reportShortcutUsed(mUsageStatsManagerInternal, shortcutId); } /** diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java index d25923c019cac..149037df2ff16 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java @@ -1799,6 +1799,8 @@ public void testThrottling_resetByInternalCall() throws Exception { public void testReportShortcutUsed() { mRunningUsers.put(USER_10, true); + mService.updateConfigurationLocked( + ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=1"); runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { reset(mMockUsageStatsManagerInternal);