diff options
author | Varun Shah <varunshah@google.com> | 2020-01-07 16:33:22 -0800 |
---|---|---|
committer | Varun Shah <varunshah@google.com> | 2020-01-29 11:28:22 -0800 |
commit | 01f6f26b544b188ac2f7e933e0222182eb1368ce (patch) | |
tree | abe94c37f5285eea5a3c15f623efe771bb8a2e9e | |
parent | 1b1bdd3642517cbb9b0986bbe0fe7cc2d5b8b49c (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
5 files changed, 59 insertions, 10 deletions
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 133b1aed68f1..0697b3ff6612 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -363,6 +363,8 @@ applications that come with the platform <permission name="android.permission.WRITE_DREAM_STATE" /> <!-- Permission required to test lights control APIs. --> <permission name="android.permission.CONTROL_DEVICE_LIGHTS" /> + <!-- Permission required for ShortcutManagerUsageTest CTS test. --> + <permission name="android.permission.ACCESS_SHORTCUTS"/> </privapp-permissions> <privapp-permissions package="com.android.statementservice"> diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 0f3585303ed8..7d2b85dc2571 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -240,6 +240,9 @@ <!-- Allows setting brightness from the shell --> <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS"/> + <!-- Permission required for CTS test - ShortcutManagerUsageTest --> + <uses-permission android:name="android.permission.ACCESS_SHORTCUTS"/> + <!-- 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/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(); } |