diff options
| author | 2023-08-23 17:19:46 +0000 | |
|---|---|---|
| committer | 2023-08-25 23:12:12 +0000 | |
| commit | ad842da783bf26056a7ab040fabaf7e29d98dda7 (patch) | |
| tree | d442404a53a8621e97f2cd6831c0c0dda288bd35 | |
| parent | 1983fd773a2b76ed52757d51675b077f278f8468 (diff) | |
Update certain APIs to require the REPORT_USAGE_STATS permission.
Add requirement of either being the system or having the
REPORT_USAGE_STATS permission in order to call any report events related
APIs. This includes the reportChooserSelection and reportUserInteraction
APIs.
Also add the permission to Shell so the APIs can be tested via CTS.
Bug: 296056771
Bug: 218679369
Test: atest CtsUsageStatsTest
Change-Id: I3b28e00b9da73cd4bc051f3c5e03e29a734a1df0
| -rw-r--r-- | core/java/android/app/usage/UsageStatsManager.java | 2 | ||||
| -rw-r--r-- | packages/Shell/AndroidManifest.xml | 1 | ||||
| -rw-r--r-- | services/usage/java/com/android/server/usage/UsageStatsService.java | 32 |
3 files changed, 27 insertions, 8 deletions
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index ecf164394c31..2a10ed181576 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -1106,6 +1106,7 @@ public final class UsageStatsManager { * <p><em>This method is only for use by the system</em> * @hide */ + @RequiresPermission(android.Manifest.permission.REPORT_USAGE_STATS) public void reportUserInteraction(@NonNull String packageName, int userId) { try { mService.reportUserInteraction(packageName, userId); @@ -1396,6 +1397,7 @@ public final class UsageStatsManager { * {@link UsageEvents} * @hide */ + @RequiresPermission(android.Manifest.permission.REPORT_USAGE_STATS) public void reportChooserSelection(String packageName, int userId, String contentType, String[] annotations, String action) { try { diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 323f65f4f066..0364ede37f54 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -167,6 +167,7 @@ <uses-permission android:name="android.permission.FORCE_BACK" /> <uses-permission android:name="android.permission.BATTERY_STATS" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> + <uses-permission android:name="android.permission.REPORT_USAGE_STATS" /> <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" /> <uses-permission android:name="android.permission.INJECT_EVENTS" /> <uses-permission android:name="android.permission.RETRIEVE_WINDOW_CONTENT" /> diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index e738d292a0f9..90b798c3cb90 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -2061,6 +2061,15 @@ public class UsageStatsService extends SystemService implements return mode == AppOpsManager.MODE_ALLOWED; } + private boolean canReportUsageStats() { + if (isCallingUidSystem()) { + return true; // System UID can always report UsageStats + } + + return getContext().checkCallingPermission(Manifest.permission.REPORT_USAGE_STATS) + == PackageManager.PERMISSION_GRANTED; + } + private boolean hasObserverPermission() { final int callingUid = Binder.getCallingUid(); DevicePolicyManagerInternal dpmInternal = getDpmInternal(); @@ -2541,14 +2550,19 @@ public class UsageStatsService extends SystemService implements @Override public void reportChooserSelection(@NonNull String packageName, int userId, @NonNull String contentType, String[] annotations, @NonNull String action) { - if (packageName == null) { - throw new IllegalArgumentException("Package selection must not be null."); - } - // A valid contentType and action must be provided for chooser selection events. - if (contentType == null || contentType.isBlank() - || action == null || action.isBlank()) { + // A valid package name, content type, and action must be provided for these events + Objects.requireNonNull(packageName); + Objects.requireNonNull(contentType); + Objects.requireNonNull(action); + if (contentType.isBlank() || action.isBlank()) { return; } + + if (!canReportUsageStats()) { + throw new SecurityException("Only the system or holders of the REPORT_USAGE_STATS" + + " permission are allowed to call reportChooserSelection"); + } + // Verify if this package exists before reporting an event for it. if (mPackageManagerInternal.getPackageUid(packageName, 0, userId) < 0) { Slog.w(TAG, "Event report user selecting an invalid package"); @@ -2566,9 +2580,11 @@ public class UsageStatsService extends SystemService implements @Override public void reportUserInteraction(String packageName, int userId) { Objects.requireNonNull(packageName); - if (!isCallingUidSystem()) { - throw new SecurityException("Only system is allowed to call reportUserInteraction"); + if (!canReportUsageStats()) { + throw new SecurityException("Only the system or holders of the REPORT_USAGE_STATS" + + " permission are allowed to call reportUserInteraction"); } + final Event event = new Event(USER_INTERACTION, SystemClock.elapsedRealtime()); event.mPackage = packageName; reportEventOrAddToQueue(userId, event); |