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