TrafficStats.java revision d2a458750e5a3d490af09cecb5c28370baf0a913
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy 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,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
19import android.content.Context;
20import android.os.IBinder;
21import android.os.INetworkManagementService;
22import android.os.RemoteException;
23import android.os.ServiceManager;
24
25import dalvik.system.BlockGuard;
26
27import java.net.Socket;
28import java.net.SocketException;
29
30/**
31 * Class that provides network traffic statistics.  These statistics include
32 * bytes transmitted and received and network packets transmitted and received,
33 * over all interfaces, over the mobile interface, and on a per-UID basis.
34 * <p>
35 * These statistics may not be available on all platforms.  If the statistics
36 * are not supported by this device, {@link #UNSUPPORTED} will be returned.
37 */
38public class TrafficStats {
39    /**
40     * The return value to indicate that the device does not support the statistic.
41     */
42    public final static int UNSUPPORTED = -1;
43
44    // TODO: find better home for these template constants
45
46    /**
47     * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
48     * networks together. Only uses statistics for currently active IMSI.
49     *
50     * @hide
51     */
52    public static final int TEMPLATE_MOBILE_ALL = 1;
53
54    /**
55     * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
56     * networks together that roughly meet a "3G" definition, or lower. Only
57     * uses statistics for currently active IMSI.
58     *
59     * @hide
60     */
61    public static final int TEMPLATE_MOBILE_3G_LOWER = 2;
62
63    /**
64     * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
65     * networks together that meet a "4G" definition. Only uses statistics for
66     * currently active IMSI.
67     *
68     * @hide
69     */
70    public static final int TEMPLATE_MOBILE_4G = 3;
71
72    /**
73     * Template to combine all {@link ConnectivityManager#TYPE_WIFI} style
74     * networks together.
75     *
76     * @hide
77     */
78    public static final int TEMPLATE_WIFI = 4;
79
80    /**
81     * Snapshot of {@link NetworkStats} when the currently active profiling
82     * session started, or {@code null} if no session active.
83     *
84     * @see #startDataProfiling(Context)
85     * @see #stopDataProfiling(Context)
86     */
87    private static NetworkStats sActiveProfilingStart;
88
89    private static Object sProfilingLock = new Object();
90
91    /**
92     * Set active tag to use when accounting {@link Socket} traffic originating
93     * from the current thread. Only one active tag per thread is supported.
94     * <p>
95     * Changes only take effect during subsequent calls to
96     * {@link #tagSocket(Socket)}.
97     */
98    public static void setThreadStatsTag(String tag) {
99        BlockGuard.setThreadSocketStatsTag(tag);
100    }
101
102    public static void clearThreadStatsTag() {
103        BlockGuard.setThreadSocketStatsTag(null);
104    }
105
106    /**
107     * Set specific UID to use when accounting {@link Socket} traffic
108     * originating from the current thread. Designed for use when performing an
109     * operation on behalf of another application.
110     * <p>
111     * Changes only take effect during subsequent calls to
112     * {@link #tagSocket(Socket)}.
113     * <p>
114     * To take effect, caller must hold
115     * {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission.
116     *
117     * {@hide}
118     */
119    public static void setThreadStatsUid(int uid) {
120        BlockGuard.setThreadSocketStatsUid(uid);
121    }
122
123    /** {@hide} */
124    public static void clearThreadStatsUid() {
125        BlockGuard.setThreadSocketStatsUid(-1);
126    }
127
128    /**
129     * Tag the given {@link Socket} with any statistics parameters active for
130     * the current thread. Subsequent calls always replace any existing
131     * parameters. When finished, call {@link #untagSocket(Socket)} to remove
132     * statistics parameters.
133     *
134     * @see #setThreadStatsTag(String)
135     * @see #setThreadStatsUid(int)
136     */
137    public static void tagSocket(Socket socket) throws SocketException {
138        BlockGuard.tagSocketFd(socket.getFileDescriptor$());
139    }
140
141    /**
142     * Remove any statistics parameters from the given {@link Socket}.
143     */
144    public static void untagSocket(Socket socket) throws SocketException {
145        BlockGuard.untagSocketFd(socket.getFileDescriptor$());
146    }
147
148    /**
149     * Start profiling data usage for current UID. Only one profiling session
150     * can be active at a time.
151     *
152     * @hide
153     */
154    public static void startDataProfiling(Context context) {
155        synchronized (sProfilingLock) {
156            if (sActiveProfilingStart != null) {
157                throw new IllegalStateException("already profiling data");
158            }
159
160            // take snapshot in time; we calculate delta later
161            sActiveProfilingStart = getNetworkStatsForUid(context);
162        }
163    }
164
165    /**
166     * Stop profiling data usage for current UID.
167     *
168     * @return Detailed {@link NetworkStats} of data that occurred since last
169     *         {@link #startDataProfiling(Context)} call.
170     * @hide
171     */
172    public static NetworkStats stopDataProfiling(Context context) {
173        synchronized (sProfilingLock) {
174            if (sActiveProfilingStart == null) {
175                throw new IllegalStateException("not profiling data");
176            }
177
178            // subtract starting values and return delta
179            final NetworkStats profilingStop = getNetworkStatsForUid(context);
180            final NetworkStats profilingDelta = profilingStop.subtract(
181                    sActiveProfilingStart, false);
182            sActiveProfilingStart = null;
183            return profilingDelta;
184        }
185    }
186
187    /**
188     * Get the total number of packets transmitted through the mobile interface.
189     *
190     * @return number of packets.  If the statistics are not supported by this device,
191     * {@link #UNSUPPORTED} will be returned.
192     */
193    public static native long getMobileTxPackets();
194
195    /**
196     * Get the total number of packets received through the mobile interface.
197     *
198     * @return number of packets.  If the statistics are not supported by this device,
199     * {@link #UNSUPPORTED} will be returned.
200     */
201    public static native long getMobileRxPackets();
202
203    /**
204     * Get the total number of bytes transmitted through the mobile interface.
205     *
206     * @return number of bytes.  If the statistics are not supported by this device,
207     * {@link #UNSUPPORTED} will be returned.
208     */
209      public static native long getMobileTxBytes();
210
211    /**
212     * Get the total number of bytes received through the mobile interface.
213     *
214     * @return number of bytes.  If the statistics are not supported by this device,
215     * {@link #UNSUPPORTED} will be returned.
216     */
217    public static native long getMobileRxBytes();
218
219    /**
220     * Get the total number of packets transmitted through the specified interface.
221     *
222     * @return number of packets.  If the statistics are not supported by this interface,
223     * {@link #UNSUPPORTED} will be returned.
224     * @hide
225     */
226    public static native long getTxPackets(String iface);
227
228    /**
229     * Get the total number of packets received through the specified interface.
230     *
231     * @return number of packets.  If the statistics are not supported by this interface,
232     * {@link #UNSUPPORTED} will be returned.
233     * @hide
234     */
235    public static native long getRxPackets(String iface);
236
237    /**
238     * Get the total number of bytes transmitted through the specified interface.
239     *
240     * @return number of bytes.  If the statistics are not supported by this interface,
241     * {@link #UNSUPPORTED} will be returned.
242     * @hide
243     */
244    public static native long getTxBytes(String iface);
245
246    /**
247     * Get the total number of bytes received through the specified interface.
248     *
249     * @return number of bytes.  If the statistics are not supported by this interface,
250     * {@link #UNSUPPORTED} will be returned.
251     * @hide
252     */
253    public static native long getRxBytes(String iface);
254
255
256    /**
257     * Get the total number of packets sent through all network interfaces.
258     *
259     * @return the number of packets.  If the statistics are not supported by this device,
260     * {@link #UNSUPPORTED} will be returned.
261     */
262    public static native long getTotalTxPackets();
263
264    /**
265     * Get the total number of packets received through all network interfaces.
266     *
267     * @return number of packets.  If the statistics are not supported by this device,
268     * {@link #UNSUPPORTED} will be returned.
269     */
270    public static native long getTotalRxPackets();
271
272    /**
273     * Get the total number of bytes sent through all network interfaces.
274     *
275     * @return number of bytes.  If the statistics are not supported by this device,
276     * {@link #UNSUPPORTED} will be returned.
277     */
278    public static native long getTotalTxBytes();
279
280    /**
281     * Get the total number of bytes received through all network interfaces.
282     *
283     * @return number of bytes.  If the statistics are not supported by this device,
284     * {@link #UNSUPPORTED} will be returned.
285     */
286    public static native long getTotalRxBytes();
287
288    /**
289     * Get the number of bytes sent through the network for this UID.
290     * The statistics are across all interfaces.
291     *
292     * {@see android.os.Process#myUid()}.
293     *
294     * @param uid The UID of the process to examine.
295     * @return number of bytes.  If the statistics are not supported by this device,
296     * {@link #UNSUPPORTED} will be returned.
297     */
298    public static native long getUidTxBytes(int uid);
299
300    /**
301     * Get the number of bytes received through the network for this UID.
302     * The statistics are across all interfaces.
303     *
304     * {@see android.os.Process#myUid()}.
305     *
306     * @param uid The UID of the process to examine.
307     * @return number of bytes
308     */
309    public static native long getUidRxBytes(int uid);
310
311    /**
312     * Get the number of packets (TCP segments + UDP) sent through
313     * the network for this UID.
314     * The statistics are across all interfaces.
315     *
316     * {@see android.os.Process#myUid()}.
317     *
318     * @param uid The UID of the process to examine.
319     * @return number of packets.
320     * If the statistics are not supported by this device,
321     * {@link #UNSUPPORTED} will be returned.
322     */
323    public static native long getUidTxPackets(int uid);
324
325    /**
326     * Get the number of packets (TCP segments + UDP) received through
327     * the network for this UID.
328     * The statistics are across all interfaces.
329     *
330     * {@see android.os.Process#myUid()}.
331     *
332     * @param uid The UID of the process to examine.
333     * @return number of packets
334     */
335    public static native long getUidRxPackets(int uid);
336
337    /**
338     * Get the number of TCP payload bytes sent for this UID.
339     * This total does not include protocol and control overheads at
340     * the transport and the lower layers of the networking stack.
341     * The statistics are across all interfaces.
342     *
343     * {@see android.os.Process#myUid()}.
344     *
345     * @param uid The UID of the process to examine.
346     * @return number of bytes.  If the statistics are not supported by this device,
347     * {@link #UNSUPPORTED} will be returned.
348     */
349    public static native long getUidTcpTxBytes(int uid);
350
351    /**
352     * Get the number of TCP payload bytes received for this UID.
353     * This total does not include protocol and control overheads at
354     * the transport and the lower layers of the networking stack.
355     * The statistics are across all interfaces.
356     *
357     * {@see android.os.Process#myUid()}.
358     *
359     * @param uid The UID of the process to examine.
360     * @return number of bytes.  If the statistics are not supported by this device,
361     * {@link #UNSUPPORTED} will be returned.
362     */
363    public static native long getUidTcpRxBytes(int uid);
364
365    /**
366     * Get the number of UDP payload bytes sent for this UID.
367     * This total does not include protocol and control overheads at
368     * the transport and the lower layers of the networking stack.
369     * The statistics are across all interfaces.
370     *
371     * {@see android.os.Process#myUid()}.
372     *
373     * @param uid The UID of the process to examine.
374     * @return number of bytes.  If the statistics are not supported by this device,
375     * {@link #UNSUPPORTED} will be returned.
376     */
377    public static native long getUidUdpTxBytes(int uid);
378
379    /**
380     * Get the number of UDP payload bytes received for this UID.
381     * This total does not include protocol and control overheads at
382     * the transport and the lower layers of the networking stack.
383     * The statistics are across all interfaces.
384     *
385     * {@see android.os.Process#myUid()}.
386     *
387     * @param uid The UID of the process to examine.
388     * @return number of bytes.  If the statistics are not supported by this device,
389     * {@link #UNSUPPORTED} will be returned.
390     */
391    public static native long getUidUdpRxBytes(int uid);
392
393    /**
394     * Get the number of TCP segments sent for this UID.
395     * Does not include TCP control packets (SYN/ACKs/FIN/..).
396     * The statistics are across all interfaces.
397     *
398     * {@see android.os.Process#myUid()}.
399     *
400     * @param uid The UID of the process to examine.
401     * @return number of TCP segments.  If the statistics are not supported by this device,
402     * {@link #UNSUPPORTED} will be returned.
403     */
404    public static native long getUidTcpTxSegments(int uid);
405
406    /**
407     * Get the number of TCP segments received for this UID.
408     * Does not include TCP control packets (SYN/ACKs/FIN/..).
409     * The statistics are across all interfaces.
410     *
411     * {@see android.os.Process#myUid()}.
412     *
413     * @param uid The UID of the process to examine.
414     * @return number of TCP segments.  If the statistics are not supported by this device,
415     * {@link #UNSUPPORTED} will be returned.
416     */
417    public static native long getUidTcpRxSegments(int uid);
418
419
420    /**
421     * Get the number of UDP packets sent for this UID.
422     * Includes DNS requests.
423     * The statistics are across all interfaces.
424     *
425     * {@see android.os.Process#myUid()}.
426     *
427     * @param uid The UID of the process to examine.
428     * @return number of packets.  If the statistics are not supported by this device,
429     * {@link #UNSUPPORTED} will be returned.
430     */
431    public static native long getUidUdpTxPackets(int uid);
432
433    /**
434     * Get the number of UDP packets received for this UID.
435     * Includes DNS responses.
436     * The statistics are across all interfaces.
437     *
438     * {@see android.os.Process#myUid()}.
439     *
440     * @param uid The UID of the process to examine.
441     * @return number of packets.  If the statistics are not supported by this device,
442     * {@link #UNSUPPORTED} will be returned.
443     */
444    public static native long getUidUdpRxPackets(int uid);
445
446    /**
447     * Return detailed {@link NetworkStats} for the current UID. Requires no
448     * special permission.
449     */
450    private static NetworkStats getNetworkStatsForUid(Context context) {
451        final IBinder binder = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
452        final INetworkManagementService service = INetworkManagementService.Stub.asInterface(
453                binder);
454
455        final int uid = android.os.Process.myUid();
456        try {
457            return service.getNetworkStatsUidDetail(uid);
458        } catch (RemoteException e) {
459            throw new RuntimeException(e);
460        }
461    }
462}
463