NetworkStatsManager.java revision 46c75367fa47bfd0429cab6121da0b897b5620a2
1/** 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy 6 * of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 17package android.app.usage; 18 19import android.app.usage.NetworkStats.Bucket; 20import android.content.Context; 21import android.net.ConnectivityManager; 22import android.net.NetworkIdentity; 23import android.net.NetworkTemplate; 24import android.os.Build; 25import android.os.RemoteException; 26import android.util.Log; 27 28/** 29 * Provides access to network usage history and statistics. Usage data is collected in 30 * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details. 31 * <p /> 32 * Queries can define a time interval in the form of start and end timestamps (Long.MIN_VALUE and 33 * Long.MAX_VALUE can be used to simulate open ended intervals). By default, apps can only obtain 34 * data about themselves. See the below note for special cases in which apps can obtain data about 35 * other applications. 36 * <h3> 37 * Summary queries 38 * </h3> 39 * {@link #querySummaryForDevice} <p /> 40 * {@link #querySummaryForUser} <p /> 41 * {@link #querySummary} <p /> 42 * These queries aggregate network usage across the whole interval. Therefore there will be only one 43 * bucket for a particular key and state and roaming combination. In case of the user-wide and 44 * device-wide summaries a single bucket containing the totalised network usage is returned. 45 * <h3> 46 * History queries 47 * </h3> 48 * {@link #queryDetailsForUid} <p /> 49 * {@link #queryDetails} <p /> 50 * These queries do not aggregate over time but do aggregate over state and roaming. Therefore there 51 * can be multiple buckets for a particular key but all Bucket's state is going to be 52 * {@link NetworkStats.Bucket#STATE_ALL} and all Bucket's roaming is going to be 53 * {@link NetworkStats.Bucket#ROAMING_ALL}. 54 * <p /> 55 * <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the 56 * calling app requires the permission {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, 57 * which is a system-level permission and will not be granted to third-party apps. However, 58 * declaring the permission implies intention to use the API and the user of the device can grant 59 * permission through the Settings application. 60 * <p /> 61 * Profile owner apps are automatically granted permission to query data on the profile they manage 62 * (that is, for any query except {@link #querySummaryForDevice}). Device owner apps and carrier- 63 * privileged apps likewise get access to usage data for all users on the device. 64 * <p /> 65 * In addition to tethering usage, usage by removed users and apps, and usage by the system 66 * is also included in the results for callers with one of these higher levels of access. 67 * <p /> 68 * <b>NOTE:</b> Prior to API level {@value Build.VERSION_CODES#N}, all calls to these APIs required 69 * the above permission, even to access an app's own data usage, and carrier-privileged apps were 70 * not included. 71 */ 72public class NetworkStatsManager { 73 private final static String TAG = "NetworkStatsManager"; 74 75 private final Context mContext; 76 77 /** 78 * {@hide} 79 */ 80 public NetworkStatsManager(Context context) { 81 mContext = context; 82 } 83 /** 84 * Query network usage statistics summaries. Result is summarised data usage for the whole 85 * device. Result is a single Bucket aggregated over time, state, uid, tag and roaming. This 86 * means the bucket's start and end timestamp are going to be the same as the 'startTime' and 87 * 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid 88 * {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_ALL} 89 * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}. 90 * 91 * @param networkType As defined in {@link ConnectivityManager}, e.g. 92 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 93 * etc. 94 * @param subscriberId If applicable, the subscriber id of the network interface. 95 * @param startTime Start of period. Defined in terms of "Unix time", see 96 * {@link java.lang.System#currentTimeMillis}. 97 * @param endTime End of period. Defined in terms of "Unix time", see 98 * {@link java.lang.System#currentTimeMillis}. 99 * @return Bucket object or null if permissions are insufficient or error happened during 100 * statistics collection. 101 */ 102 public Bucket querySummaryForDevice(int networkType, String subscriberId, 103 long startTime, long endTime) throws SecurityException, RemoteException { 104 NetworkTemplate template = createTemplate(networkType, subscriberId); 105 if (template == null) { 106 return null; 107 } 108 109 Bucket bucket = null; 110 NetworkStats stats = new NetworkStats(mContext, template, startTime, endTime); 111 bucket = stats.getDeviceSummaryForNetwork(); 112 113 stats.close(); 114 return bucket; 115 } 116 117 /** 118 * Query network usage statistics summaries aggregated across tags. 119 * 120 * #see querySummaryForUser(int, String, long, long, boolean) 121 */ 122 public Bucket querySummaryForUser(int networkType, String subscriberId, long startTime, 123 long endTime) throws SecurityException, RemoteException { 124 return querySummaryForUser(networkType, subscriberId, startTime, endTime, 125 false /* includeTags */); 126 } 127 128 /** 129 * Query network usage statistics summaries. Result is summarised data usage for all uids 130 * belonging to calling user. Result is a single Bucket aggregated over time, state and uid. 131 * This means the bucket's start and end timestamp are going to be the same as the 'startTime' 132 * and 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid 133 * {@link NetworkStats.Bucket#UID_ALL}. 134 * 135 * @param networkType As defined in {@link ConnectivityManager}, e.g. 136 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 137 * etc. 138 * @param subscriberId If applicable, the subscriber id of the network interface. 139 * @param startTime Start of period. Defined in terms of "Unix time", see 140 * {@link java.lang.System#currentTimeMillis}. 141 * @param endTime End of period. Defined in terms of "Unix time", see 142 * {@link java.lang.System#currentTimeMillis}. 143 * @param includeTags whether to include network tags. If {@code true}, tags will be returned 144 * and history retention may be shorter. 145 * @return Bucket object or null if permissions are insufficient or error happened during 146 * statistics collection. 147 */ 148 public Bucket querySummaryForUser(int networkType, String subscriberId, long startTime, 149 long endTime, boolean includeTags) throws SecurityException, RemoteException { 150 NetworkTemplate template = createTemplate(networkType, subscriberId); 151 if (template == null) { 152 return null; 153 } 154 155 NetworkStats stats; 156 stats = new NetworkStats(mContext, template, startTime, endTime); 157 stats.startSummaryEnumeration(includeTags); 158 159 stats.close(); 160 return stats.getSummaryAggregate(); 161 } 162 163 /** 164 * Query network usage statistics summaries aggregated across tags. 165 * 166 * #see querySummary(int, String, long, long, boolean) 167 */ 168 public NetworkStats querySummary(int networkType, String subscriberId, long startTime, 169 long endTime) throws SecurityException, RemoteException { 170 return querySummary(networkType, subscriberId, startTime, endTime, false /* includeTags */); 171 } 172 173 /** 174 * Query network usage statistics summaries. Result filtered to include only uids belonging to 175 * calling user. Result is aggregated over time, hence all buckets will have the same start and 176 * end timestamps. Not aggregated over state or uid or tag. This means buckets' start and end 177 * timestamps are going to be the same as the 'startTime' and 'endTime' parameters. State, 178 * uid and tag are going to vary. 179 * 180 * @param networkType As defined in {@link ConnectivityManager}, e.g. 181 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 182 * etc. 183 * @param subscriberId If applicable, the subscriber id of the network interface. 184 * @param startTime Start of period. Defined in terms of "Unix time", see 185 * {@link java.lang.System#currentTimeMillis}. 186 * @param endTime End of period. Defined in terms of "Unix time", see 187 * {@link java.lang.System#currentTimeMillis}. 188 * @param includeTags whether to include network tags. If {@code true}, tags will be returned 189 * and history retention may be shorter. 190 * @return Statistics object or null if permissions are insufficient or error happened during 191 * statistics collection. 192 */ 193 public NetworkStats querySummary(int networkType, String subscriberId, long startTime, 194 long endTime, boolean includeTags) throws SecurityException, RemoteException { 195 NetworkTemplate template = createTemplate(networkType, subscriberId); 196 if (template == null) { 197 return null; 198 } 199 200 NetworkStats result; 201 result = new NetworkStats(mContext, template, startTime, endTime); 202 result.startSummaryEnumeration(includeTags); 203 204 return result; 205 } 206 207 /** 208 * Query network usage statistics details for a given uid. 209 * 210 * #see queryDetailsForUidTag(int, String, long, long, int, int) 211 */ 212 public NetworkStats queryDetailsForUid(int networkType, String subscriberId, 213 long startTime, long endTime, int uid) throws SecurityException, RemoteException { 214 return queryDetailsForUidTag(networkType, subscriberId, startTime, endTime, uid, 215 NetworkStats.Bucket.TAG_ALL); 216 } 217 218 /** 219 * Query network usage statistics details for a given uid and tag. Only usable for uids 220 * belonging to calling user. Result is aggregated over state but not aggregated over time. 221 * This means buckets' start and end timestamps are going to be between 'startTime' and 222 * 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid the 223 * same as the 'uid' parameter and tag the same as 'tag' parameter. 224 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't 225 * interpolate across partial buckets. Since bucket length is in the order of hours, this 226 * method cannot be used to measure data usage on a fine grained time scale. 227 * 228 * @param networkType As defined in {@link ConnectivityManager}, e.g. 229 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 230 * etc. 231 * @param subscriberId If applicable, the subscriber id of the network interface. 232 * @param startTime Start of period. Defined in terms of "Unix time", see 233 * {@link java.lang.System#currentTimeMillis}. 234 * @param endTime End of period. Defined in terms of "Unix time", see 235 * {@link java.lang.System#currentTimeMillis}. 236 * @param uid UID of app 237 * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_ANY} for any tags, use 238 * {@link NetworkStats.Bucket#TAG_ALL} to aggregate over tags. 239 * @return Statistics object or null if permissions are insufficient or error happened during 240 * statistics collection. 241 */ 242 public NetworkStats queryDetailsForUidTag(int networkType, String subscriberId, 243 long startTime, long endTime, int uid, int tag) throws SecurityException, 244 RemoteException { 245 NetworkTemplate template = createTemplate(networkType, subscriberId); 246 if (template == null) { 247 return null; 248 } 249 250 NetworkStats result; 251 result = new NetworkStats(mContext, template, startTime, endTime); 252 result.startHistoryEnumeration(uid, tag); 253 254 return result; 255 } 256 257 /** 258 * Query network usage statistics details. Result filtered to include only uids belonging to 259 * calling user. Result is aggregated over state but not aggregated over time or uid. This means 260 * buckets' start and end timestamps are going to be between 'startTime' and 'endTime' 261 * parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid will vary, 262 * tag {@link NetworkStats.Bucket#TAG_ALL} and roaming is going to be 263 * {@link NetworkStats.Bucket#ROAMING_ALL}. 264 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't 265 * interpolate across partial buckets. Since bucket length is in the order of hours, this 266 * method cannot be used to measure data usage on a fine grained time scale. 267 * 268 * @param networkType As defined in {@link ConnectivityManager}, e.g. 269 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 270 * etc. 271 * @param subscriberId If applicable, the subscriber id of the network interface. 272 * @param startTime Start of period. Defined in terms of "Unix time", see 273 * {@link java.lang.System#currentTimeMillis}. 274 * @param endTime End of period. Defined in terms of "Unix time", see 275 * {@link java.lang.System#currentTimeMillis}. 276 * @return Statistics object or null if permissions are insufficient or error happened during 277 * statistics collection. 278 */ 279 public NetworkStats queryDetails(int networkType, String subscriberId, long startTime, 280 long endTime) throws SecurityException, RemoteException { 281 NetworkTemplate template = createTemplate(networkType, subscriberId); 282 if (template == null) { 283 return null; 284 } 285 NetworkStats result; 286 result = new NetworkStats(mContext, template, startTime, endTime); 287 result.startUserUidEnumeration(); 288 return result; 289 } 290 291 private static NetworkTemplate createTemplate(int networkType, String subscriberId) { 292 NetworkTemplate template = null; 293 switch (networkType) { 294 case ConnectivityManager.TYPE_MOBILE: { 295 template = NetworkTemplate.buildTemplateMobileAll(subscriberId); 296 } break; 297 case ConnectivityManager.TYPE_WIFI: { 298 template = NetworkTemplate.buildTemplateWifiWildcard(); 299 } break; 300 default: { 301 Log.w(TAG, "Cannot create template for network type " + networkType 302 + ", subscriberId '" + NetworkIdentity.scrubSubscriberId(subscriberId) + 303 "'."); 304 } 305 } 306 return template; 307 } 308} 309