summaryrefslogtreecommitdiff
path: root/services/usage/java
diff options
context:
space:
mode:
authorVarun Shah <varunshah@google.com>2020-01-07 16:33:22 -0800
committerVarun Shah <varunshah@google.com>2020-01-29 11:28:22 -0800
commit01f6f26b544b188ac2f7e933e0222182eb1368ce (patch)
treeabe94c37f5285eea5a3c15f623efe771bb8a2e9e /services/usage/java
parent1b1bdd3642517cbb9b0986bbe0fe7cc2d5b8b49c (diff)
Restrict visibility of SHORTCUT_INVOCATION events.
UsageStats will not return SHORTCUT_INVOCATION events to callers of #queryEvents and #queryEventsForUser if they don't have visibility, as defined by ShortcutService#hasShortcutHostPermission. Also, add ACCESS_SHORTCUT permission to shell for CTS test and add the ShortcutManagerUsageTest to postsubmit. Bug: 145549490 Test: atest android.app.usage.cts.UsageStatsTest Test: atest android.content.pm.cts.shortcutmanager.ShortcutManagerUsageTest Change-Id: I2a69f061c35c31035a5d0381ab2f42029ec4fffc
Diffstat (limited to 'services/usage/java')
-rw-r--r--services/usage/java/com/android/server/usage/TEST_MAPPING8
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java50
-rw-r--r--services/usage/java/com/android/server/usage/UserUsageStatsService.java6
3 files changed, 54 insertions, 10 deletions
diff --git a/services/usage/java/com/android/server/usage/TEST_MAPPING b/services/usage/java/com/android/server/usage/TEST_MAPPING
index 7b53d09fdbef..523d5f95c6f3 100644
--- a/services/usage/java/com/android/server/usage/TEST_MAPPING
+++ b/services/usage/java/com/android/server/usage/TEST_MAPPING
@@ -28,6 +28,14 @@
"include-filter": "android.app.usage.cts.UsageStatsTest"
}
]
+ },
+ {
+ "name": "CtsShortcutManagerTestCases",
+ "options": [
+ {
+ "include-filter": "android.content.pm.cts.shortcutmanager.ShortcutManagerUsageTest"
+ }
+ ]
}
]
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 9a18f8cd3a46..14852d0f4161 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -60,6 +60,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
+import android.content.pm.ShortcutServiceInternal;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.os.Binder;
@@ -156,6 +157,8 @@ public class UsageStatsService extends SystemService implements
PackageManagerInternal mPackageManagerInternal;
// Do not use directly. Call getDpmInternal() instead
DevicePolicyManagerInternal mDpmInternal;
+ // Do not use directly. Call getShortcutServiceInternal() instead
+ ShortcutServiceInternal mShortcutServiceInternal;
private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>();
private final SparseBooleanArray mUserUnlockedStates = new SparseBooleanArray();
@@ -267,6 +270,8 @@ public class UsageStatsService extends SystemService implements
if (phase == PHASE_SYSTEM_SERVICES_READY) {
// initialize mDpmInternal
getDpmInternal();
+ // initialize mShortcutServiceInternal
+ getShortcutServiceInternal();
if (ENABLE_KERNEL_UPDATES && KERNEL_COUNTER_FILE.exists()) {
try {
@@ -400,6 +405,13 @@ public class UsageStatsService extends SystemService implements
return mDpmInternal;
}
+ private ShortcutServiceInternal getShortcutServiceInternal() {
+ if (mShortcutServiceInternal == null) {
+ mShortcutServiceInternal = LocalServices.getService(ShortcutServiceInternal.class);
+ }
+ return mShortcutServiceInternal;
+ }
+
private void readUsageSourceSetting() {
synchronized (mLock) {
mUsageSource = Settings.Global.getInt(getContext().getContentResolver(),
@@ -469,6 +481,16 @@ public class UsageStatsService extends SystemService implements
return !mPackageManagerInternal.canAccessInstantApps(callingUid, userId);
}
+ private boolean shouldHideShortcutInvocationEvents(int userId, String callingPackage,
+ int callingPid, int callingUid) {
+ final ShortcutServiceInternal shortcutServiceInternal = getShortcutServiceInternal();
+ if (shortcutServiceInternal != null) {
+ return !shortcutServiceInternal.hasShortcutHostPermission(userId, callingPackage,
+ callingPid, callingUid);
+ }
+ return true; // hide by default if we can't verify visibility
+ }
+
private static void deleteRecursively(File f) {
File[] files = f.listFiles();
if (files != null) {
@@ -1008,7 +1030,7 @@ public class UsageStatsService extends SystemService implements
* Called by the Binder stub.
*/
UsageEvents queryEvents(int userId, long beginTime, long endTime,
- boolean shouldObfuscateInstantApps) {
+ boolean shouldObfuscateInstantApps, boolean shouldHideShortcutInvocationEvents) {
synchronized (mLock) {
if (!mUserUnlockedStates.get(userId)) {
Slog.w(TAG, "Failed to query events for locked user " + userId);
@@ -1019,7 +1041,8 @@ public class UsageStatsService extends SystemService implements
if (service == null) {
return null; // user was stopped or removed
}
- return service.queryEvents(beginTime, endTime, shouldObfuscateInstantApps);
+ return service.queryEvents(beginTime, endTime, shouldObfuscateInstantApps,
+ shouldHideShortcutInvocationEvents);
}
}
@@ -1418,14 +1441,18 @@ public class UsageStatsService extends SystemService implements
return null;
}
+ final int userId = UserHandle.getCallingUserId();
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(
- Binder.getCallingUid(), UserHandle.getCallingUserId());
+ callingUid, userId);
- final int userId = UserHandle.getCallingUserId();
final long token = Binder.clearCallingIdentity();
try {
+ final boolean hideShortcutInvocationEvents = shouldHideShortcutInvocationEvents(
+ userId, callingPackage, callingPid, callingUid);
return UsageStatsService.this.queryEvents(userId, beginTime, endTime,
- obfuscateInstantApps);
+ obfuscateInstantApps, hideShortcutInvocationEvents);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1456,19 +1483,24 @@ public class UsageStatsService extends SystemService implements
return null;
}
- if (userId != UserHandle.getCallingUserId()) {
+ final int callingUserId = UserHandle.getCallingUserId();
+ if (userId != callingUserId) {
getContext().enforceCallingPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL,
"No permission to query usage stats for this user");
}
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(
- Binder.getCallingUid(), UserHandle.getCallingUserId());
+ callingUid, callingUserId);
final long token = Binder.clearCallingIdentity();
try {
+ final boolean hideShortcutInvocationEvents = shouldHideShortcutInvocationEvents(
+ userId, callingPackage, callingPid, callingUid);
return UsageStatsService.this.queryEvents(userId, beginTime, endTime,
- obfuscateInstantApps);
+ obfuscateInstantApps, hideShortcutInvocationEvents);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -2087,7 +2119,7 @@ public class UsageStatsService extends SystemService implements
public UsageEvents queryEventsForUser(int userId, long beginTime, long endTime,
boolean shouldObfuscateInstantApps) {
return UsageStatsService.this.queryEvents(
- userId, beginTime, endTime, shouldObfuscateInstantApps);
+ userId, beginTime, endTime, shouldObfuscateInstantApps, false);
}
@Override
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 179b6490a7fd..4d711128da76 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -482,7 +482,7 @@ class UserUsageStatsService {
}
UsageEvents queryEvents(final long beginTime, final long endTime,
- boolean obfuscateInstantApps) {
+ boolean obfuscateInstantApps, boolean hideShortcutInvocationEvents) {
if (!validRange(checkAndGetTimeLocked(), beginTime, endTime)) {
return null;
}
@@ -500,6 +500,10 @@ class UserUsageStatsService {
}
Event event = stats.events.get(i);
+ if (hideShortcutInvocationEvents
+ && event.mEventType == Event.SHORTCUT_INVOCATION) {
+ continue;
+ }
if (obfuscateInstantApps) {
event = event.getObfuscatedIfInstantApp();
}