TrafficStats.java revision b09540f33a6cabe50edec0ef32d0b1d0b0d96fff
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    /**
45     * Special UID value used when collecting {@link NetworkStatsHistory} for
46     * removed applications.
47     *
48     * @hide
49     */
50    public static final int UID_REMOVED = -4;
51
52    /**
53     * Snapshot of {@link NetworkStats} when the currently active profiling
54     * session started, or {@code null} if no session active.
55     *
56     * @see #startDataProfiling(Context)
57     * @see #stopDataProfiling(Context)
58     */
59    private static NetworkStats sActiveProfilingStart;
60
61    private static Object sProfilingLock = new Object();
62
63    /**
64     * Set active tag to use when accounting {@link Socket} traffic originating
65     * from the current thread. Only one active tag per thread is supported.
66     * <p>
67     * Changes only take effect during subsequent calls to
68     * {@link #tagSocket(Socket)}.
69     */
70    public static void setThreadStatsTag(String tag) {
71        BlockGuard.setThreadSocketStatsTag(tag);
72    }
73
74    public static void clearThreadStatsTag() {
75        BlockGuard.setThreadSocketStatsTag(null);
76    }
77
78    /**
79     * Set specific UID to use when accounting {@link Socket} traffic
80     * originating from the current thread. Designed for use when performing an
81     * operation on behalf of another application.
82     * <p>
83     * Changes only take effect during subsequent calls to
84     * {@link #tagSocket(Socket)}.
85     * <p>
86     * To take effect, caller must hold
87     * {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission.
88     *
89     * {@hide}
90     */
91    public static void setThreadStatsUid(int uid) {
92        BlockGuard.setThreadSocketStatsUid(uid);
93    }
94
95    /** {@hide} */
96    public static void clearThreadStatsUid() {
97        BlockGuard.setThreadSocketStatsUid(-1);
98    }
99
100    /**
101     * Tag the given {@link Socket} with any statistics parameters active for
102     * the current thread. Subsequent calls always replace any existing
103     * parameters. When finished, call {@link #untagSocket(Socket)} to remove
104     * statistics parameters.
105     *
106     * @see #setThreadStatsTag(String)
107     * @see #setThreadStatsUid(int)
108     */
109    public static void tagSocket(Socket socket) throws SocketException {
110        BlockGuard.tagSocketFd(socket.getFileDescriptor$());
111    }
112
113    /**
114     * Remove any statistics parameters from the given {@link Socket}.
115     */
116    public static void untagSocket(Socket socket) throws SocketException {
117        BlockGuard.untagSocketFd(socket.getFileDescriptor$());
118    }
119
120    /**
121     * Start profiling data usage for current UID. Only one profiling session
122     * can be active at a time.
123     *
124     * @hide
125     */
126    public static void startDataProfiling(Context context) {
127        synchronized (sProfilingLock) {
128            if (sActiveProfilingStart != null) {
129                throw new IllegalStateException("already profiling data");
130            }
131
132            // take snapshot in time; we calculate delta later
133            sActiveProfilingStart = getNetworkStatsForUid(context);
134        }
135    }
136
137    /**
138     * Stop profiling data usage for current UID.
139     *
140     * @return Detailed {@link NetworkStats} of data that occurred since last
141     *         {@link #startDataProfiling(Context)} call.
142     * @hide
143     */
144    public static NetworkStats stopDataProfiling(Context context) {
145        synchronized (sProfilingLock) {
146            if (sActiveProfilingStart == null) {
147                throw new IllegalStateException("not profiling data");
148            }
149
150            // subtract starting values and return delta
151            final NetworkStats profilingStop = getNetworkStatsForUid(context);
152            final NetworkStats profilingDelta = profilingStop.subtractClamped(
153                    sActiveProfilingStart);
154            sActiveProfilingStart = null;
155            return profilingDelta;
156        }
157    }
158
159    /**
160     * Get the total number of packets transmitted through the mobile interface.
161     *
162     * @return number of packets.  If the statistics are not supported by this device,
163     * {@link #UNSUPPORTED} will be returned.
164     */
165    public static native long getMobileTxPackets();
166
167    /**
168     * Get the total number of packets received through the mobile interface.
169     *
170     * @return number of packets.  If the statistics are not supported by this device,
171     * {@link #UNSUPPORTED} will be returned.
172     */
173    public static native long getMobileRxPackets();
174
175    /**
176     * Get the total number of bytes transmitted through the mobile interface.
177     *
178     * @return number of bytes.  If the statistics are not supported by this device,
179     * {@link #UNSUPPORTED} will be returned.
180     */
181      public static native long getMobileTxBytes();
182
183    /**
184     * Get the total number of bytes received through the mobile interface.
185     *
186     * @return number of bytes.  If the statistics are not supported by this device,
187     * {@link #UNSUPPORTED} will be returned.
188     */
189    public static native long getMobileRxBytes();
190
191    /**
192     * Get the total number of packets transmitted through the specified interface.
193     *
194     * @return number of packets.  If the statistics are not supported by this interface,
195     * {@link #UNSUPPORTED} will be returned.
196     * @hide
197     */
198    public static native long getTxPackets(String iface);
199
200    /**
201     * Get the total number of packets received through the specified interface.
202     *
203     * @return number of packets.  If the statistics are not supported by this interface,
204     * {@link #UNSUPPORTED} will be returned.
205     * @hide
206     */
207    public static native long getRxPackets(String iface);
208
209    /**
210     * Get the total number of bytes transmitted through the specified interface.
211     *
212     * @return number of bytes.  If the statistics are not supported by this interface,
213     * {@link #UNSUPPORTED} will be returned.
214     * @hide
215     */
216    public static native long getTxBytes(String iface);
217
218    /**
219     * Get the total number of bytes received through the specified interface.
220     *
221     * @return number of bytes.  If the statistics are not supported by this interface,
222     * {@link #UNSUPPORTED} will be returned.
223     * @hide
224     */
225    public static native long getRxBytes(String iface);
226
227
228    /**
229     * Get the total number of packets sent through all network interfaces.
230     *
231     * @return the number of packets.  If the statistics are not supported by this device,
232     * {@link #UNSUPPORTED} will be returned.
233     */
234    public static native long getTotalTxPackets();
235
236    /**
237     * Get the total number of packets received through all network interfaces.
238     *
239     * @return number of packets.  If the statistics are not supported by this device,
240     * {@link #UNSUPPORTED} will be returned.
241     */
242    public static native long getTotalRxPackets();
243
244    /**
245     * Get the total number of bytes sent through all network interfaces.
246     *
247     * @return number of bytes.  If the statistics are not supported by this device,
248     * {@link #UNSUPPORTED} will be returned.
249     */
250    public static native long getTotalTxBytes();
251
252    /**
253     * Get the total number of bytes received through all network interfaces.
254     *
255     * @return number of bytes.  If the statistics are not supported by this device,
256     * {@link #UNSUPPORTED} will be returned.
257     */
258    public static native long getTotalRxBytes();
259
260    /**
261     * Get the number of bytes sent through the network for this UID.
262     * The statistics are across all interfaces.
263     *
264     * {@see android.os.Process#myUid()}.
265     *
266     * @param uid The UID of the process to examine.
267     * @return number of bytes.  If the statistics are not supported by this device,
268     * {@link #UNSUPPORTED} will be returned.
269     */
270    public static native long getUidTxBytes(int uid);
271
272    /**
273     * Get the number of bytes received through the network for this UID.
274     * The statistics are across all interfaces.
275     *
276     * {@see android.os.Process#myUid()}.
277     *
278     * @param uid The UID of the process to examine.
279     * @return number of bytes
280     */
281    public static native long getUidRxBytes(int uid);
282
283    /**
284     * Get the number of packets (TCP segments + UDP) sent through
285     * the network for this UID.
286     * The statistics are across all interfaces.
287     *
288     * {@see android.os.Process#myUid()}.
289     *
290     * @param uid The UID of the process to examine.
291     * @return number of packets.
292     * If the statistics are not supported by this device,
293     * {@link #UNSUPPORTED} will be returned.
294     */
295    public static native long getUidTxPackets(int uid);
296
297    /**
298     * Get the number of packets (TCP segments + UDP) received through
299     * the network for this UID.
300     * The statistics are across all interfaces.
301     *
302     * {@see android.os.Process#myUid()}.
303     *
304     * @param uid The UID of the process to examine.
305     * @return number of packets
306     */
307    public static native long getUidRxPackets(int uid);
308
309    /**
310     * Get the number of TCP payload bytes sent for this UID.
311     * This total does not include protocol and control overheads at
312     * the transport and the lower layers of the networking stack.
313     * The statistics are across all interfaces.
314     *
315     * {@see android.os.Process#myUid()}.
316     *
317     * @param uid The UID of the process to examine.
318     * @return number of bytes.  If the statistics are not supported by this device,
319     * {@link #UNSUPPORTED} will be returned.
320     */
321    public static native long getUidTcpTxBytes(int uid);
322
323    /**
324     * Get the number of TCP payload bytes received for this UID.
325     * This total does not include protocol and control overheads at
326     * the transport and the lower layers of the networking stack.
327     * The statistics are across all interfaces.
328     *
329     * {@see android.os.Process#myUid()}.
330     *
331     * @param uid The UID of the process to examine.
332     * @return number of bytes.  If the statistics are not supported by this device,
333     * {@link #UNSUPPORTED} will be returned.
334     */
335    public static native long getUidTcpRxBytes(int uid);
336
337    /**
338     * Get the number of UDP 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 getUidUdpTxBytes(int uid);
350
351    /**
352     * Get the number of UDP 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 getUidUdpRxBytes(int uid);
364
365    /**
366     * Get the number of TCP segments sent for this UID.
367     * Does not include TCP control packets (SYN/ACKs/FIN/..).
368     * The statistics are across all interfaces.
369     *
370     * {@see android.os.Process#myUid()}.
371     *
372     * @param uid The UID of the process to examine.
373     * @return number of TCP segments.  If the statistics are not supported by this device,
374     * {@link #UNSUPPORTED} will be returned.
375     */
376    public static native long getUidTcpTxSegments(int uid);
377
378    /**
379     * Get the number of TCP segments received for this UID.
380     * Does not include TCP control packets (SYN/ACKs/FIN/..).
381     * The statistics are across all interfaces.
382     *
383     * {@see android.os.Process#myUid()}.
384     *
385     * @param uid The UID of the process to examine.
386     * @return number of TCP segments.  If the statistics are not supported by this device,
387     * {@link #UNSUPPORTED} will be returned.
388     */
389    public static native long getUidTcpRxSegments(int uid);
390
391
392    /**
393     * Get the number of UDP packets sent for this UID.
394     * Includes DNS requests.
395     * The statistics are across all interfaces.
396     *
397     * {@see android.os.Process#myUid()}.
398     *
399     * @param uid The UID of the process to examine.
400     * @return number of packets.  If the statistics are not supported by this device,
401     * {@link #UNSUPPORTED} will be returned.
402     */
403    public static native long getUidUdpTxPackets(int uid);
404
405    /**
406     * Get the number of UDP packets received for this UID.
407     * Includes DNS responses.
408     * The statistics are across all interfaces.
409     *
410     * {@see android.os.Process#myUid()}.
411     *
412     * @param uid The UID of the process to examine.
413     * @return number of packets.  If the statistics are not supported by this device,
414     * {@link #UNSUPPORTED} will be returned.
415     */
416    public static native long getUidUdpRxPackets(int uid);
417
418    /**
419     * Return detailed {@link NetworkStats} for the current UID. Requires no
420     * special permission.
421     */
422    private static NetworkStats getNetworkStatsForUid(Context context) {
423        final IBinder binder = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
424        final INetworkManagementService service = INetworkManagementService.Stub.asInterface(
425                binder);
426
427        final int uid = android.os.Process.myUid();
428        try {
429            return service.getNetworkStatsUidDetail(uid);
430        } catch (RemoteException e) {
431            throw new RuntimeException(e);
432        }
433    }
434}
435