TrafficStats.java revision d18addb4e3d0cd4da798dd35ad676d98465ebed3
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    public static void clearThreadStatsTag() {
108        NetworkManagementSocketTagger.setThreadSocketStatsTag(-1);
109    }
110
111    /**
112     * Set specific UID to use when accounting {@link Socket} traffic
113     * originating from the current thread. Designed for use when performing an
114     * operation on behalf of another application.
115     * <p>
116     * Changes only take effect during subsequent calls to
117     * {@link #tagSocket(Socket)}.
118     * <p>
119     * To take effect, caller must hold
120     * {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission.
121     *
122     * {@hide}
123     */
124    public static void setThreadStatsUid(int uid) {
125        NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
126    }
127
128    /** {@hide} */
129    public static void clearThreadStatsUid() {
130        NetworkManagementSocketTagger.setThreadSocketStatsUid(-1);
131    }
132
133    /**
134     * Tag the given {@link Socket} with any statistics parameters active for
135     * the current thread. Subsequent calls always replace any existing
136     * parameters. When finished, call {@link #untagSocket(Socket)} to remove
137     * statistics parameters.
138     *
139     * @see #setThreadStatsTag(int)
140     * @see #setThreadStatsUid(int)
141     */
142    public static void tagSocket(Socket socket) throws SocketException {
143        SocketTagger.get().tag(socket);
144    }
145
146    /**
147     * Remove any statistics parameters from the given {@link Socket}.
148     */
149    public static void untagSocket(Socket socket) throws SocketException {
150        SocketTagger.get().untag(socket);
151    }
152
153    /**
154     * Start profiling data usage for current UID. Only one profiling session
155     * can be active at a time.
156     *
157     * @hide
158     */
159    public static void startDataProfiling(Context context) {
160        synchronized (sProfilingLock) {
161            if (sActiveProfilingStart != null) {
162                throw new IllegalStateException("already profiling data");
163            }
164
165            // take snapshot in time; we calculate delta later
166            sActiveProfilingStart = getDataLayerSnapshotForUid(context);
167        }
168    }
169
170    /**
171     * Stop profiling data usage for current UID.
172     *
173     * @return Detailed {@link NetworkStats} of data that occurred since last
174     *         {@link #startDataProfiling(Context)} call.
175     * @hide
176     */
177    public static NetworkStats stopDataProfiling(Context context) {
178        synchronized (sProfilingLock) {
179            if (sActiveProfilingStart == null) {
180                throw new IllegalStateException("not profiling data");
181            }
182
183            // subtract starting values and return delta
184            final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
185            final NetworkStats profilingDelta = profilingStop.subtractClamped(
186                    sActiveProfilingStart);
187            sActiveProfilingStart = null;
188            return profilingDelta;
189        }
190    }
191
192    /**
193     * Increment count of network operations performed under the accounting tag
194     * currently active on the calling thread. This can be used to derive
195     * bytes-per-operation.
196     *
197     * @param operationCount Number of operations to increment count by.
198     */
199    public static void incrementOperationCount(int operationCount) {
200        final int tag = getThreadStatsTag();
201        incrementOperationCount(tag, operationCount);
202    }
203
204    /**
205     * Increment count of network operations performed under the given
206     * accounting tag. This can be used to derive bytes-per-operation.
207     *
208     * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}.
209     * @param operationCount Number of operations to increment count by.
210     */
211    public static void incrementOperationCount(int tag, int operationCount) {
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