blob: 9c4a8f4fbe2754fe3d28a85db4187c8c7574ee6a [file] [log] [blame]
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +00001/**
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
junyulai80831d22019-11-21 16:26:27 +080019import android.annotation.NonNull;
Antonio Cansadoba8288d2015-12-02 08:42:54 -080020import android.annotation.Nullable;
junyulai80831d22019-11-21 16:26:27 +080021import android.annotation.RequiresPermission;
22import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060023import android.annotation.SystemService;
Jeff Sharkeyc3c8d162018-04-20 10:59:09 -060024import android.annotation.TestApi;
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +010025import android.app.usage.NetworkStats.Bucket;
Artur Satayevd9b11b02019-12-10 17:47:51 +000026import android.compat.annotation.UnsupportedAppUsage;
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000027import android.content.Context;
28import android.net.ConnectivityManager;
Antonio Cansadoba8288d2015-12-02 08:42:54 -080029import android.net.DataUsageRequest;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060030import android.net.INetworkStatsService;
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000031import android.net.NetworkIdentity;
32import android.net.NetworkTemplate;
junyulai80831d22019-11-21 16:26:27 +080033import android.net.netstats.provider.AbstractNetworkStatsProvider;
34import android.net.netstats.provider.NetworkStatsProviderCallback;
35import android.net.netstats.provider.NetworkStatsProviderWrapper;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080036import android.os.Binder;
Antonio Cansadoba8288d2015-12-02 08:42:54 -080037import android.os.Handler;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080038import android.os.Looper;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060039import android.os.Message;
40import android.os.Messenger;
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000041import android.os.RemoteException;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080042import android.os.ServiceManager;
Jeff Sharkey49ca5292016-05-10 12:54:45 -060043import android.os.ServiceManager.ServiceNotFoundException;
Remi NGUYEN VANd06a9002018-04-04 14:51:26 +090044import android.util.DataUnit;
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000045import android.util.Log;
46
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +090047import com.android.internal.annotations.VisibleForTesting;
48
junyulai232b2ed2020-01-13 14:36:55 +080049import java.util.Objects;
50
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000051/**
52 * Provides access to network usage history and statistics. Usage data is collected in
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +010053 * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000054 * <p />
55 * Queries can define a time interval in the form of start and end timestamps (Long.MIN_VALUE and
Jeff Davidson1efb1332015-12-09 18:04:50 -080056 * Long.MAX_VALUE can be used to simulate open ended intervals). By default, apps can only obtain
57 * data about themselves. See the below note for special cases in which apps can obtain data about
58 * other applications.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000059 * <h3>
60 * Summary queries
61 * </h3>
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +010062 * {@link #querySummaryForDevice} <p />
63 * {@link #querySummaryForUser} <p />
64 * {@link #querySummary} <p />
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000065 * These queries aggregate network usage across the whole interval. Therefore there will be only one
Stephen Chen25147872016-10-21 12:44:26 -070066 * bucket for a particular key, state, metered and roaming combination. In case of the user-wide
67 * and device-wide summaries a single bucket containing the totalised network usage is returned.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000068 * <h3>
69 * History queries
70 * </h3>
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +010071 * {@link #queryDetailsForUid} <p />
72 * {@link #queryDetails} <p />
Stephen Chen25147872016-10-21 12:44:26 -070073 * These queries do not aggregate over time but do aggregate over state, metered and roaming.
Lorenzo Colitti35c13e52018-01-19 01:12:58 +090074 * Therefore there can be multiple buckets for a particular key. However, all Buckets will have
75 * {@code state} {@link NetworkStats.Bucket#STATE_ALL},
76 * {@code defaultNetwork} {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
77 * {@code metered } {@link NetworkStats.Bucket#METERED_ALL},
78 * {@code roaming} {@link NetworkStats.Bucket#ROAMING_ALL}.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000079 * <p />
Zoltan Szatmary-Ban3a8b3432016-01-21 10:44:37 +000080 * <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the
81 * calling app requires the permission {@link android.Manifest.permission#PACKAGE_USAGE_STATS},
82 * which is a system-level permission and will not be granted to third-party apps. However,
83 * declaring the permission implies intention to use the API and the user of the device can grant
84 * permission through the Settings application.
85 * <p />
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000086 * Profile owner apps are automatically granted permission to query data on the profile they manage
Jeff Davidson1efb1332015-12-09 18:04:50 -080087 * (that is, for any query except {@link #querySummaryForDevice}). Device owner apps and carrier-
88 * privileged apps likewise get access to usage data for all users on the device.
89 * <p />
90 * In addition to tethering usage, usage by removed users and apps, and usage by the system
91 * is also included in the results for callers with one of these higher levels of access.
92 * <p />
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060093 * <b>NOTE:</b> Prior to API level {@value android.os.Build.VERSION_CODES#N}, all calls to these APIs required
Jeff Davidson1efb1332015-12-09 18:04:50 -080094 * the above permission, even to access an app's own data usage, and carrier-privileged apps were
95 * not included.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000096 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060097@SystemService(Context.NETWORK_STATS_SERVICE)
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +000098public class NetworkStatsManager {
Antonio Cansadocd42acd2016-02-17 13:03:38 -080099 private static final String TAG = "NetworkStatsManager";
100 private static final boolean DBG = false;
101
102 /** @hide */
103 public static final int CALLBACK_LIMIT_REACHED = 0;
104 /** @hide */
105 public static final int CALLBACK_RELEASED = 1;
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000106
Remi NGUYEN VANd06a9002018-04-04 14:51:26 +0900107 /**
108 * Minimum data usage threshold for registering usage callbacks.
109 *
110 * Requests registered with a threshold lower than this will only be triggered once this minimum
111 * is reached.
112 * @hide
113 */
114 public static final long MIN_THRESHOLD_BYTES = DataUnit.MEBIBYTES.toBytes(2);
115
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000116 private final Context mContext;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800117 private final INetworkStatsService mService;
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000118
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600119 /** @hide */
120 public static final int FLAG_POLL_ON_OPEN = 1 << 0;
121 /** @hide */
Jeff Sharkeyc3c8d162018-04-20 10:59:09 -0600122 public static final int FLAG_POLL_FORCE = 1 << 1;
123 /** @hide */
124 public static final int FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN = 1 << 2;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600125
126 private int mFlags;
127
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000128 /**
129 * {@hide}
130 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100131 @UnsupportedAppUsage
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600132 public NetworkStatsManager(Context context) throws ServiceNotFoundException {
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900133 this(context, INetworkStatsService.Stub.asInterface(
134 ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE)));
135 }
136
137 /** @hide */
138 @VisibleForTesting
139 public NetworkStatsManager(Context context, INetworkStatsService service) {
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000140 mContext = context;
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900141 mService = service;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600142 setPollOnOpen(true);
143 }
144
145 /** @hide */
146 public void setPollOnOpen(boolean pollOnOpen) {
147 if (pollOnOpen) {
148 mFlags |= FLAG_POLL_ON_OPEN;
149 } else {
150 mFlags &= ~FLAG_POLL_ON_OPEN;
151 }
152 }
153
154 /** @hide */
Artur Satayev5a525852019-10-31 15:15:50 +0000155 @UnsupportedAppUsage
Jeff Sharkeyc3c8d162018-04-20 10:59:09 -0600156 @TestApi
157 public void setPollForce(boolean pollForce) {
158 if (pollForce) {
159 mFlags |= FLAG_POLL_FORCE;
160 } else {
161 mFlags &= ~FLAG_POLL_FORCE;
162 }
163 }
164
165 /** @hide */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600166 public void setAugmentWithSubscriptionPlan(boolean augmentWithSubscriptionPlan) {
167 if (augmentWithSubscriptionPlan) {
168 mFlags |= FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
169 } else {
170 mFlags &= ~FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
171 }
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000172 }
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800173
Lorenzo Colittie0f69092018-01-22 21:00:49 +0900174 /** @hide */
175 public Bucket querySummaryForDevice(NetworkTemplate template,
176 long startTime, long endTime) throws SecurityException, RemoteException {
177 Bucket bucket = null;
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900178 NetworkStats stats = new NetworkStats(mContext, template, mFlags, startTime, endTime,
179 mService);
Lorenzo Colittie0f69092018-01-22 21:00:49 +0900180 bucket = stats.getDeviceSummaryForNetwork();
181
182 stats.close();
183 return bucket;
184 }
185
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000186 /**
187 * Query network usage statistics summaries. Result is summarised data usage for the whole
Stephen Chen25147872016-10-21 12:44:26 -0700188 * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and
189 * roaming. This means the bucket's start and end timestamp are going to be the same as the
190 * 'startTime' and 'endTime' parameters. State is going to be
191 * {@link NetworkStats.Bucket#STATE_ALL}, uid {@link NetworkStats.Bucket#UID_ALL},
Lorenzo Colitti35c13e52018-01-19 01:12:58 +0900192 * tag {@link NetworkStats.Bucket#TAG_NONE},
193 * default network {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
194 * metered {@link NetworkStats.Bucket#METERED_ALL},
Antonio Cansado46c753672015-12-10 15:57:56 -0800195 * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000196 *
197 * @param networkType As defined in {@link ConnectivityManager}, e.g.
198 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
199 * etc.
200 * @param subscriberId If applicable, the subscriber id of the network interface.
201 * @param startTime Start of period. Defined in terms of "Unix time", see
202 * {@link java.lang.System#currentTimeMillis}.
203 * @param endTime End of period. Defined in terms of "Unix time", see
204 * {@link java.lang.System#currentTimeMillis}.
205 * @return Bucket object or null if permissions are insufficient or error happened during
206 * statistics collection.
207 */
208 public Bucket querySummaryForDevice(int networkType, String subscriberId,
209 long startTime, long endTime) throws SecurityException, RemoteException {
Antonio Cansado6965c182016-03-30 11:37:18 -0700210 NetworkTemplate template;
211 try {
212 template = createTemplate(networkType, subscriberId);
213 } catch (IllegalArgumentException e) {
214 if (DBG) Log.e(TAG, "Cannot create template", e);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000215 return null;
216 }
217
Lorenzo Colittie0f69092018-01-22 21:00:49 +0900218 return querySummaryForDevice(template, startTime, endTime);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000219 }
220
221 /**
222 * Query network usage statistics summaries. Result is summarised data usage for all uids
223 * belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100224 * This means the bucket's start and end timestamp are going to be the same as the 'startTime'
Stephen Chen25147872016-10-21 12:44:26 -0700225 * and 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL},
226 * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE},
227 * metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming
228 * {@link NetworkStats.Bucket#ROAMING_ALL}.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000229 *
230 * @param networkType As defined in {@link ConnectivityManager}, e.g.
231 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
232 * etc.
233 * @param subscriberId If applicable, the subscriber id of the network interface.
234 * @param startTime Start of period. Defined in terms of "Unix time", see
235 * {@link java.lang.System#currentTimeMillis}.
236 * @param endTime End of period. Defined in terms of "Unix time", see
237 * {@link java.lang.System#currentTimeMillis}.
238 * @return Bucket object or null if permissions are insufficient or error happened during
239 * statistics collection.
240 */
241 public Bucket querySummaryForUser(int networkType, String subscriberId, long startTime,
Antonio Cansado6965c182016-03-30 11:37:18 -0700242 long endTime) throws SecurityException, RemoteException {
243 NetworkTemplate template;
244 try {
245 template = createTemplate(networkType, subscriberId);
246 } catch (IllegalArgumentException e) {
247 if (DBG) Log.e(TAG, "Cannot create template", e);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000248 return null;
249 }
250
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +0100251 NetworkStats stats;
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900252 stats = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
Antonio Cansado6965c182016-03-30 11:37:18 -0700253 stats.startSummaryEnumeration();
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000254
255 stats.close();
256 return stats.getSummaryAggregate();
257 }
258
259 /**
260 * Query network usage statistics summaries. Result filtered to include only uids belonging to
261 * calling user. Result is aggregated over time, hence all buckets will have the same start and
Lorenzo Colitti35c13e52018-01-19 01:12:58 +0900262 * end timestamps. Not aggregated over state, uid, default network, metered, or roaming. This
263 * means buckets' start and end timestamps are going to be the same as the 'startTime' and
264 * 'endTime' parameters. State, uid, metered, and roaming are going to vary, and tag is going to
265 * be the same.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000266 *
267 * @param networkType As defined in {@link ConnectivityManager}, e.g.
268 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
269 * etc.
270 * @param subscriberId If applicable, the subscriber id of the network interface.
271 * @param startTime Start of period. Defined in terms of "Unix time", see
272 * {@link java.lang.System#currentTimeMillis}.
273 * @param endTime End of period. Defined in terms of "Unix time", see
274 * {@link java.lang.System#currentTimeMillis}.
275 * @return Statistics object or null if permissions are insufficient or error happened during
276 * statistics collection.
277 */
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +0100278 public NetworkStats querySummary(int networkType, String subscriberId, long startTime,
Antonio Cansado6965c182016-03-30 11:37:18 -0700279 long endTime) throws SecurityException, RemoteException {
280 NetworkTemplate template;
281 try {
282 template = createTemplate(networkType, subscriberId);
283 } catch (IllegalArgumentException e) {
284 if (DBG) Log.e(TAG, "Cannot create template", e);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000285 return null;
286 }
287
Lei Yuc00a30e2019-05-09 11:53:57 -0700288 return querySummary(template, startTime, endTime);
289 }
290
291 /** @hide */
292 public NetworkStats querySummary(NetworkTemplate template, long startTime,
293 long endTime) throws SecurityException, RemoteException {
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +0100294 NetworkStats result;
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900295 result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
Antonio Cansado6965c182016-03-30 11:37:18 -0700296 result.startSummaryEnumeration();
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000297
298 return result;
299 }
300
301 /**
Antonio Cansado46c753672015-12-10 15:57:56 -0800302 * Query network usage statistics details for a given uid.
303 *
Lorenzo Colitti84b317c2018-04-02 16:48:31 +0900304 * #see queryDetailsForUidTagState(int, String, long, long, int, int, int)
Antonio Cansado46c753672015-12-10 15:57:56 -0800305 */
306 public NetworkStats queryDetailsForUid(int networkType, String subscriberId,
Lorenzo Colitti84b317c2018-04-02 16:48:31 +0900307 long startTime, long endTime, int uid) throws SecurityException {
308 return queryDetailsForUidTagState(networkType, subscriberId, startTime, endTime, uid,
309 NetworkStats.Bucket.TAG_NONE, NetworkStats.Bucket.STATE_ALL);
Antonio Cansado46c753672015-12-10 15:57:56 -0800310 }
311
Lei Yuc00a30e2019-05-09 11:53:57 -0700312 /** @hide */
313 public NetworkStats queryDetailsForUid(NetworkTemplate template,
314 long startTime, long endTime, int uid) throws SecurityException {
315 return queryDetailsForUidTagState(template, startTime, endTime, uid,
316 NetworkStats.Bucket.TAG_NONE, NetworkStats.Bucket.STATE_ALL);
317 }
318
Antonio Cansado46c753672015-12-10 15:57:56 -0800319 /**
Lorenzo Colitti84b317c2018-04-02 16:48:31 +0900320 * Query network usage statistics details for a given uid and tag.
321 *
322 * #see queryDetailsForUidTagState(int, String, long, long, int, int, int)
323 */
324 public NetworkStats queryDetailsForUidTag(int networkType, String subscriberId,
325 long startTime, long endTime, int uid, int tag) throws SecurityException {
326 return queryDetailsForUidTagState(networkType, subscriberId, startTime, endTime, uid,
327 tag, NetworkStats.Bucket.STATE_ALL);
328 }
329
330 /**
331 * Query network usage statistics details for a given uid, tag, and state. Only usable for uids
332 * belonging to calling user. Result is not aggregated over time. This means buckets' start and
333 * end timestamps are going to be between 'startTime' and 'endTime' parameters. The uid is going
334 * to be the same as the 'uid' parameter, the tag the same as the 'tag' parameter, and the state
335 * the same as the 'state' parameter.
Lorenzo Colitti35c13e52018-01-19 01:12:58 +0900336 * defaultNetwork is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
337 * metered is going to be {@link NetworkStats.Bucket#METERED_ALL}, and
338 * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100339 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
340 * interpolate across partial buckets. Since bucket length is in the order of hours, this
341 * method cannot be used to measure data usage on a fine grained time scale.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000342 *
343 * @param networkType As defined in {@link ConnectivityManager}, e.g.
344 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
345 * etc.
346 * @param subscriberId If applicable, the subscriber id of the network interface.
347 * @param startTime Start of period. Defined in terms of "Unix time", see
348 * {@link java.lang.System#currentTimeMillis}.
349 * @param endTime End of period. Defined in terms of "Unix time", see
350 * {@link java.lang.System#currentTimeMillis}.
351 * @param uid UID of app
Antonio Cansado6965c182016-03-30 11:37:18 -0700352 * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for no tags.
Lorenzo Colitti53765e02018-04-06 22:56:52 +0900353 * @param state state of interest. Use {@link NetworkStats.Bucket#STATE_ALL} to aggregate
354 * traffic from all states.
Antonio Cansado904237f2016-05-25 09:57:21 -0700355 * @return Statistics object or null if an error happened during statistics collection.
356 * @throws SecurityException if permissions are insufficient to read network statistics.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000357 */
Lorenzo Colitti84b317c2018-04-02 16:48:31 +0900358 public NetworkStats queryDetailsForUidTagState(int networkType, String subscriberId,
359 long startTime, long endTime, int uid, int tag, int state) throws SecurityException {
Antonio Cansado6965c182016-03-30 11:37:18 -0700360 NetworkTemplate template;
Antonio Cansado904237f2016-05-25 09:57:21 -0700361 template = createTemplate(networkType, subscriberId);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000362
Lei Yuc00a30e2019-05-09 11:53:57 -0700363 return queryDetailsForUidTagState(template, startTime, endTime, uid, tag, state);
364 }
365
366 /** @hide */
367 public NetworkStats queryDetailsForUidTagState(NetworkTemplate template,
368 long startTime, long endTime, int uid, int tag, int state) throws SecurityException {
369
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +0100370 NetworkStats result;
Antonio Cansado6965c182016-03-30 11:37:18 -0700371 try {
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900372 result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
Lorenzo Colitti84b317c2018-04-02 16:48:31 +0900373 result.startHistoryEnumeration(uid, tag, state);
Antonio Cansado6965c182016-03-30 11:37:18 -0700374 } catch (RemoteException e) {
Lorenzo Colitti84b317c2018-04-02 16:48:31 +0900375 Log.e(TAG, "Error while querying stats for uid=" + uid + " tag=" + tag
376 + " state=" + state, e);
Antonio Cansado6965c182016-03-30 11:37:18 -0700377 return null;
378 }
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000379
380 return result;
381 }
382
383 /**
384 * Query network usage statistics details. Result filtered to include only uids belonging to
Stephen Chen25147872016-10-21 12:44:26 -0700385 * calling user. Result is aggregated over state but not aggregated over time, uid, tag,
386 * metered, nor roaming. This means buckets' start and end timestamps are going to be between
387 * 'startTime' and 'endTime' parameters. State is going to be
388 * {@link NetworkStats.Bucket#STATE_ALL}, uid will vary,
Lorenzo Colitti35c13e52018-01-19 01:12:58 +0900389 * tag {@link NetworkStats.Bucket#TAG_NONE},
390 * default network is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
391 * metered is going to be {@link NetworkStats.Bucket#METERED_ALL},
392 * and roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100393 * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
394 * interpolate across partial buckets. Since bucket length is in the order of hours, this
395 * method cannot be used to measure data usage on a fine grained time scale.
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000396 *
397 * @param networkType As defined in {@link ConnectivityManager}, e.g.
398 * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
399 * etc.
400 * @param subscriberId If applicable, the subscriber id of the network interface.
401 * @param startTime Start of period. Defined in terms of "Unix time", see
402 * {@link java.lang.System#currentTimeMillis}.
403 * @param endTime End of period. Defined in terms of "Unix time", see
404 * {@link java.lang.System#currentTimeMillis}.
405 * @return Statistics object or null if permissions are insufficient or error happened during
406 * statistics collection.
407 */
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +0100408 public NetworkStats queryDetails(int networkType, String subscriberId, long startTime,
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000409 long endTime) throws SecurityException, RemoteException {
Antonio Cansado6965c182016-03-30 11:37:18 -0700410 NetworkTemplate template;
411 try {
412 template = createTemplate(networkType, subscriberId);
413 } catch (IllegalArgumentException e) {
414 if (DBG) Log.e(TAG, "Cannot create template", e);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000415 return null;
416 }
Antonio Cansado6965c182016-03-30 11:37:18 -0700417
Zoltan Szatmary-Ban381483b2015-05-13 17:53:17 +0100418 NetworkStats result;
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900419 result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000420 result.startUserUidEnumeration();
421 return result;
422 }
423
Lorenzo Colittie0f69092018-01-22 21:00:49 +0900424 /** @hide */
425 public void registerUsageCallback(NetworkTemplate template, int networkType,
426 long thresholdBytes, UsageCallback callback, @Nullable Handler handler) {
junyulai232b2ed2020-01-13 14:36:55 +0800427 Objects.requireNonNull(callback, "UsageCallback cannot be null");
Lorenzo Colittie0f69092018-01-22 21:00:49 +0900428
429 final Looper looper;
430 if (handler == null) {
431 looper = Looper.myLooper();
432 } else {
433 looper = handler.getLooper();
434 }
435
436 DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET,
437 template, thresholdBytes);
438 try {
439 CallbackHandler callbackHandler = new CallbackHandler(looper, networkType,
440 template.getSubscriberId(), callback);
441 callback.request = mService.registerUsageCallback(
442 mContext.getOpPackageName(), request, new Messenger(callbackHandler),
443 new Binder());
444 if (DBG) Log.d(TAG, "registerUsageCallback returned " + callback.request);
445
446 if (callback.request == null) {
447 Log.e(TAG, "Request from callback is null; should not happen");
448 }
449 } catch (RemoteException e) {
450 if (DBG) Log.d(TAG, "Remote exception when registering callback");
451 throw e.rethrowFromSystemServer();
452 }
453 }
454
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800455 /**
Antonio Cansado6965c182016-03-30 11:37:18 -0700456 * Registers to receive notifications about data usage on specified networks.
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800457 *
Antonio Cansado6965c182016-03-30 11:37:18 -0700458 * #see registerUsageCallback(int, String[], long, UsageCallback, Handler)
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800459 */
Antonio Cansado6965c182016-03-30 11:37:18 -0700460 public void registerUsageCallback(int networkType, String subscriberId, long thresholdBytes,
461 UsageCallback callback) {
Antonio Cansadof7048372016-06-20 15:03:03 -0700462 registerUsageCallback(networkType, subscriberId, thresholdBytes, callback,
463 null /* handler */);
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800464 }
465
466 /**
Antonio Cansado6965c182016-03-30 11:37:18 -0700467 * Registers to receive notifications about data usage on specified networks.
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800468 *
Antonio Cansado6965c182016-03-30 11:37:18 -0700469 * <p>The callbacks will continue to be called as long as the process is live or
470 * {@link #unregisterUsageCallback} is called.
471 *
472 * @param networkType Type of network to monitor. Either
473 {@link ConnectivityManager#TYPE_MOBILE} or {@link ConnectivityManager#TYPE_WIFI}.
474 * @param subscriberId If applicable, the subscriber id of the network interface.
475 * @param thresholdBytes Threshold in bytes to be notified on.
476 * @param callback The {@link UsageCallback} that the system will call when data usage
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800477 * has exceeded the specified threshold.
478 * @param handler to dispatch callback events through, otherwise if {@code null} it uses
479 * the calling thread.
480 */
Antonio Cansado6965c182016-03-30 11:37:18 -0700481 public void registerUsageCallback(int networkType, String subscriberId, long thresholdBytes,
482 UsageCallback callback, @Nullable Handler handler) {
Lorenzo Colittie0f69092018-01-22 21:00:49 +0900483 NetworkTemplate template = createTemplate(networkType, subscriberId);
Antonio Cansado6965c182016-03-30 11:37:18 -0700484 if (DBG) {
485 Log.d(TAG, "registerUsageCallback called with: {"
486 + " networkType=" + networkType
487 + " subscriberId=" + subscriberId
488 + " thresholdBytes=" + thresholdBytes
489 + " }");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800490 }
Lorenzo Colittie0f69092018-01-22 21:00:49 +0900491 registerUsageCallback(template, networkType, thresholdBytes, callback, handler);
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800492 }
493
494 /**
495 * Unregisters callbacks on data usage.
496 *
Antonio Cansado6965c182016-03-30 11:37:18 -0700497 * @param callback The {@link UsageCallback} used when registering.
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800498 */
Antonio Cansado6965c182016-03-30 11:37:18 -0700499 public void unregisterUsageCallback(UsageCallback callback) {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800500 if (callback == null || callback.request == null
501 || callback.request.requestId == DataUsageRequest.REQUEST_ID_UNSET) {
Antonio Cansado6965c182016-03-30 11:37:18 -0700502 throw new IllegalArgumentException("Invalid UsageCallback");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800503 }
504 try {
Antonio Cansado6965c182016-03-30 11:37:18 -0700505 mService.unregisterUsageRequest(callback.request);
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800506 } catch (RemoteException e) {
507 if (DBG) Log.d(TAG, "Remote exception when unregistering callback");
Antonio Cansado6965c182016-03-30 11:37:18 -0700508 throw e.rethrowFromSystemServer();
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800509 }
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800510 }
511
Antonio Cansado6965c182016-03-30 11:37:18 -0700512 /**
513 * Base class for usage callbacks. Should be extended by applications wanting notifications.
514 */
515 public static abstract class UsageCallback {
516
517 /**
518 * Called when data usage has reached the given threshold.
519 */
520 public abstract void onThresholdReached(int networkType, String subscriberId);
521
522 /**
523 * @hide used for internal bookkeeping
524 */
Antonio Cansadoba8288d2015-12-02 08:42:54 -0800525 private DataUsageRequest request;
526 }
527
junyulai80831d22019-11-21 16:26:27 +0800528 /**
529 * Registers a custom provider of {@link android.net.NetworkStats} to combine the network
530 * statistics that cannot be seen by the kernel to system. To unregister, invoke
531 * {@link NetworkStatsProviderCallback#unregister()}.
532 *
533 * @param tag a human readable identifier of the custom network stats provider.
534 * @param provider a custom implementation of {@link AbstractNetworkStatsProvider} that needs to
535 * be registered to the system.
536 * @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the
537 * system.
538 * @hide
539 */
540 @SystemApi
541 @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
542 @NonNull public NetworkStatsProviderCallback registerNetworkStatsProvider(
543 @NonNull String tag,
544 @NonNull AbstractNetworkStatsProvider provider) {
545 try {
546 final NetworkStatsProviderWrapper wrapper = new NetworkStatsProviderWrapper(provider);
547 return new NetworkStatsProviderCallback(
548 mService.registerNetworkStatsProvider(tag, wrapper));
549 } catch (RemoteException e) {
550 e.rethrowAsRuntimeException();
551 }
552 // Unreachable code, but compiler doesn't know about it.
553 return null;
554 }
555
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000556 private static NetworkTemplate createTemplate(int networkType, String subscriberId) {
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900557 final NetworkTemplate template;
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000558 switch (networkType) {
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900559 case ConnectivityManager.TYPE_MOBILE:
560 template = subscriberId == null
561 ? NetworkTemplate.buildTemplateMobileWildcard()
562 : NetworkTemplate.buildTemplateMobileAll(subscriberId);
563 break;
564 case ConnectivityManager.TYPE_WIFI:
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000565 template = NetworkTemplate.buildTemplateWifiWildcard();
Remi NGUYEN VAN786b7ad2018-03-05 18:14:56 +0900566 break;
567 default:
Antonio Cansado6965c182016-03-30 11:37:18 -0700568 throw new IllegalArgumentException("Cannot create template for network type "
569 + networkType + ", subscriberId '"
570 + NetworkIdentity.scrubSubscriberId(subscriberId) + "'.");
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000571 }
572 return template;
573 }
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800574
575 private static class CallbackHandler extends Handler {
Antonio Cansado6965c182016-03-30 11:37:18 -0700576 private final int mNetworkType;
577 private final String mSubscriberId;
578 private UsageCallback mCallback;
579
580 CallbackHandler(Looper looper, int networkType, String subscriberId,
581 UsageCallback callback) {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800582 super(looper);
Antonio Cansado6965c182016-03-30 11:37:18 -0700583 mNetworkType = networkType;
584 mSubscriberId = subscriberId;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800585 mCallback = callback;
586 }
587
588 @Override
589 public void handleMessage(Message message) {
590 DataUsageRequest request =
591 (DataUsageRequest) getObject(message, DataUsageRequest.PARCELABLE_KEY);
592
593 switch (message.what) {
594 case CALLBACK_LIMIT_REACHED: {
595 if (mCallback != null) {
Antonio Cansado6965c182016-03-30 11:37:18 -0700596 mCallback.onThresholdReached(mNetworkType, mSubscriberId);
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800597 } else {
598 Log.e(TAG, "limit reached with released callback for " + request);
599 }
600 break;
601 }
602 case CALLBACK_RELEASED: {
603 if (DBG) Log.d(TAG, "callback released for " + request);
604 mCallback = null;
605 break;
606 }
607 }
608 }
609
610 private static Object getObject(Message msg, String key) {
611 return msg.getData().getParcelable(key);
612 }
613 }
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000614}