NetworkStatsManager.java revision 3a8b343ce5220086c4f71e63f5d42f2d28434c4b
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 and uid. This means the 86 * bucket's start and end timestamp are going to be the same as the 'startTime' and 'endTime' 87 * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid 88 * {@link NetworkStats.Bucket#UID_ALL}, and roaming {@link NetworkStats.Bucket#ROAMING_ALL}. 89 * 90 * @param networkType As defined in {@link ConnectivityManager}, e.g. 91 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 92 * etc. 93 * @param subscriberId If applicable, the subscriber id of the network interface. 94 * @param startTime Start of period. Defined in terms of "Unix time", see 95 * {@link java.lang.System#currentTimeMillis}. 96 * @param endTime End of period. Defined in terms of "Unix time", see 97 * {@link java.lang.System#currentTimeMillis}. 98 * @return Bucket object or null if permissions are insufficient or error happened during 99 * statistics collection. 100 */ 101 public Bucket querySummaryForDevice(int networkType, String subscriberId, 102 long startTime, long endTime) throws SecurityException, RemoteException { 103 NetworkTemplate template = createTemplate(networkType, subscriberId); 104 if (template == null) { 105 return null; 106 } 107 108 Bucket bucket = null; 109 NetworkStats stats = new NetworkStats(mContext, template, startTime, endTime); 110 bucket = stats.getDeviceSummaryForNetwork(); 111 112 stats.close(); 113 return bucket; 114 } 115 116 /** 117 * Query network usage statistics summaries. Result is summarised data usage for all uids 118 * belonging to calling user. Result is a single Bucket aggregated over time, state and uid. 119 * This means the bucket's start and end timestamp are going to be the same as the 'startTime' 120 * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid 121 * {@link NetworkStats.Bucket#UID_ALL}, and roaming {@link NetworkStats.Bucket#ROAMING_ALL}. 122 * 123 * @param networkType As defined in {@link ConnectivityManager}, e.g. 124 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 125 * etc. 126 * @param subscriberId If applicable, the subscriber id of the network interface. 127 * @param startTime Start of period. Defined in terms of "Unix time", see 128 * {@link java.lang.System#currentTimeMillis}. 129 * @param endTime End of period. Defined in terms of "Unix time", see 130 * {@link java.lang.System#currentTimeMillis}. 131 * @return Bucket object or null if permissions are insufficient or error happened during 132 * statistics collection. 133 */ 134 public Bucket querySummaryForUser(int networkType, String subscriberId, long startTime, 135 long endTime) throws SecurityException, RemoteException { 136 NetworkTemplate template = createTemplate(networkType, subscriberId); 137 if (template == null) { 138 return null; 139 } 140 141 NetworkStats stats; 142 stats = new NetworkStats(mContext, template, startTime, endTime); 143 stats.startSummaryEnumeration(); 144 145 stats.close(); 146 return stats.getSummaryAggregate(); 147 } 148 149 /** 150 * Query network usage statistics summaries. Result filtered to include only uids belonging to 151 * calling user. Result is aggregated over time, hence all buckets will have the same start and 152 * end timestamps. Not aggregated over state, uid, or roaming. This means buckets' start and end 153 * timestamps are going to be the same as the 'startTime' and 'endTime' parameters, state and 154 * uid are going to vary. 155 * 156 * @param networkType As defined in {@link ConnectivityManager}, e.g. 157 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 158 * etc. 159 * @param subscriberId If applicable, the subscriber id of the network interface. 160 * @param startTime Start of period. Defined in terms of "Unix time", see 161 * {@link java.lang.System#currentTimeMillis}. 162 * @param endTime End of period. Defined in terms of "Unix time", see 163 * {@link java.lang.System#currentTimeMillis}. 164 * @return Statistics object or null if permissions are insufficient or error happened during 165 * statistics collection. 166 */ 167 public NetworkStats querySummary(int networkType, String subscriberId, long startTime, 168 long endTime) throws SecurityException, RemoteException { 169 NetworkTemplate template = createTemplate(networkType, subscriberId); 170 if (template == null) { 171 return null; 172 } 173 174 NetworkStats result; 175 result = new NetworkStats(mContext, template, startTime, endTime); 176 result.startSummaryEnumeration(); 177 178 return result; 179 } 180 181 /** 182 * Query network usage statistics details. Only usable for uids belonging to calling user. 183 * Result is aggregated over state but not aggregated over time. This means buckets' start and 184 * end timestamps are going to be between 'startTime' and 'endTime' parameters, state is going 185 * to be {@link NetworkStats.Bucket#STATE_ALL} and uid the same as the 'uid' parameter. roaming 186 * is going to be {@link NetworkStats.Bucket#ROAMING_ALL}. 187 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't 188 * interpolate across partial buckets. Since bucket length is in the order of hours, this 189 * method cannot be used to measure data usage on a fine grained time scale. 190 * 191 * @param networkType As defined in {@link ConnectivityManager}, e.g. 192 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 193 * etc. 194 * @param subscriberId If applicable, the subscriber id of the network interface. 195 * @param startTime Start of period. Defined in terms of "Unix time", see 196 * {@link java.lang.System#currentTimeMillis}. 197 * @param endTime End of period. Defined in terms of "Unix time", see 198 * {@link java.lang.System#currentTimeMillis}. 199 * @param uid UID of app 200 * @return Statistics object or null if permissions are insufficient or error happened during 201 * statistics collection. 202 */ 203 public NetworkStats queryDetailsForUid(int networkType, String subscriberId, 204 long startTime, long endTime, int uid) throws SecurityException, RemoteException { 205 NetworkTemplate template = createTemplate(networkType, subscriberId); 206 if (template == null) { 207 return null; 208 } 209 210 NetworkStats result; 211 result = new NetworkStats(mContext, template, startTime, endTime); 212 result.startHistoryEnumeration(uid); 213 214 return result; 215 } 216 217 /** 218 * Query network usage statistics details. Result filtered to include only uids belonging to 219 * calling user. Result is aggregated over state but not aggregated over time or uid. This means 220 * buckets' start and end timestamps are going to be between 'startTime' and 'endTime' 221 * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid will vary. 222 * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}. 223 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't 224 * interpolate across partial buckets. Since bucket length is in the order of hours, this 225 * method cannot be used to measure data usage on a fine grained time scale. 226 * 227 * @param networkType As defined in {@link ConnectivityManager}, e.g. 228 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 229 * etc. 230 * @param subscriberId If applicable, the subscriber id of the network interface. 231 * @param startTime Start of period. Defined in terms of "Unix time", see 232 * {@link java.lang.System#currentTimeMillis}. 233 * @param endTime End of period. Defined in terms of "Unix time", see 234 * {@link java.lang.System#currentTimeMillis}. 235 * @return Statistics object or null if permissions are insufficient or error happened during 236 * statistics collection. 237 */ 238 public NetworkStats queryDetails(int networkType, String subscriberId, long startTime, 239 long endTime) throws SecurityException, RemoteException { 240 NetworkTemplate template = createTemplate(networkType, subscriberId); 241 if (template == null) { 242 return null; 243 } 244 NetworkStats result; 245 result = new NetworkStats(mContext, template, startTime, endTime); 246 result.startUserUidEnumeration(); 247 return result; 248 } 249 250 private static NetworkTemplate createTemplate(int networkType, String subscriberId) { 251 NetworkTemplate template = null; 252 switch (networkType) { 253 case ConnectivityManager.TYPE_MOBILE: { 254 template = NetworkTemplate.buildTemplateMobileAll(subscriberId); 255 } break; 256 case ConnectivityManager.TYPE_WIFI: { 257 template = NetworkTemplate.buildTemplateWifiWildcard(); 258 } break; 259 default: { 260 Log.w(TAG, "Cannot create template for network type " + networkType 261 + ", subscriberId '" + NetworkIdentity.scrubSubscriberId(subscriberId) + 262 "'."); 263 } 264 } 265 return template; 266 } 267} 268