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