From 0000000000000000000000000000000000000000 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 +++++++++++++++++++ .../server/pm/ShortcutPackage.java.rej | 16 +++++++++ .../android/server/pm/ShortcutService.java | 12 +++---- .../server/pm/ShortcutManagerTest2.java | 2 ++ 4 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 services/core/java/com/android/server/pm/ShortcutPackage.java.rej diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index 4bc3cdb730a3..dabbf375a5e2 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -19,6 +19,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.Person; +import android.app.usage.UsageStatsManagerInternal; import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; @@ -29,6 +30,7 @@ import android.content.pm.ShortcutManager; import android.content.res.Resources; import android.graphics.drawable.Icon; import android.os.PersistableBundle; +import android.os.SystemClock; import android.text.format.Formatter; import android.util.ArrayMap; import android.util.ArraySet; @@ -37,6 +39,7 @@ import android.util.Log; import android.util.Slog; import android.util.Xml; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; @@ -132,6 +135,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. */ @@ -156,6 +164,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, @@ -1545,6 +1556,30 @@ class ShortcutPackage extends ShortcutPackageItem { 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, DumpFilter filter) { pw.println(); diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java.rej b/services/core/java/com/android/server/pm/ShortcutPackage.java.rej new file mode 100644 index 000000000000..fee101cb86a7 --- /dev/null +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java.rej @@ -0,0 +1,16 @@ +diff a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java (rejected hunks) +@@ -28,12 +29,14 @@ + import android.content.pm.ShortcutManager; + 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.ArrayUtils; + import com.android.internal.util.Preconditions; diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 2b00ab5d6669..3d1fce98307d 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -338,7 +338,7 @@ public class ShortcutService extends IShortcutService.Stub { private CompressFormat mIconPersistFormat; private int mIconPersistQuality; - private int mSaveDelayMillis; + int mSaveDelayMillis; private final IPackageManager mIPackageManager; private final PackageManagerInternal mPackageManagerInternal; @@ -2591,10 +2591,11 @@ public class ShortcutService extends IShortcutService.Stub { 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", @@ -2603,12 +2604,7 @@ public class ShortcutService extends IShortcutService.Stub { } } - final long token = injectClearCallingIdentity(); - try { - mUsageStatsManagerInternal.reportShortcutUsage(packageName, shortcutId, userId); - } finally { - injectRestoreCallingIdentity(token); - } + ps.reportShortcutUsed(mUsageStatsManagerInternal, shortcutId); } @Override 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 088d693205c2..c509cb8baf0d 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java @@ -2130,6 +2130,8 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest { 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);