Merge "Restrict visibility of LOCUS_ID_SET events."
diff --git a/api/system-current.txt b/api/system-current.txt
index 59cc616..b3a2c13 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9,6 +9,7 @@
field public static final String ACCESS_DRM_CERTIFICATES = "android.permission.ACCESS_DRM_CERTIFICATES";
field @Deprecated public static final String ACCESS_FM_RADIO = "android.permission.ACCESS_FM_RADIO";
field public static final String ACCESS_INSTANT_APPS = "android.permission.ACCESS_INSTANT_APPS";
+ field public static final String ACCESS_LOCUS_ID_USAGE_STATS = "android.permission.ACCESS_LOCUS_ID_USAGE_STATS";
field public static final String ACCESS_MESSAGES_ON_ICC = "android.permission.ACCESS_MESSAGES_ON_ICC";
field public static final String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";
field public static final String ACCESS_MTP = "android.permission.ACCESS_MTP";
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d1031f4..57ba7fe 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4943,6 +4943,10 @@
<permission android:name="android.permission.ACCESS_TV_TUNER"
android:protectionLevel="signature|privileged" />
+ <!-- @hide @SystemApi Allows an application to access locusId events in the usage stats. -->
+ <permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"
+ android:protectionLevel="signature|appPredictor" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 772f6e4..cc2c92b 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -253,6 +253,9 @@
<!-- Permission required for CTS test - ShortcutManagerUsageTest -->
<uses-permission android:name="android.permission.ACCESS_SHORTCUTS"/>
+ <!-- Permission required for CTS test - UsageStatsTest -->
+ <uses-permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"/>
+
<!-- Permissions required to test ambient display. -->
<uses-permission android:name="android.permission.READ_DREAM_STATE"/>
<uses-permission android:name="android.permission.WRITE_DREAM_STATE"/>
diff --git a/services/core/java/android/app/usage/UsageStatsManagerInternal.java b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
index 5c2cbfa..442c9e5 100644
--- a/services/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -220,9 +220,13 @@
* result.
* @param hideShortcutInvocationEvents whether the {@link UsageEvents.Event#SHORTCUT_INVOCATION}
* events need to be excluded from the result.
+ * @param hideLocusIdEvents whether the {@link UsageEvents.Event#LOCUS_ID_SET}
+ * events need to be excluded from the result.
+ *
*/
public abstract UsageEvents queryEventsForUser(@UserIdInt int userId, long beginTime,
- long endTime, boolean obfuscateInstantApps, boolean hideShortcutInvocationEvents);
+ long endTime, boolean obfuscateInstantApps, boolean hideShortcutInvocationEvents,
+ boolean hideLocusIdEvents);
/**
* Used to persist the last time a job was run for this app, in order to make decisions later
diff --git a/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java b/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java
index 4e37f47..644c155 100644
--- a/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java
+++ b/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java
@@ -59,7 +59,7 @@
*/
boolean querySince(long sinceTime) {
UsageEvents usageEvents = mUsageStatsManagerInternal.queryEventsForUser(
- mUserId, sinceTime, System.currentTimeMillis(), false, false);
+ mUserId, sinceTime, System.currentTimeMillis(), false, false, false);
if (usageEvents == null) {
return false;
}
diff --git a/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java b/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java
index b273578..01d9dc0 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java
@@ -189,7 +189,7 @@
private void addUsageEvents(UsageEvents.Event... events) {
UsageEvents usageEvents = new UsageEvents(Arrays.asList(events), new String[]{});
when(mUsageStatsManagerInternal.queryEventsForUser(anyInt(), anyLong(), anyLong(),
- anyBoolean(), anyBoolean())).thenReturn(usageEvents);
+ anyBoolean(), anyBoolean(), anyBoolean())).thenReturn(usageEvents);
}
private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 1371481..420695d 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -491,6 +491,15 @@
return true; // hide by default if we can't verify visibility
}
+ private boolean shouldHideLocusIdEvents(int callingPid, int callingUid) {
+ if (callingUid == Process.SYSTEM_UID) {
+ return false;
+ }
+ return !(getContext().checkPermission(
+ android.Manifest.permission.ACCESS_LOCUS_ID_USAGE_STATS, callingPid, callingUid)
+ == PackageManager.PERMISSION_GRANTED);
+ }
+
private static void deleteRecursively(File f) {
File[] files = f.listFiles();
if (files != null) {
@@ -1030,7 +1039,8 @@
* Called by the Binder stub.
*/
UsageEvents queryEvents(int userId, long beginTime, long endTime,
- boolean shouldObfuscateInstantApps, boolean shouldHideShortcutInvocationEvents) {
+ boolean shouldObfuscateInstantApps, boolean shouldHideShortcutInvocationEvents,
+ boolean shouldHideLocusIdEvents) {
synchronized (mLock) {
if (!mUserUnlockedStates.get(userId)) {
Slog.w(TAG, "Failed to query events for locked user " + userId);
@@ -1042,7 +1052,7 @@
return null; // user was stopped or removed
}
return service.queryEvents(beginTime, endTime, shouldObfuscateInstantApps,
- shouldHideShortcutInvocationEvents);
+ shouldHideShortcutInvocationEvents, shouldHideLocusIdEvents);
}
}
@@ -1465,8 +1475,10 @@
try {
final boolean hideShortcutInvocationEvents = shouldHideShortcutInvocationEvents(
userId, callingPackage, callingPid, callingUid);
+ boolean shouldHideLocusIdEvents = shouldHideLocusIdEvents(callingPid, callingUid);
return UsageStatsService.this.queryEvents(userId, beginTime, endTime,
- obfuscateInstantApps, hideShortcutInvocationEvents);
+ obfuscateInstantApps, hideShortcutInvocationEvents,
+ shouldHideLocusIdEvents);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1513,8 +1525,10 @@
try {
final boolean hideShortcutInvocationEvents = shouldHideShortcutInvocationEvents(
userId, callingPackage, callingPid, callingUid);
+ boolean shouldHideLocusIdEvents = shouldHideLocusIdEvents(callingPid, callingUid);
return UsageStatsService.this.queryEvents(userId, beginTime, endTime,
- obfuscateInstantApps, hideShortcutInvocationEvents);
+ obfuscateInstantApps, hideShortcutInvocationEvents,
+ shouldHideLocusIdEvents);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -2131,9 +2145,11 @@
@Override
public UsageEvents queryEventsForUser(int userId, long beginTime, long endTime,
- boolean obfuscateInstantApps, boolean hideShortcutInvocationEvents) {
+ boolean obfuscateInstantApps, boolean shouldHideShortcutInvocationEvents,
+ boolean shouldHideLocusIdEvents) {
return UsageStatsService.this.queryEvents(
- userId, beginTime, endTime, obfuscateInstantApps, hideShortcutInvocationEvents);
+ userId, beginTime, endTime, obfuscateInstantApps,
+ shouldHideShortcutInvocationEvents, shouldHideLocusIdEvents);
}
@Override
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 4d71112..d9317ac 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -481,8 +481,8 @@
return queryStats(bucketType, beginTime, endTime, sEventStatsCombiner);
}
- UsageEvents queryEvents(final long beginTime, final long endTime,
- boolean obfuscateInstantApps, boolean hideShortcutInvocationEvents) {
+ UsageEvents queryEvents(final long beginTime, final long endTime, boolean obfuscateInstantApps,
+ boolean hideShortcutInvocationEvents, boolean hideLocusIdEvents) {
if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) {
return null;
}
@@ -504,6 +504,10 @@
&& event.mEventType == Event.SHORTCUT_INVOCATION) {
continue;
}
+ if (hideLocusIdEvents
+ && event.mEventType == Event.LOCUS_ID_SET) {
+ continue;
+ }
if (obfuscateInstantApps) {
event = event.getObfuscatedIfInstantApp();
}