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