• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.net;
18 
19 import android.app.DownloadManager;
20 import android.app.backup.BackupManager;
21 import android.content.Context;
22 import android.media.MediaPlayer;
23 import android.os.RemoteException;
24 import android.os.ServiceManager;
25 
26 import com.android.server.NetworkManagementSocketTagger;
27 
28 import dalvik.system.SocketTagger;
29 
30 import java.net.Socket;
31 import 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  */
41 public 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      */
setThreadStatsTag(int tag)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      */
getThreadStatsTag()115     public static int getThreadStatsTag() {
116         return NetworkManagementSocketTagger.getThreadSocketStatsTag();
117     }
118 
clearThreadStatsTag()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      */
setThreadStatsUid(int uid)136     public static void setThreadStatsUid(int uid) {
137         NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
138     }
139 
140     /** {@hide} */
clearThreadStatsUid()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      */
tagSocket(Socket socket)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      */
untagSocket(Socket socket)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      */
startDataProfiling(Context context)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      */
stopDataProfiling(Context context)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 = profilingStop.subtractClamped(
198                     sActiveProfilingStart);
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      */
incrementOperationCount(int operationCount)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      */
incrementOperationCount(int tag, int operationCount)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      */
getMobileTxPackets()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      */
getMobileRxPackets()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      */
getMobileTxBytes()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      */
getMobileRxBytes()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      */
getTxPackets(String iface)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      */
getRxPackets(String iface)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      */
getTxBytes(String iface)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      */
getRxBytes(String iface)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      */
getTotalTxPackets()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      */
getTotalRxPackets()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      */
getTotalTxBytes()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      */
getTotalRxBytes()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      */
getUidTxBytes(int uid)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      */
getUidRxBytes(int uid)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      */
getUidTxPackets(int uid)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      */
getUidRxPackets(int uid)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      */
getUidTcpTxBytes(int uid)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      */
getUidTcpRxBytes(int uid)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      */
getUidUdpTxBytes(int uid)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      */
getUidUdpRxBytes(int uid)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      */
getUidTcpTxSegments(int uid)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      */
getUidTcpRxSegments(int uid)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      */
getUidUdpTxPackets(int uid)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      */
getUidUdpRxPackets(int uid)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      */
getDataLayerSnapshotForUid(Context context)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