TrafficStats.java revision a63ba59260cd1bb3f5c16e395ace45a61f1d4461
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 given
202     * accounting tag. This can be used to derive bytes-per-operation.
203     *
204     * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}.
205     * @param operationCount Number of operations to increment count by.
206     */
207    public static void incrementOperationCount(int tag, int operationCount) {
208        if (operationCount < 0) {
209            throw new IllegalArgumentException("operation count can only be incremented");
210        }
211
212        final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
213                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
214        final int uid = android.os.Process.myUid();
215        try {
216            statsService.incrementOperationCount(uid, tag, operationCount);
217        } catch (RemoteException e) {
218            throw new RuntimeException(e);
219        }
220    }
221
222    /**
223     * Get the total number of packets transmitted through the mobile interface.
224     *
225     * @return number of packets.  If the statistics are not supported by this device,
226     * {@link #UNSUPPORTED} will be returned.
227     */
228    public static native long getMobileTxPackets();
229
230    /**
231     * Get the total number of packets received 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 getMobileRxPackets();
237
238    /**
239     * Get the total number of bytes transmitted through the mobile interface.
240     *
241     * @return number of bytes.  If the statistics are not supported by this device,
242     * {@link #UNSUPPORTED} will be returned.
243     */
244      public static native long getMobileTxBytes();
245
246    /**
247     * Get the total number of bytes received 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 getMobileRxBytes();
253
254    /**
255     * Get the total number of packets transmitted through the specified interface.
256     *
257     * @return number of packets.  If the statistics are not supported by this interface,
258     * {@link #UNSUPPORTED} will be returned.
259     * @hide
260     */
261    public static native long getTxPackets(String iface);
262
263    /**
264     * Get the total number of packets received through the specified interface.
265     *
266     * @return number of packets.  If the statistics are not supported by this interface,
267     * {@link #UNSUPPORTED} will be returned.
268     * @hide
269     */
270    public static native long getRxPackets(String iface);
271
272    /**
273     * Get the total number of bytes transmitted through the specified interface.
274     *
275     * @return number of bytes.  If the statistics are not supported by this interface,
276     * {@link #UNSUPPORTED} will be returned.
277     * @hide
278     */
279    public static native long getTxBytes(String iface);
280
281    /**
282     * Get the total number of bytes received through the specified interface.
283     *
284     * @return number of bytes.  If the statistics are not supported by this interface,
285     * {@link #UNSUPPORTED} will be returned.
286     * @hide
287     */
288    public static native long getRxBytes(String iface);
289
290
291    /**
292     * Get the total number of packets sent through all network interfaces.
293     *
294     * @return the number of packets.  If the statistics are not supported by this device,
295     * {@link #UNSUPPORTED} will be returned.
296     */
297    public static native long getTotalTxPackets();
298
299    /**
300     * Get the total number of packets received through all network interfaces.
301     *
302     * @return number of packets.  If the statistics are not supported by this device,
303     * {@link #UNSUPPORTED} will be returned.
304     */
305    public static native long getTotalRxPackets();
306
307    /**
308     * Get the total number of bytes sent through all network interfaces.
309     *
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 getTotalTxBytes();
314
315    /**
316     * Get the total number of bytes received 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 getTotalRxBytes();
322
323    /**
324     * Get the number of bytes sent through the network for this UID.
325     * The statistics are across all interfaces.
326     *
327     * {@see android.os.Process#myUid()}.
328     *
329     * @param uid The UID of the process to examine.
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 getUidTxBytes(int uid);
334
335    /**
336     * Get the number of bytes received 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
343     */
344    public static native long getUidRxBytes(int uid);
345
346    /**
347     * Get the number of packets (TCP segments + UDP) sent through
348     * 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 packets.
355     * If the statistics are not supported by this device,
356     * {@link #UNSUPPORTED} will be returned.
357     */
358    public static native long getUidTxPackets(int uid);
359
360    /**
361     * Get the number of packets (TCP segments + UDP) received through
362     * the network for this UID.
363     * The statistics are across all interfaces.
364     *
365     * {@see android.os.Process#myUid()}.
366     *
367     * @param uid The UID of the process to examine.
368     * @return number of packets
369     */
370    public static native long getUidRxPackets(int uid);
371
372    /**
373     * Get the number of TCP payload bytes sent for this UID.
374     * This total does not include protocol and control overheads at
375     * the transport and the lower layers of the networking stack.
376     * The statistics are across all interfaces.
377     *
378     * {@see android.os.Process#myUid()}.
379     *
380     * @param uid The UID of the process to examine.
381     * @return number of bytes.  If the statistics are not supported by this device,
382     * {@link #UNSUPPORTED} will be returned.
383     */
384    public static native long getUidTcpTxBytes(int uid);
385
386    /**
387     * Get the number of TCP payload bytes received for this UID.
388     * This total does not include protocol and control overheads at
389     * the transport and the lower layers of the networking stack.
390     * The statistics are across all interfaces.
391     *
392     * {@see android.os.Process#myUid()}.
393     *
394     * @param uid The UID of the process to examine.
395     * @return number of bytes.  If the statistics are not supported by this device,
396     * {@link #UNSUPPORTED} will be returned.
397     */
398    public static native long getUidTcpRxBytes(int uid);
399
400    /**
401     * Get the number of UDP payload bytes sent for this UID.
402     * This total does not include protocol and control overheads at
403     * the transport and the lower layers of the networking stack.
404     * The statistics are across all interfaces.
405     *
406     * {@see android.os.Process#myUid()}.
407     *
408     * @param uid The UID of the process to examine.
409     * @return number of bytes.  If the statistics are not supported by this device,
410     * {@link #UNSUPPORTED} will be returned.
411     */
412    public static native long getUidUdpTxBytes(int uid);
413
414    /**
415     * Get the number of UDP payload bytes received for this UID.
416     * This total does not include protocol and control overheads at
417     * the transport and the lower layers of the networking stack.
418     * The statistics are across all interfaces.
419     *
420     * {@see android.os.Process#myUid()}.
421     *
422     * @param uid The UID of the process to examine.
423     * @return number of bytes.  If the statistics are not supported by this device,
424     * {@link #UNSUPPORTED} will be returned.
425     */
426    public static native long getUidUdpRxBytes(int uid);
427
428    /**
429     * Get the number of TCP segments sent for this UID.
430     * Does not include TCP control packets (SYN/ACKs/FIN/..).
431     * The statistics are across all interfaces.
432     *
433     * {@see android.os.Process#myUid()}.
434     *
435     * @param uid The UID of the process to examine.
436     * @return number of TCP segments.  If the statistics are not supported by this device,
437     * {@link #UNSUPPORTED} will be returned.
438     */
439    public static native long getUidTcpTxSegments(int uid);
440
441    /**
442     * Get the number of TCP segments received for this UID.
443     * Does not include TCP control packets (SYN/ACKs/FIN/..).
444     * The statistics are across all interfaces.
445     *
446     * {@see android.os.Process#myUid()}.
447     *
448     * @param uid The UID of the process to examine.
449     * @return number of TCP segments.  If the statistics are not supported by this device,
450     * {@link #UNSUPPORTED} will be returned.
451     */
452    public static native long getUidTcpRxSegments(int uid);
453
454
455    /**
456     * Get the number of UDP packets sent for this UID.
457     * Includes DNS requests.
458     * The statistics are across all interfaces.
459     *
460     * {@see android.os.Process#myUid()}.
461     *
462     * @param uid The UID of the process to examine.
463     * @return number of packets.  If the statistics are not supported by this device,
464     * {@link #UNSUPPORTED} will be returned.
465     */
466    public static native long getUidUdpTxPackets(int uid);
467
468    /**
469     * Get the number of UDP packets received for this UID.
470     * Includes DNS responses.
471     * The statistics are across all interfaces.
472     *
473     * {@see android.os.Process#myUid()}.
474     *
475     * @param uid The UID of the process to examine.
476     * @return number of packets.  If the statistics are not supported by this device,
477     * {@link #UNSUPPORTED} will be returned.
478     */
479    public static native long getUidUdpRxPackets(int uid);
480
481    /**
482     * Return detailed {@link NetworkStats} for the current UID. Requires no
483     * special permission.
484     */
485    private static NetworkStats getDataLayerSnapshotForUid(Context context) {
486        final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
487                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
488        final int uid = android.os.Process.myUid();
489        try {
490            return statsService.getDataLayerSnapshotForUid(uid);
491        } catch (RemoteException e) {
492            throw new RuntimeException(e);
493        }
494    }
495}
496