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 17 package android.app.usage; 18 19 import android.app.usage.NetworkStats.Bucket; 20 import android.content.Context; 21 import android.net.ConnectivityManager; 22 import android.net.NetworkIdentity; 23 import android.net.NetworkTemplate; 24 import android.os.RemoteException; 25 import android.util.Log; 26 27 /** 28 * Provides access to network usage history and statistics. Usage data is collected in 29 * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details. 30 * <p /> 31 * Queries can define a time interval in the form of start and end timestamps (Long.MIN_VALUE and 32 * Long.MAX_VALUE can be used to simulate open ended intervals). All queries (except 33 * {@link #querySummaryForDevice}) collect only network usage of apps belonging to the same user 34 * as the client. In addition tethering usage, usage by removed users and apps, and usage by system 35 * is also included in the results. 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> This API 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 likewise get 60 * access to usage data of the primary user. 61 */ 62 public class NetworkStatsManager { 63 private final static String TAG = "NetworkStatsManager"; 64 65 private final Context mContext; 66 67 /** 68 * {@hide} 69 */ NetworkStatsManager(Context context)70 public NetworkStatsManager(Context context) { 71 mContext = context; 72 } 73 /** 74 * Query network usage statistics summaries. Result is summarised data usage for the whole 75 * device. Result is a single Bucket aggregated over time, state and uid. This means the 76 * bucket's start and end timestamp are going to be the same as the 'startTime' and 'endTime' 77 * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid 78 * {@link NetworkStats.Bucket#UID_ALL}. 79 * 80 * @param networkType As defined in {@link ConnectivityManager}, e.g. 81 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 82 * etc. 83 * @param subscriberId If applicable, the subscriber id of the network interface. 84 * @param startTime Start of period. Defined in terms of "Unix time", see 85 * {@link java.lang.System#currentTimeMillis}. 86 * @param endTime End of period. Defined in terms of "Unix time", see 87 * {@link java.lang.System#currentTimeMillis}. 88 * @return Bucket object or null if permissions are insufficient or error happened during 89 * statistics collection. 90 */ querySummaryForDevice(int networkType, String subscriberId, long startTime, long endTime)91 public Bucket querySummaryForDevice(int networkType, String subscriberId, 92 long startTime, long endTime) throws SecurityException, RemoteException { 93 NetworkTemplate template = createTemplate(networkType, subscriberId); 94 if (template == null) { 95 return null; 96 } 97 98 Bucket bucket = null; 99 NetworkStats stats = new NetworkStats(mContext, template, startTime, endTime); 100 bucket = stats.getDeviceSummaryForNetwork(); 101 102 stats.close(); 103 return bucket; 104 } 105 106 /** 107 * Query network usage statistics summaries. Result is summarised data usage for all uids 108 * belonging to calling user. Result is a single Bucket aggregated over time, state and uid. 109 * This means the bucket's start and end timestamp are going to be the same as the 'startTime' 110 * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid 111 * {@link NetworkStats.Bucket#UID_ALL}. 112 * 113 * @param networkType As defined in {@link ConnectivityManager}, e.g. 114 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 115 * etc. 116 * @param subscriberId If applicable, the subscriber id of the network interface. 117 * @param startTime Start of period. Defined in terms of "Unix time", see 118 * {@link java.lang.System#currentTimeMillis}. 119 * @param endTime End of period. Defined in terms of "Unix time", see 120 * {@link java.lang.System#currentTimeMillis}. 121 * @return Bucket object or null if permissions are insufficient or error happened during 122 * statistics collection. 123 */ querySummaryForUser(int networkType, String subscriberId, long startTime, long endTime)124 public Bucket querySummaryForUser(int networkType, String subscriberId, long startTime, 125 long endTime) throws SecurityException, RemoteException { 126 NetworkTemplate template = createTemplate(networkType, subscriberId); 127 if (template == null) { 128 return null; 129 } 130 131 NetworkStats stats; 132 stats = new NetworkStats(mContext, template, startTime, endTime); 133 stats.startSummaryEnumeration(); 134 135 stats.close(); 136 return stats.getSummaryAggregate(); 137 } 138 139 /** 140 * Query network usage statistics summaries. Result filtered to include only uids belonging to 141 * calling user. Result is aggregated over time, hence all buckets will have the same start and 142 * end timestamps. Not aggregated over state or uid. This means buckets' start and end 143 * timestamps are going to be the same as the 'startTime' and 'endTime' parameters, state and 144 * uid are going to vary. 145 * 146 * @param networkType As defined in {@link ConnectivityManager}, e.g. 147 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 148 * etc. 149 * @param subscriberId If applicable, the subscriber id of the network interface. 150 * @param startTime Start of period. Defined in terms of "Unix time", see 151 * {@link java.lang.System#currentTimeMillis}. 152 * @param endTime End of period. Defined in terms of "Unix time", see 153 * {@link java.lang.System#currentTimeMillis}. 154 * @return Statistics object or null if permissions are insufficient or error happened during 155 * statistics collection. 156 */ querySummary(int networkType, String subscriberId, long startTime, long endTime)157 public NetworkStats querySummary(int networkType, String subscriberId, long startTime, 158 long endTime) throws SecurityException, RemoteException { 159 NetworkTemplate template = createTemplate(networkType, subscriberId); 160 if (template == null) { 161 return null; 162 } 163 164 NetworkStats result; 165 result = new NetworkStats(mContext, template, startTime, endTime); 166 result.startSummaryEnumeration(); 167 168 return result; 169 } 170 171 /** 172 * Query network usage statistics details. Only usable for uids belonging to calling user. 173 * Result is aggregated over state but not aggregated over time. This means buckets' start and 174 * end timestamps are going to be between 'startTime' and 'endTime' parameters, state is going 175 * to be {@link NetworkStats.Bucket#STATE_ALL} and uid the same as the 'uid' parameter. 176 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't 177 * interpolate across partial buckets. Since bucket length is in the order of hours, this 178 * method cannot be used to measure data usage on a fine grained time scale. 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 uid UID of app 189 * @return Statistics object or null if permissions are insufficient or error happened during 190 * statistics collection. 191 */ queryDetailsForUid(int networkType, String subscriberId, long startTime, long endTime, int uid)192 public NetworkStats queryDetailsForUid(int networkType, String subscriberId, 193 long startTime, long endTime, int uid) throws SecurityException, RemoteException { 194 NetworkTemplate template = createTemplate(networkType, subscriberId); 195 if (template == null) { 196 return null; 197 } 198 199 NetworkStats result; 200 result = new NetworkStats(mContext, template, startTime, endTime); 201 result.startHistoryEnumeration(uid); 202 203 return result; 204 } 205 206 /** 207 * Query network usage statistics details. Result filtered to include only uids belonging to 208 * calling user. Result is aggregated over state but not aggregated over time or uid. This means 209 * buckets' start and end timestamps are going to be between 'startTime' and 'endTime' 210 * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid will vary. 211 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't 212 * interpolate across partial buckets. Since bucket length is in the order of hours, this 213 * method cannot be used to measure data usage on a fine grained time scale. 214 * 215 * @param networkType As defined in {@link ConnectivityManager}, e.g. 216 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} 217 * etc. 218 * @param subscriberId If applicable, the subscriber id of the network interface. 219 * @param startTime Start of period. Defined in terms of "Unix time", see 220 * {@link java.lang.System#currentTimeMillis}. 221 * @param endTime End of period. Defined in terms of "Unix time", see 222 * {@link java.lang.System#currentTimeMillis}. 223 * @return Statistics object or null if permissions are insufficient or error happened during 224 * statistics collection. 225 */ queryDetails(int networkType, String subscriberId, long startTime, long endTime)226 public NetworkStats queryDetails(int networkType, String subscriberId, long startTime, 227 long endTime) throws SecurityException, RemoteException { 228 NetworkTemplate template = createTemplate(networkType, subscriberId); 229 if (template == null) { 230 return null; 231 } 232 NetworkStats result; 233 result = new NetworkStats(mContext, template, startTime, endTime); 234 result.startUserUidEnumeration(); 235 return result; 236 } 237 createTemplate(int networkType, String subscriberId)238 private static NetworkTemplate createTemplate(int networkType, String subscriberId) { 239 NetworkTemplate template = null; 240 switch (networkType) { 241 case ConnectivityManager.TYPE_MOBILE: { 242 template = NetworkTemplate.buildTemplateMobileAll(subscriberId); 243 } break; 244 case ConnectivityManager.TYPE_WIFI: { 245 template = NetworkTemplate.buildTemplateWifiWildcard(); 246 } break; 247 default: { 248 Log.w(TAG, "Cannot create template for network type " + networkType 249 + ", subscriberId '" + NetworkIdentity.scrubSubscriberId(subscriberId) + 250 "'."); 251 } 252 } 253 return template; 254 } 255 } 256