TrafficStats.java revision b52e3e55098c4a6e3dbfe19885895411cfb38911
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.app.DownloadManager;
20import android.app.backup.BackupManager;
21import android.content.Context;
22import android.media.MediaPlayer;
23import android.os.RemoteException;
24import android.os.ServiceManager;
25
26import com.android.server.NetworkManagementSocketTagger;
27
28import dalvik.system.SocketTagger;
29
30import java.net.Socket;
31import java.net.SocketException;
32
33/**
34 * Class that provides network traffic statistics.  These statistics include
35 * bytes transmitted and received and network packets transmitted and received,
36 * over all interfaces, over the mobile interface, and on a per-UID basis.
37 * <p>
38 * These statistics may not be available on all platforms.  If the statistics
39 * are not supported by this device, {@link #UNSUPPORTED} will be returned.
40 */
41public class TrafficStats {
42    /**
43     * The return value to indicate that the device does not support the statistic.
44     */
45    public final static int UNSUPPORTED = -1;
46
47    /** @hide */
48    public static final long KB_IN_BYTES = 1024;
49    /** @hide */
50    public static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
51    /** @hide */
52    public static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
53
54    /**
55     * Special UID value used when collecting {@link NetworkStatsHistory} for
56     * removed applications.
57     *
58     * @hide
59     */
60    public static final int UID_REMOVED = -4;
61
62    /**
63     * Special UID value used when collecting {@link NetworkStatsHistory} for
64     * tethering traffic.
65     *
66     * @hide
67     */
68    public static final int UID_TETHERING = -5;
69
70    /**
71     * Default tag value for {@link DownloadManager} traffic.
72     *
73     * @hide
74     */
75    public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFFFF01;
76
77    /**
78     * Default tag value for {@link MediaPlayer} traffic.
79     *
80     * @hide
81     */
82    public static final int TAG_SYSTEM_MEDIA = 0xFFFFFF02;
83
84    /**
85     * Default tag value for {@link BackupManager} traffic.
86     *
87     * @hide
88     */
89    public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03;
90
91    /**
92     * Snapshot of {@link NetworkStats} when the currently active profiling
93     * session started, or {@code null} if no session active.
94     *
95     * @see #startDataProfiling(Context)
96     * @see #stopDataProfiling(Context)
97     */
98    private static NetworkStats sActiveProfilingStart;
99
100    private static Object sProfilingLock = new Object();
101
102    /**
103     * Set active tag to use when accounting {@link Socket} traffic originating
104     * from the current thread. Only one active tag per thread is supported.
105     * <p>
106     * Changes only take effect during subsequent calls to
107     * {@link #tagSocket(Socket)}.
108     * <p>
109     * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
110     * used internally by system services like {@link DownloadManager} when
111     * performing traffic on behalf of an application.
112     */
113    public static void setThreadStatsTag(int tag) {
114        NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
115    }
116
117    /**
118     * Get the active tag used when accounting {@link Socket} traffic originating
119     * from the current thread. Only one active tag per thread is supported.
120     * {@link #tagSocket(Socket)}.
121     */
122    public static int getThreadStatsTag() {
123        return NetworkManagementSocketTagger.getThreadSocketStatsTag();
124    }
125
126    public static void clearThreadStatsTag() {
127        NetworkManagementSocketTagger.setThreadSocketStatsTag(-1);
128    }
129
130    /**
131     * Set specific UID to use when accounting {@link Socket} traffic
132     * originating from the current thread. Designed for use when performing an
133     * operation on behalf of another application.
134     * <p>
135     * Changes only take effect during subsequent calls to
136     * {@link #tagSocket(Socket)}.
137     * <p>
138     * To take effect, caller must hold
139     * {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission.
140     *
141     * {@hide}
142     */
143    public static void setThreadStatsUid(int uid) {
144        NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
145    }
146
147    /** {@hide} */
148    public static void clearThreadStatsUid() {
149        NetworkManagementSocketTagger.setThreadSocketStatsUid(-1);
150    }
151
152    /**
153     * Tag the given {@link Socket} with any statistics parameters active for
154     * the current thread. Subsequent calls always replace any existing
155     * parameters. When finished, call {@link #untagSocket(Socket)} to remove
156     * statistics parameters.
157     *
158     * @see #setThreadStatsTag(int)
159     * @see #setThreadStatsUid(int)
160     */
161    public static void tagSocket(Socket socket) throws SocketException {
162        SocketTagger.get().tag(socket);
163    }
164
165    /**
166     * Remove any statistics parameters from the given {@link Socket}.
167     */
168    public static void untagSocket(Socket socket) throws SocketException {
169        SocketTagger.get().untag(socket);
170    }
171
172    /**
173     * Start profiling data usage for current UID. Only one profiling session
174     * can be active at a time.
175     *
176     * @hide
177     */
178    public static void startDataProfiling(Context context) {
179        synchronized (sProfilingLock) {
180            if (sActiveProfilingStart != null) {
181                throw new IllegalStateException("already profiling data");
182            }
183
184            // take snapshot in time; we calculate delta later
185            sActiveProfilingStart = getDataLayerSnapshotForUid(context);
186        }
187    }
188
189    /**
190     * Stop profiling data usage for current UID.
191     *
192     * @return Detailed {@link NetworkStats} of data that occurred since last
193     *         {@link #startDataProfiling(Context)} call.
194     * @hide
195     */
196    public static NetworkStats stopDataProfiling(Context context) {
197        synchronized (sProfilingLock) {
198            if (sActiveProfilingStart == null) {
199                throw new IllegalStateException("not profiling data");
200            }
201
202            // subtract starting values and return delta
203            final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
204            final NetworkStats profilingDelta = NetworkStats.subtract(
205                    profilingStop, sActiveProfilingStart, null, null);
206            sActiveProfilingStart = null;
207            return profilingDelta;
208        }
209    }
210
211    /**
212     * Increment count of network operations performed under the accounting tag
213     * currently active on the calling thread. This can be used to derive
214     * bytes-per-operation.
215     *
216     * @param operationCount Number of operations to increment count by.
217     */
218    public static void incrementOperationCount(int operationCount) {
219        final int tag = getThreadStatsTag();
220        incrementOperationCount(tag, operationCount);
221    }
222
223    /**
224     * Increment count of network operations performed under the given
225     * accounting tag. This can be used to derive bytes-per-operation.
226     *
227     * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}.
228     * @param operationCount Number of operations to increment count by.
229     */
230    public static void incrementOperationCount(int tag, int operationCount) {
231        final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
232                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
233        final int uid = android.os.Process.myUid();
234        try {
235            statsService.incrementOperationCount(uid, tag, operationCount);
236        } catch (RemoteException e) {
237            throw new RuntimeException(e);
238        }
239    }
240
241    /** {@hide} */
242    public static void closeQuietly(INetworkStatsSession session) {
243        // TODO: move to NetworkStatsService once it exists
244        if (session != null) {
245            try {
246                session.close();
247            } catch (RuntimeException rethrown) {
248                throw rethrown;
249            } catch (Exception ignored) {
250            }
251        }
252    }
253
254    /**
255     * Get the total number of packets transmitted through the mobile interface.
256     *
257     * @return number of packets.  If the statistics are not supported by this device,
258     * {@link #UNSUPPORTED} will be returned.
259     */
260    public static native long getMobileTxPackets();
261
262    /**
263     * Get the total number of packets received through the mobile interface.
264     *
265     * @return number of packets.  If the statistics are not supported by this device,
266     * {@link #UNSUPPORTED} will be returned.
267     */
268    public static native long getMobileRxPackets();
269
270    /**
271     * Get the total number of bytes transmitted through the mobile interface.
272     *
273     * @return number of bytes.  If the statistics are not supported by this device,
274     * {@link #UNSUPPORTED} will be returned.
275     */
276      public static native long getMobileTxBytes();
277
278    /**
279     * Get the total number of bytes received through the mobile interface.
280     *
281     * @return number of bytes.  If the statistics are not supported by this device,
282     * {@link #UNSUPPORTED} will be returned.
283     */
284    public static native long getMobileRxBytes();
285
286    /**
287     * Get the total number of packets transmitted through the specified interface.
288     *
289     * @return number of packets.  If the statistics are not supported by this interface,
290     * {@link #UNSUPPORTED} will be returned.
291     * @hide
292     */
293    public static native long getTxPackets(String iface);
294
295    /**
296     * Get the total number of packets received through the specified interface.
297     *
298     * @return number of packets.  If the statistics are not supported by this interface,
299     * {@link #UNSUPPORTED} will be returned.
300     * @hide
301     */
302    public static native long getRxPackets(String iface);
303
304    /**
305     * Get the total number of bytes transmitted through the specified interface.
306     *
307     * @return number of bytes.  If the statistics are not supported by this interface,
308     * {@link #UNSUPPORTED} will be returned.
309     * @hide
310     */
311    public static native long getTxBytes(String iface);
312
313    /**
314     * Get the total number of bytes received through the specified interface.
315     *
316     * @return number of bytes.  If the statistics are not supported by this interface,
317     * {@link #UNSUPPORTED} will be returned.
318     * @hide
319     */
320    public static native long getRxBytes(String iface);
321
322
323    /**
324     * Get the total number of packets sent through all network interfaces.
325     *
326     * @return the number of packets.  If the statistics are not supported by this device,
327     * {@link #UNSUPPORTED} will be returned.
328     */
329    public static native long getTotalTxPackets();
330
331    /**
332     * Get the total number of packets received through all network interfaces.
333     *
334     * @return number of packets.  If the statistics are not supported by this device,
335     * {@link #UNSUPPORTED} will be returned.
336     */
337    public static native long getTotalRxPackets();
338
339    /**
340     * Get the total number of bytes sent through all network interfaces.
341     *
342     * @return number of bytes.  If the statistics are not supported by this device,
343     * {@link #UNSUPPORTED} will be returned.
344     */
345    public static native long getTotalTxBytes();
346
347    /**
348     * Get the total number of bytes received through all network interfaces.
349     *
350     * @return number of bytes.  If the statistics are not supported by this device,
351     * {@link #UNSUPPORTED} will be returned.
352     */
353    public static native long getTotalRxBytes();
354
355    /**
356     * Get the number of bytes sent through the network for this UID.
357     * The statistics are across all interfaces.
358     *
359     * {@see android.os.Process#myUid()}.
360     *
361     * @param uid The UID of the process to examine.
362     * @return number of bytes.  If the statistics are not supported by this device,
363     * {@link #UNSUPPORTED} will be returned.
364     */
365    public static native long getUidTxBytes(int uid);
366
367    /**
368     * Get the number of bytes received through the network for this UID.
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
375     */
376    public static native long getUidRxBytes(int uid);
377
378    /**
379     * Get the number of packets (TCP segments + UDP) sent through
380     * the network for this UID.
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 packets.
387     * If the statistics are not supported by this device,
388     * {@link #UNSUPPORTED} will be returned.
389     */
390    public static native long getUidTxPackets(int uid);
391
392    /**
393     * Get the number of packets (TCP segments + UDP) received through
394     * the network for this UID.
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
401     */
402    public static native long getUidRxPackets(int uid);
403
404    /**
405     * Get the number of TCP payload bytes sent for this UID.
406     * This total does not include protocol and control overheads at
407     * the transport and the lower layers of the networking stack.
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 bytes.  If the statistics are not supported by this device,
414     * {@link #UNSUPPORTED} will be returned.
415     */
416    public static native long getUidTcpTxBytes(int uid);
417
418    /**
419     * Get the number of TCP payload bytes received for this UID.
420     * This total does not include protocol and control overheads at
421     * the transport and the lower layers of the networking stack.
422     * The statistics are across all interfaces.
423     *
424     * {@see android.os.Process#myUid()}.
425     *
426     * @param uid The UID of the process to examine.
427     * @return number of bytes.  If the statistics are not supported by this device,
428     * {@link #UNSUPPORTED} will be returned.
429     */
430    public static native long getUidTcpRxBytes(int uid);
431
432    /**
433     * Get the number of UDP payload bytes sent for this UID.
434     * This total does not include protocol and control overheads at
435     * the transport and the lower layers of the networking stack.
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 bytes.  If the statistics are not supported by this device,
442     * {@link #UNSUPPORTED} will be returned.
443     */
444    public static native long getUidUdpTxBytes(int uid);
445
446    /**
447     * Get the number of UDP payload bytes received for this UID.
448     * This total does not include protocol and control overheads at
449     * the transport and the lower layers of the networking stack.
450     * The statistics are across all interfaces.
451     *
452     * {@see android.os.Process#myUid()}.
453     *
454     * @param uid The UID of the process to examine.
455     * @return number of bytes.  If the statistics are not supported by this device,
456     * {@link #UNSUPPORTED} will be returned.
457     */
458    public static native long getUidUdpRxBytes(int uid);
459
460    /**
461     * Get the number of TCP segments sent for this UID.
462     * Does not include TCP control packets (SYN/ACKs/FIN/..).
463     * The statistics are across all interfaces.
464     *
465     * {@see android.os.Process#myUid()}.
466     *
467     * @param uid The UID of the process to examine.
468     * @return number of TCP segments.  If the statistics are not supported by this device,
469     * {@link #UNSUPPORTED} will be returned.
470     */
471    public static native long getUidTcpTxSegments(int uid);
472
473    /**
474     * Get the number of TCP segments received for this UID.
475     * Does not include TCP control packets (SYN/ACKs/FIN/..).
476     * The statistics are across all interfaces.
477     *
478     * {@see android.os.Process#myUid()}.
479     *
480     * @param uid The UID of the process to examine.
481     * @return number of TCP segments.  If the statistics are not supported by this device,
482     * {@link #UNSUPPORTED} will be returned.
483     */
484    public static native long getUidTcpRxSegments(int uid);
485
486
487    /**
488     * Get the number of UDP packets sent for this UID.
489     * Includes DNS requests.
490     * The statistics are across all interfaces.
491     *
492     * {@see android.os.Process#myUid()}.
493     *
494     * @param uid The UID of the process to examine.
495     * @return number of packets.  If the statistics are not supported by this device,
496     * {@link #UNSUPPORTED} will be returned.
497     */
498    public static native long getUidUdpTxPackets(int uid);
499
500    /**
501     * Get the number of UDP packets received for this UID.
502     * Includes DNS responses.
503     * The statistics are across all interfaces.
504     *
505     * {@see android.os.Process#myUid()}.
506     *
507     * @param uid The UID of the process to examine.
508     * @return number of packets.  If the statistics are not supported by this device,
509     * {@link #UNSUPPORTED} will be returned.
510     */
511    public static native long getUidUdpRxPackets(int uid);
512
513    /**
514     * Return detailed {@link NetworkStats} for the current UID. Requires no
515     * special permission.
516     */
517    private static NetworkStats getDataLayerSnapshotForUid(Context context) {
518        final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
519                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
520        final int uid = android.os.Process.myUid();
521        try {
522            return statsService.getDataLayerSnapshotForUid(uid);
523        } catch (RemoteException e) {
524            throw new RuntimeException(e);
525        }
526    }
527}
528