Loading core/java/android/app/usage/NetworkStatsManager.java +6 −4 Original line number Diff line number Diff line Loading @@ -52,10 +52,12 @@ import android.util.Log; * {@link NetworkStats.Bucket#STATE_ALL} and all Bucket's roaming is going to be * {@link NetworkStats.Bucket#ROAMING_ALL}. * <p /> * <b>NOTE:</b> Accessing stats for apps other than the calling app requires the permission * {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, which is a system-level permission and * will not be granted to third-party apps. However, declaring the permission implies intention to * use the API and the user of the device can grant permission through the Settings application. * <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the * calling app requires the permission {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, * which is a system-level permission and will not be granted to third-party apps. However, * declaring the permission implies intention to use the API and the user of the device can grant * permission through the Settings application. * <p /> * Profile owner apps are automatically granted permission to query data on the profile they manage * (that is, for any query except {@link #querySummaryForDevice}). Device owner apps and carrier- * privileged apps likewise get access to usage data for all users on the device. Loading services/core/java/com/android/server/net/NetworkStatsAccess.java +22 −6 Original line number Diff line number Diff line Loading @@ -66,13 +66,24 @@ public final class NetworkStatsAccess { * * <p>Granted to: * <ul> * <li>Profile owners. * </ul> */ int USER = 1; /** * Access level for apps which can access usage summary of device. Device summary includes * usage by apps running in any profiles/users, however this access level does not * allow querying usage of individual apps running in other profiles/users. * * <p>Granted to: * <ul> * <li>Apps with the PACKAGE_USAGE_STATS permission granted. Note that this is an AppOps bit * so it is not necessarily sufficient to declare this in the manifest. * <li>Apps with the (signature/privileged) READ_NETWORK_USAGE_HISTORY permission. * <li>Profile owners. * </ul> */ int USER = 1; int DEVICESUMMARY = 2; /** * Access level for apps which can access usage for any app on the device, including apps Loading @@ -85,7 +96,7 @@ public final class NetworkStatsAccess { * <li>The system UID. * </ul> */ int DEVICE = 2; int DEVICE = 3; } /** Returns the {@link NetworkStatsAccess.Level} for the given caller. */ Loading @@ -107,11 +118,15 @@ public final class NetworkStatsAccess { return NetworkStatsAccess.Level.DEVICE; } boolean hasAppOpsPermission = hasAppOpsPermission(context, callingUid, callingPackage); if (hasAppOpsPermission || context.checkCallingOrSelfPermission( READ_NETWORK_USAGE_HISTORY) == PackageManager.PERMISSION_GRANTED) { return NetworkStatsAccess.Level.DEVICESUMMARY; } boolean isProfileOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (hasAppOpsPermission(context, callingUid, callingPackage) || isProfileOwner || context.checkCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY) == PackageManager.PERMISSION_GRANTED) { if (isProfileOwner) { // Apps with the AppOps permission, profile owners, and apps with the privileged // permission can access data usage for all apps in this user/profile. return NetworkStatsAccess.Level.USER; Loading @@ -131,6 +146,7 @@ public final class NetworkStatsAccess { case NetworkStatsAccess.Level.DEVICE: // Device-level access - can access usage for any uid. return true; case NetworkStatsAccess.Level.DEVICESUMMARY: case NetworkStatsAccess.Level.USER: // User-level access - can access usage for any app running in the same user, along // with some special uids (system, removed, or tethering). Loading services/core/java/com/android/server/net/NetworkStatsService.java +7 −3 Original line number Diff line number Diff line Loading @@ -484,15 +484,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public NetworkStats getDeviceSummaryForNetwork(NetworkTemplate template, long start, long end) { @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(mCallingPackage); if (accessLevel < NetworkStatsAccess.Level.DEVICE) { if (accessLevel < NetworkStatsAccess.Level.DEVICESUMMARY) { throw new SecurityException("Calling package " + mCallingPackage + " cannot access device-level network stats"); + " cannot access device summary network stats"); } NetworkStats result = new NetworkStats(end - start, 1); final long ident = Binder.clearCallingIdentity(); try { // Using access level higher than the one we checked for above. // Reason is that we are combining usage data in a way that is not PII // anymore. result.combineAllValues( internalGetSummaryForNetwork(template, start, end, accessLevel)); internalGetSummaryForNetwork(template, start, end, NetworkStatsAccess.Level.DEVICE)); } finally { Binder.restoreCallingIdentity(ident); } Loading Loading
core/java/android/app/usage/NetworkStatsManager.java +6 −4 Original line number Diff line number Diff line Loading @@ -52,10 +52,12 @@ import android.util.Log; * {@link NetworkStats.Bucket#STATE_ALL} and all Bucket's roaming is going to be * {@link NetworkStats.Bucket#ROAMING_ALL}. * <p /> * <b>NOTE:</b> Accessing stats for apps other than the calling app requires the permission * {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, which is a system-level permission and * will not be granted to third-party apps. However, declaring the permission implies intention to * use the API and the user of the device can grant permission through the Settings application. * <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the * calling app requires the permission {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, * which is a system-level permission and will not be granted to third-party apps. However, * declaring the permission implies intention to use the API and the user of the device can grant * permission through the Settings application. * <p /> * Profile owner apps are automatically granted permission to query data on the profile they manage * (that is, for any query except {@link #querySummaryForDevice}). Device owner apps and carrier- * privileged apps likewise get access to usage data for all users on the device. Loading
services/core/java/com/android/server/net/NetworkStatsAccess.java +22 −6 Original line number Diff line number Diff line Loading @@ -66,13 +66,24 @@ public final class NetworkStatsAccess { * * <p>Granted to: * <ul> * <li>Profile owners. * </ul> */ int USER = 1; /** * Access level for apps which can access usage summary of device. Device summary includes * usage by apps running in any profiles/users, however this access level does not * allow querying usage of individual apps running in other profiles/users. * * <p>Granted to: * <ul> * <li>Apps with the PACKAGE_USAGE_STATS permission granted. Note that this is an AppOps bit * so it is not necessarily sufficient to declare this in the manifest. * <li>Apps with the (signature/privileged) READ_NETWORK_USAGE_HISTORY permission. * <li>Profile owners. * </ul> */ int USER = 1; int DEVICESUMMARY = 2; /** * Access level for apps which can access usage for any app on the device, including apps Loading @@ -85,7 +96,7 @@ public final class NetworkStatsAccess { * <li>The system UID. * </ul> */ int DEVICE = 2; int DEVICE = 3; } /** Returns the {@link NetworkStatsAccess.Level} for the given caller. */ Loading @@ -107,11 +118,15 @@ public final class NetworkStatsAccess { return NetworkStatsAccess.Level.DEVICE; } boolean hasAppOpsPermission = hasAppOpsPermission(context, callingUid, callingPackage); if (hasAppOpsPermission || context.checkCallingOrSelfPermission( READ_NETWORK_USAGE_HISTORY) == PackageManager.PERMISSION_GRANTED) { return NetworkStatsAccess.Level.DEVICESUMMARY; } boolean isProfileOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (hasAppOpsPermission(context, callingUid, callingPackage) || isProfileOwner || context.checkCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY) == PackageManager.PERMISSION_GRANTED) { if (isProfileOwner) { // Apps with the AppOps permission, profile owners, and apps with the privileged // permission can access data usage for all apps in this user/profile. return NetworkStatsAccess.Level.USER; Loading @@ -131,6 +146,7 @@ public final class NetworkStatsAccess { case NetworkStatsAccess.Level.DEVICE: // Device-level access - can access usage for any uid. return true; case NetworkStatsAccess.Level.DEVICESUMMARY: case NetworkStatsAccess.Level.USER: // User-level access - can access usage for any app running in the same user, along // with some special uids (system, removed, or tethering). Loading
services/core/java/com/android/server/net/NetworkStatsService.java +7 −3 Original line number Diff line number Diff line Loading @@ -484,15 +484,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public NetworkStats getDeviceSummaryForNetwork(NetworkTemplate template, long start, long end) { @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(mCallingPackage); if (accessLevel < NetworkStatsAccess.Level.DEVICE) { if (accessLevel < NetworkStatsAccess.Level.DEVICESUMMARY) { throw new SecurityException("Calling package " + mCallingPackage + " cannot access device-level network stats"); + " cannot access device summary network stats"); } NetworkStats result = new NetworkStats(end - start, 1); final long ident = Binder.clearCallingIdentity(); try { // Using access level higher than the one we checked for above. // Reason is that we are combining usage data in a way that is not PII // anymore. result.combineAllValues( internalGetSummaryForNetwork(template, start, end, accessLevel)); internalGetSummaryForNetwork(template, start, end, NetworkStatsAccess.Level.DEVICE)); } finally { Binder.restoreCallingIdentity(ident); } Loading