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