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