NetworkStatsManager.java revision 1efb1335814aea8ee0696144ca0ab24159b86e54
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 combination. In case of the user-wide and device-wide 44 * 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. Therefore there can be 51 * multiple buckets for a particular key but all Bucket's state is going to be 52 * {@link NetworkStats.Bucket#STATE_ALL}. 53 * <p /> 54 * <b>NOTE:</b> Accessing stats for apps other than the calling app requires the permission 55 * {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, which is a system-level permission and 56 * will not be granted to third-party apps. However, declaring the permission implies intention to 57 * use the API and the user of the device can grant permission through the Settings application. 58 * Profile owner apps are automatically granted permission to query data on the profile they manage 59 * (that is, for any query except {@link #querySummaryForDevice}). Device owner apps and carrier- 60 * privileged apps likewise get access to usage data for all users on the device. 61 * <p /> 62 * In addition to tethering usage, usage by removed users and apps, and usage by the system 63 * is also included in the results for callers with one of these higher levels of access. 64 * <p /> 65 * <b>NOTE:</b> Prior to API level {@value Build.VERSION_CODES#N}, all calls to these APIs required 66 * the above permission, even to access an app's own data usage, and carrier-privileged apps were 67 * not included. 68 */ 69public class NetworkStatsManager { 70 private final static String TAG = "NetworkStatsManager"; 71 72 private final Context mContext; 73 74 /** 75 * {@hide} 76 */ 77 public NetworkStatsManager(Context context) { 78 mContext = context; 79 } 80 /** 81 * Query network usage statistics summaries. Result is summarised data usage for the whole 82 * device. Result is a single Bucket aggregated over time, state and uid. This means the 83 * bucket's start and end timestamp are going to be the same as the 'startTime' and 'endTime' 84 * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid 85 * {@link NetworkStats.Bucket#UID_ALL}. 86 * 87 * @param networkType As defined in {@link ConnectivityManager}, e.g. 88 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 89 * etc. 90 * @param subscriberId If applicable, the subscriber id of the network interface. 91 * @param startTime Start of period. Defined in terms of "Unix time", see 92 * {@link java.lang.System#currentTimeMillis}. 93 * @param endTime End of period. Defined in terms of "Unix time", see 94 * {@link java.lang.System#currentTimeMillis}. 95 * @return Bucket object or null if permissions are insufficient or error happened during 96 * statistics collection. 97 */ 98 public Bucket querySummaryForDevice(int networkType, String subscriberId, 99 long startTime, long endTime) throws SecurityException, RemoteException { 100 NetworkTemplate template = createTemplate(networkType, subscriberId); 101 if (template == null) { 102 return null; 103 } 104 105 Bucket bucket = null; 106 NetworkStats stats = new NetworkStats(mContext, template, startTime, endTime); 107 bucket = stats.getDeviceSummaryForNetwork(); 108 109 stats.close(); 110 return bucket; 111 } 112 113 /** 114 * Query network usage statistics summaries. Result is summarised data usage for all uids 115 * belonging to calling user. Result is a single Bucket aggregated over time, state and uid. 116 * This means the bucket's start and end timestamp are going to be the same as the 'startTime' 117 * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid 118 * {@link NetworkStats.Bucket#UID_ALL}. 119 * 120 * @param networkType As defined in {@link ConnectivityManager}, e.g. 121 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 122 * etc. 123 * @param subscriberId If applicable, the subscriber id of the network interface. 124 * @param startTime Start of period. Defined in terms of "Unix time", see 125 * {@link java.lang.System#currentTimeMillis}. 126 * @param endTime End of period. Defined in terms of "Unix time", see 127 * {@link java.lang.System#currentTimeMillis}. 128 * @return Bucket object or null if permissions are insufficient or error happened during 129 * statistics collection. 130 */ 131 public Bucket querySummaryForUser(int networkType, String subscriberId, long startTime, 132 long endTime) throws SecurityException, RemoteException { 133 NetworkTemplate template = createTemplate(networkType, subscriberId); 134 if (template == null) { 135 return null; 136 } 137 138 NetworkStats stats; 139 stats = new NetworkStats(mContext, template, startTime, endTime); 140 stats.startSummaryEnumeration(); 141 142 stats.close(); 143 return stats.getSummaryAggregate(); 144 } 145 146 /** 147 * Query network usage statistics summaries. Result filtered to include only uids belonging to 148 * calling user. Result is aggregated over time, hence all buckets will have the same start and 149 * end timestamps. Not aggregated over state or uid. This means buckets' start and end 150 * timestamps are going to be the same as the 'startTime' and 'endTime' parameters, state and 151 * uid are going to vary. 152 * 153 * @param networkType As defined in {@link ConnectivityManager}, e.g. 154 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 155 * etc. 156 * @param subscriberId If applicable, the subscriber id of the network interface. 157 * @param startTime Start of period. Defined in terms of "Unix time", see 158 * {@link java.lang.System#currentTimeMillis}. 159 * @param endTime End of period. Defined in terms of "Unix time", see 160 * {@link java.lang.System#currentTimeMillis}. 161 * @return Statistics object or null if permissions are insufficient or error happened during 162 * statistics collection. 163 */ 164 public NetworkStats querySummary(int networkType, String subscriberId, long startTime, 165 long endTime) throws SecurityException, RemoteException { 166 NetworkTemplate template = createTemplate(networkType, subscriberId); 167 if (template == null) { 168 return null; 169 } 170 171 NetworkStats result; 172 result = new NetworkStats(mContext, template, startTime, endTime); 173 result.startSummaryEnumeration(); 174 175 return result; 176 } 177 178 /** 179 * Query network usage statistics details. Only usable for uids belonging to calling user. 180 * Result is aggregated over state but not aggregated over time. This means buckets' start and 181 * end timestamps are going to be between 'startTime' and 'endTime' parameters, state is going 182 * to be {@link NetworkStats.Bucket#STATE_ALL} and uid the same as the 'uid' parameter. 183 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't 184 * interpolate across partial buckets. Since bucket length is in the order of hours, this 185 * method cannot be used to measure data usage on a fine grained time scale. 186 * 187 * @param networkType As defined in {@link ConnectivityManager}, e.g. 188 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 189 * etc. 190 * @param subscriberId If applicable, the subscriber id of the network interface. 191 * @param startTime Start of period. Defined in terms of "Unix time", see 192 * {@link java.lang.System#currentTimeMillis}. 193 * @param endTime End of period. Defined in terms of "Unix time", see 194 * {@link java.lang.System#currentTimeMillis}. 195 * @param uid UID of app 196 * @return Statistics object or null if permissions are insufficient or error happened during 197 * statistics collection. 198 */ 199 public NetworkStats queryDetailsForUid(int networkType, String subscriberId, 200 long startTime, long endTime, int uid) throws SecurityException, RemoteException { 201 NetworkTemplate template = createTemplate(networkType, subscriberId); 202 if (template == null) { 203 return null; 204 } 205 206 NetworkStats result; 207 result = new NetworkStats(mContext, template, startTime, endTime); 208 result.startHistoryEnumeration(uid); 209 210 return result; 211 } 212 213 /** 214 * Query network usage statistics details. Result filtered to include only uids belonging to 215 * calling user. Result is aggregated over state but not aggregated over time or uid. This means 216 * buckets' start and end timestamps are going to be between 'startTime' and 'endTime' 217 * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid will vary. 218 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't 219 * interpolate across partial buckets. Since bucket length is in the order of hours, this 220 * method cannot be used to measure data usage on a fine grained time scale. 221 * 222 * @param networkType As defined in {@link ConnectivityManager}, e.g. 223 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 224 * etc. 225 * @param subscriberId If applicable, the subscriber id of the network interface. 226 * @param startTime Start of period. Defined in terms of "Unix time", see 227 * {@link java.lang.System#currentTimeMillis}. 228 * @param endTime End of period. Defined in terms of "Unix time", see 229 * {@link java.lang.System#currentTimeMillis}. 230 * @return Statistics object or null if permissions are insufficient or error happened during 231 * statistics collection. 232 */ 233 public NetworkStats queryDetails(int networkType, String subscriberId, long startTime, 234 long endTime) throws SecurityException, RemoteException { 235 NetworkTemplate template = createTemplate(networkType, subscriberId); 236 if (template == null) { 237 return null; 238 } 239 NetworkStats result; 240 result = new NetworkStats(mContext, template, startTime, endTime); 241 result.startUserUidEnumeration(); 242 return result; 243 } 244 245 private static NetworkTemplate createTemplate(int networkType, String subscriberId) { 246 NetworkTemplate template = null; 247 switch (networkType) { 248 case ConnectivityManager.TYPE_MOBILE: { 249 template = NetworkTemplate.buildTemplateMobileAll(subscriberId); 250 } break; 251 case ConnectivityManager.TYPE_WIFI: { 252 template = NetworkTemplate.buildTemplateWifiWildcard(); 253 } break; 254 default: { 255 Log.w(TAG, "Cannot create template for network type " + networkType 256 + ", subscriberId '" + NetworkIdentity.scrubSubscriberId(subscriberId) + 257 "'."); 258 } 259 } 260 return template; 261 } 262} 263