diff options
| author | 2017-05-15 09:29:34 -0700 | |
|---|---|---|
| committer | 2017-05-16 12:33:43 -0700 | |
| commit | ad623015a119efe9b63f594af9c4703f40a0c27b (patch) | |
| tree | c155e3ae4f41ce3f5798ad3117925c2e83195487 /services/usage/java | |
| parent | 28f0fd7a2d5b26a728d72984a8cf69ac0fcc4400 (diff) | |
Restrict access to instant app data in usage stats
- Events are obfuscated based on whether the app was instant or not at
the time each event was logged.
- UsageStats are obfuscated based on whether each app is instant or
not at the moment.
Bug 38202133
Test: Manual test using UsageStatsTest and instant apps
Change-Id: I3c74309196b88d010d317cb0dd6749bf4624e876
Diffstat (limited to 'services/usage/java')
3 files changed, 69 insertions, 17 deletions
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 4ba457d211a3..0de3c7c75016 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -39,6 +39,7 @@ import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ParceledListSlice; import android.content.pm.UserInfo; @@ -80,6 +81,7 @@ import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; +import com.android.server.LocalServices; import com.android.server.SystemService; import java.io.File; @@ -137,6 +139,7 @@ public class UsageStatsService extends SystemService implements AppOpsManager mAppOps; UserManager mUserManager; PackageManager mPackageManager; + PackageManagerInternal mPackageManagerInternal; AppWidgetManager mAppWidgetManager; IDeviceIdleController mDeviceIdleController; private DisplayManager mDisplayManager; @@ -179,6 +182,7 @@ public class UsageStatsService extends SystemService implements mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); mPackageManager = getContext().getPackageManager(); + mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mHandler = new H(BackgroundThread.get().getLooper()); File systemDataDir = new File(Environment.getDataDirectory(), "system"); @@ -407,6 +411,10 @@ public class UsageStatsService extends SystemService implements } } + private boolean shouldObfuscateInstantAppsForCaller(int callingUid) { + return !mPackageManagerInternal.canAccessInstantApps(callingUid); + } + void clearAppIdleForPackage(String packageName, int userId) { synchronized (mAppIdleLock) { mAppIdleHistory.clearUsage(packageName, userId); @@ -704,6 +712,11 @@ public class UsageStatsService extends SystemService implements final long elapsedRealtime = SystemClock.elapsedRealtime(); convertToSystemTimeLocked(event); + if (event.getPackageName() != null + && mPackageManagerInternal.isPackageEphemeral(userId, event.getPackageName())) { + event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP; + } + final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId, timeNow); service.reportEvent(event); @@ -807,7 +820,8 @@ public class UsageStatsService extends SystemService implements /** * Called by the Binder stub. */ - List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime) { + List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime, + boolean obfuscateInstantApps) { synchronized (mLock) { final long timeNow = checkAndGetTimeLocked(); if (!validRange(timeNow, beginTime, endTime)) { @@ -816,7 +830,20 @@ public class UsageStatsService extends SystemService implements final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId, timeNow); - return service.queryUsageStats(bucketType, beginTime, endTime); + List<UsageStats> list = service.queryUsageStats(bucketType, beginTime, endTime); + + // Mangle instant app names *using their current state (not whether they were ephemeral + // when the data was recorded)*. + if (obfuscateInstantApps) { + for (int i = list.size() - 1; i >= 0; i--) { + final UsageStats stats = list.get(i); + if (mPackageManagerInternal.isPackageEphemeral(userId, stats.mPackageName)) { + list.set(i, stats.getObfuscatedForInstantApp()); + } + } + } + + return list; } } @@ -840,7 +867,8 @@ public class UsageStatsService extends SystemService implements /** * Called by the Binder stub. */ - UsageEvents queryEvents(int userId, long beginTime, long endTime) { + UsageEvents queryEvents(int userId, long beginTime, long endTime, + boolean shouldObfuscateInstantApps) { synchronized (mLock) { final long timeNow = checkAndGetTimeLocked(); if (!validRange(timeNow, beginTime, endTime)) { @@ -849,7 +877,7 @@ public class UsageStatsService extends SystemService implements final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId, timeNow); - return service.queryEvents(beginTime, endTime); + return service.queryEvents(beginTime, endTime, shouldObfuscateInstantApps); } } @@ -884,10 +912,15 @@ public class UsageStatsService extends SystemService implements } } - boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime) { + boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime, + boolean shouldObfuscateInstantApps) { if (isParoledOrCharging()) { return false; } + if (shouldObfuscateInstantApps && + mPackageManagerInternal.isPackageEphemeral(userId, packageName)) { + return false; + } return isAppIdleFiltered(packageName, getAppId(packageName), userId, elapsedRealtime); } @@ -1353,11 +1386,14 @@ public class UsageStatsService extends SystemService implements return null; } + final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( + Binder.getCallingUid()); + final int userId = UserHandle.getCallingUserId(); final long token = Binder.clearCallingIdentity(); try { final List<UsageStats> results = UsageStatsService.this.queryUsageStats( - userId, bucketType, beginTime, endTime); + userId, bucketType, beginTime, endTime, obfuscateInstantApps); if (results != null) { return new ParceledListSlice<>(results); } @@ -1395,10 +1431,14 @@ public class UsageStatsService extends SystemService implements return null; } + final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( + Binder.getCallingUid()); + final int userId = UserHandle.getCallingUserId(); final long token = Binder.clearCallingIdentity(); try { - return UsageStatsService.this.queryEvents(userId, beginTime, endTime); + return UsageStatsService.this.queryEvents(userId, beginTime, endTime, + obfuscateInstantApps); } finally { Binder.restoreCallingIdentity(token); } @@ -1412,10 +1452,12 @@ public class UsageStatsService extends SystemService implements } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } + final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( + Binder.getCallingUid()); final long token = Binder.clearCallingIdentity(); try { return UsageStatsService.this.isAppIdleFilteredOrParoled(packageName, userId, - SystemClock.elapsedRealtime()); + SystemClock.elapsedRealtime(), obfuscateInstantApps); } finally { Binder.restoreCallingIdentity(token); } @@ -1647,9 +1689,10 @@ public class UsageStatsService extends SystemService implements @Override public List<UsageStats> queryUsageStatsForUser( - int userId, int intervalType, long beginTime, long endTime) { + int userId, int intervalType, long beginTime, long endTime, + boolean obfuscateInstantApps) { return UsageStatsService.this.queryUsageStats( - userId, intervalType, beginTime, endTime); + userId, intervalType, beginTime, endTime, obfuscateInstantApps); } } } diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java index 96f3305e2538..cc53a9cc0b70 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java +++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java @@ -26,7 +26,10 @@ import android.app.usage.TimeSparseArray; import android.app.usage.UsageEvents; import android.app.usage.UsageStats; import android.content.res.Configuration; +import android.text.TextUtils; import android.util.ArrayMap; +import android.util.Log; +import android.util.LogWriter; import java.io.IOException; import java.net.ProtocolException; @@ -35,6 +38,8 @@ import java.net.ProtocolException; * UsageStats reader/writer for version 1 of the XML format. */ final class UsageStatsXmlV1 { + private static final String TAG = "UsageStatsXmlV1"; + private static final String PACKAGES_TAG = "packages"; private static final String PACKAGE_TAG = "package"; @@ -51,6 +56,7 @@ final class UsageStatsXmlV1 { // Attributes private static final String PACKAGE_ATTR = "package"; + private static final String FLAGS_ATTR = "flags"; private static final String CLASS_ATTR = "class"; private static final String TOTAL_TIME_ACTIVE_ATTR = "timeActive"; private static final String COUNT_ATTR = "count"; @@ -70,7 +76,6 @@ final class UsageStatsXmlV1 { if (pkg == null) { throw new ProtocolException("no " + PACKAGE_ATTR + " attribute present"); } - final UsageStats stats = statsOut.getOrCreateUsageStats(pkg); // Apply the offset to the beginTime to find the absolute time. @@ -149,11 +154,12 @@ final class UsageStatsXmlV1 { if (packageName == null) { throw new ProtocolException("no " + PACKAGE_ATTR + " attribute present"); } - final String className = XmlUtils.readStringAttribute(parser, CLASS_ATTR); final UsageEvents.Event event = statsOut.buildEvent(packageName, className); + event.mFlags = XmlUtils.readIntAttribute(parser, FLAGS_ATTR, 0); + // Apply the offset to the beginTime to find the absolute time of this event. event.mTimeStamp = statsOut.beginTime + XmlUtils.readLongAttribute(parser, TIME_ATTR); @@ -256,6 +262,7 @@ final class UsageStatsXmlV1 { if (event.mClass != null) { XmlUtils.writeStringAttribute(xml, CLASS_ATTR, event.mClass); } + XmlUtils.writeIntAttribute(xml, FLAGS_ATTR, event.mFlags); XmlUtils.writeIntAttribute(xml, TYPE_ATTR, event.mEventType); switch (event.mEventType) { diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java index 8d335a51bb55..0abbb82a68a1 100644 --- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java @@ -19,11 +19,8 @@ package com.android.server.usage; import android.app.usage.ConfigurationStats; import android.app.usage.TimeSparseArray; import android.app.usage.UsageEvents; -import android.app.usage.UsageEvents.Event; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; import android.content.res.Configuration; import android.os.SystemClock; import android.content.Context; @@ -312,7 +309,8 @@ class UserUsageStatsService { return queryStats(bucketType, beginTime, endTime, sConfigStatsCombiner); } - UsageEvents queryEvents(final long beginTime, final long endTime) { + UsageEvents queryEvents(final long beginTime, final long endTime, + boolean obfuscateInstantApps) { final ArraySet<String> names = new ArraySet<>(); List<UsageEvents.Event> results = queryStats(UsageStatsManager.INTERVAL_DAILY, beginTime, endTime, new StatCombiner<UsageEvents.Event>() { @@ -334,7 +332,10 @@ class UserUsageStatsService { return; } - final UsageEvents.Event event = stats.events.valueAt(i); + UsageEvents.Event event = stats.events.valueAt(i); + if (obfuscateInstantApps) { + event = event.getObfuscatedIfInstantApp(); + } names.add(event.mPackage); if (event.mClass != null) { names.add(event.mClass); @@ -586,6 +587,7 @@ class UserUsageStatsService { if (event.mShortcutId != null) { pw.printPair("shortcutId", event.mShortcutId); } + pw.printHexPair("flags", event.mFlags); pw.println(); } pw.decreaseIndent(); |