summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Varun Shah <varunshah@google.com> 2023-08-23 17:19:46 +0000
committer Varun Shah <varunshah@google.com> 2023-08-25 23:12:12 +0000
commitad842da783bf26056a7ab040fabaf7e29d98dda7 (patch)
treed442404a53a8621e97f2cd6831c0c0dda288bd35
parent1983fd773a2b76ed52757d51675b077f278f8468 (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.java2
-rw-r--r--packages/Shell/AndroidManifest.xml1
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java32
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);