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