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