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.annotation.SystemApi;
     20 import android.app.DownloadManager;
     21 import android.app.backup.BackupManager;
     22 import android.content.Context;
     23 import android.media.MediaPlayer;
     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     /** @hide */
     49     public static final long KB_IN_BYTES = 1024;
     50     /** @hide */
     51     public static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
     52     /** @hide */
     53     public static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
     54 
     55     /**
     56      * Special UID value used when collecting {@link NetworkStatsHistory} for
     57      * removed applications.
     58      *
     59      * @hide
     60      */
     61     public static final int UID_REMOVED = -4;
     62 
     63     /**
     64      * Special UID value used when collecting {@link NetworkStatsHistory} for
     65      * tethering traffic.
     66      *
     67      * @hide
     68      */
     69     public static final int UID_TETHERING = -5;
     70 
     71     /**
     72      * Default tag value for {@link DownloadManager} traffic.
     73      *
     74      * @hide
     75      */
     76     public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFFFF01;
     77 
     78     /**
     79      * Default tag value for {@link MediaPlayer} traffic.
     80      *
     81      * @hide
     82      */
     83     public static final int TAG_SYSTEM_MEDIA = 0xFFFFFF02;
     84 
     85     /**
     86      * Default tag value for {@link BackupManager} traffic.
     87      *
     88      * @hide
     89      */
     90     public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03;
     91 
     92     private static INetworkStatsService sStatsService;
     93 
     94     private synchronized static INetworkStatsService getStatsService() {
     95         if (sStatsService == null) {
     96             sStatsService = INetworkStatsService.Stub.asInterface(
     97                     ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
     98         }
     99         return sStatsService;
    100     }
    101 
    102     /**
    103      * Snapshot of {@link NetworkStats} when the currently active profiling
    104      * session started, or {@code null} if no session active.
    105      *
    106      * @see #startDataProfiling(Context)
    107      * @see #stopDataProfiling(Context)
    108      */
    109     private static NetworkStats sActiveProfilingStart;
    110 
    111     private static Object sProfilingLock = new Object();
    112 
    113     /**
    114      * Set active tag to use when accounting {@link Socket} traffic originating
    115      * from the current thread. Only one active tag per thread is supported.
    116      * <p>
    117      * Changes only take effect during subsequent calls to
    118      * {@link #tagSocket(Socket)}.
    119      * <p>
    120      * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
    121      * used internally by system services like {@link DownloadManager} when
    122      * performing traffic on behalf of an application.
    123      *
    124      * @see #clearThreadStatsTag()
    125      */
    126     public static void setThreadStatsTag(int tag) {
    127         NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
    128     }
    129 
    130     /**
    131      * System API for backup-related support components to tag network traffic
    132      * appropriately.
    133      * @hide
    134      */
    135     @SystemApi
    136     public static void setThreadStatsTagBackup() {
    137         setThreadStatsTag(TAG_SYSTEM_BACKUP);
    138     }
    139 
    140     /**
    141      * Get the active tag used when accounting {@link Socket} traffic originating
    142      * from the current thread. Only one active tag per thread is supported.
    143      * {@link #tagSocket(Socket)}.
    144      *
    145      * @see #setThreadStatsTag(int)
    146      */
    147     public static int getThreadStatsTag() {
    148         return NetworkManagementSocketTagger.getThreadSocketStatsTag();
    149     }
    150 
    151     /**
    152      * Clear any active tag set to account {@link Socket} traffic originating
    153      * from the current thread.
    154      *
    155      * @see #setThreadStatsTag(int)
    156      */
    157     public static void clearThreadStatsTag() {
    158         NetworkManagementSocketTagger.setThreadSocketStatsTag(-1);
    159     }
    160 
    161     /**
    162      * Set specific UID to use when accounting {@link Socket} traffic
    163      * originating from the current thread. Designed for use when performing an
    164      * operation on behalf of another application.
    165      * <p>
    166      * Changes only take effect during subsequent calls to
    167      * {@link #tagSocket(Socket)}.
    168      * <p>
    169      * To take effect, caller must hold
    170      * {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission.
    171      *
    172      * @hide
    173      */
    174     @SystemApi
    175     public static void setThreadStatsUid(int uid) {
    176         NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
    177     }
    178 
    179     /** {@hide} */
    180     @SystemApi
    181     public static void clearThreadStatsUid() {
    182         NetworkManagementSocketTagger.setThreadSocketStatsUid(-1);
    183     }
    184 
    185     /**
    186      * Tag the given {@link Socket} with any statistics parameters active for
    187      * the current thread. Subsequent calls always replace any existing
    188      * parameters. When finished, call {@link #untagSocket(Socket)} to remove
    189      * statistics parameters.
    190      *
    191      * @see #setThreadStatsTag(int)
    192      * @see #setThreadStatsUid(int)
    193      */
    194     public static void tagSocket(Socket socket) throws SocketException {
    195         SocketTagger.get().tag(socket);
    196     }
    197 
    198     /**
    199      * Remove any statistics parameters from the given {@link Socket}.
    200      */
    201     public static void untagSocket(Socket socket) throws SocketException {
    202         SocketTagger.get().untag(socket);
    203     }
    204 
    205     /**
    206      * Start profiling data usage for current UID. Only one profiling session
    207      * can be active at a time.
    208      *
    209      * @hide
    210      */
    211     public static void startDataProfiling(Context context) {
    212         synchronized (sProfilingLock) {
    213             if (sActiveProfilingStart != null) {
    214                 throw new IllegalStateException("already profiling data");
    215             }
    216 
    217             // take snapshot in time; we calculate delta later
    218             sActiveProfilingStart = getDataLayerSnapshotForUid(context);
    219         }
    220     }
    221 
    222     /**
    223      * Stop profiling data usage for current UID.
    224      *
    225      * @return Detailed {@link NetworkStats} of data that occurred since last
    226      *         {@link #startDataProfiling(Context)} call.
    227      * @hide
    228      */
    229     public static NetworkStats stopDataProfiling(Context context) {
    230         synchronized (sProfilingLock) {
    231             if (sActiveProfilingStart == null) {
    232                 throw new IllegalStateException("not profiling data");
    233             }
    234 
    235             // subtract starting values and return delta
    236             final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
    237             final NetworkStats profilingDelta = NetworkStats.subtract(
    238                     profilingStop, sActiveProfilingStart, null, null);
    239             sActiveProfilingStart = null;
    240             return profilingDelta;
    241         }
    242     }
    243 
    244     /**
    245      * Increment count of network operations performed under the accounting tag
    246      * currently active on the calling thread. This can be used to derive
    247      * bytes-per-operation.
    248      *
    249      * @param operationCount Number of operations to increment count by.
    250      */
    251     public static void incrementOperationCount(int operationCount) {
    252         final int tag = getThreadStatsTag();
    253         incrementOperationCount(tag, operationCount);
    254     }
    255 
    256     /**
    257      * Increment count of network operations performed under the given
    258      * accounting tag. This can be used to derive bytes-per-operation.
    259      *
    260      * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}.
    261      * @param operationCount Number of operations to increment count by.
    262      */
    263     public static void incrementOperationCount(int tag, int operationCount) {
    264         final int uid = android.os.Process.myUid();
    265         try {
    266             getStatsService().incrementOperationCount(uid, tag, operationCount);
    267         } catch (RemoteException e) {
    268             throw new RuntimeException(e);
    269         }
    270     }
    271 
    272     /** {@hide} */
    273     public static void closeQuietly(INetworkStatsSession session) {
    274         // TODO: move to NetworkStatsService once it exists
    275         if (session != null) {
    276             try {
    277                 session.close();
    278             } catch (RuntimeException rethrown) {
    279                 throw rethrown;
    280             } catch (Exception ignored) {
    281             }
    282         }
    283     }
    284 
    285     /**
    286      * Return number of packets transmitted across mobile networks since device
    287      * boot. Counts packets across all mobile network interfaces, and always
    288      * increases monotonically since device boot. Statistics are measured at the
    289      * network layer, so they include both TCP and UDP usage.
    290      * <p>
    291      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
    292      * return {@link #UNSUPPORTED} on devices where statistics aren't available.
    293      */
    294     public static long getMobileTxPackets() {
    295         long total = 0;
    296         for (String iface : getMobileIfaces()) {
    297             total += getTxPackets(iface);
    298         }
    299         return total;
    300     }
    301 
    302     /**
    303      * Return number of packets received across mobile networks since device
    304      * boot. Counts packets across all mobile network interfaces, and always
    305      * increases monotonically since device boot. Statistics are measured at the
    306      * network layer, so they include both TCP and UDP usage.
    307      * <p>
    308      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
    309      * return {@link #UNSUPPORTED} on devices where statistics aren't available.
    310      */
    311     public static long getMobileRxPackets() {
    312         long total = 0;
    313         for (String iface : getMobileIfaces()) {
    314             total += getRxPackets(iface);
    315         }
    316         return total;
    317     }
    318 
    319     /**
    320      * Return number of bytes transmitted across mobile networks since device
    321      * boot. Counts packets across all mobile network interfaces, and always
    322      * increases monotonically since device boot. Statistics are measured at the
    323      * network layer, so they include both TCP and UDP usage.
    324      * <p>
    325      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
    326      * return {@link #UNSUPPORTED} on devices where statistics aren't available.
    327      */
    328     public static long getMobileTxBytes() {
    329         long total = 0;
    330         for (String iface : getMobileIfaces()) {
    331             total += getTxBytes(iface);
    332         }
    333         return total;
    334     }
    335 
    336     /**
    337      * Return number of bytes received across mobile networks since device boot.
    338      * Counts packets across all mobile network interfaces, and always increases
    339      * monotonically since device boot. Statistics are measured at the network
    340      * layer, so they include both TCP and UDP usage.
    341      * <p>
    342      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
    343      * return {@link #UNSUPPORTED} on devices where statistics aren't available.
    344      */
    345     public static long getMobileRxBytes() {
    346         long total = 0;
    347         for (String iface : getMobileIfaces()) {
    348             total += getRxBytes(iface);
    349         }
    350         return total;
    351     }
    352 
    353     /** {@hide} */
    354     public static long getMobileTcpRxPackets() {
    355         long total = 0;
    356         for (String iface : getMobileIfaces()) {
    357             final long stat = nativeGetIfaceStat(iface, TYPE_TCP_RX_PACKETS);
    358             if (stat != UNSUPPORTED) {
    359                 total += stat;
    360             }
    361         }
    362         return total;
    363     }
    364 
    365     /** {@hide} */
    366     public static long getMobileTcpTxPackets() {
    367         long total = 0;
    368         for (String iface : getMobileIfaces()) {
    369             final long stat = nativeGetIfaceStat(iface, TYPE_TCP_TX_PACKETS);
    370             if (stat != UNSUPPORTED) {
    371                 total += stat;
    372             }
    373         }
    374         return total;
    375     }
    376 
    377     /** {@hide} */
    378     public static long getTxPackets(String iface) {
    379         return nativeGetIfaceStat(iface, TYPE_TX_PACKETS);
    380     }
    381 
    382     /** {@hide} */
    383     public static long getRxPackets(String iface) {
    384         return nativeGetIfaceStat(iface, TYPE_RX_PACKETS);
    385     }
    386 
    387     /** {@hide} */
    388     public static long getTxBytes(String iface) {
    389         return nativeGetIfaceStat(iface, TYPE_TX_BYTES);
    390     }
    391 
    392     /** {@hide} */
    393     public static long getRxBytes(String iface) {
    394         return nativeGetIfaceStat(iface, TYPE_RX_BYTES);
    395     }
    396 
    397     /**
    398      * Return number of packets transmitted since device boot. Counts packets
    399      * across all network interfaces, and always increases monotonically since
    400      * device boot. Statistics are measured at the network layer, so they
    401      * include both TCP and UDP usage.
    402      * <p>
    403      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
    404      * return {@link #UNSUPPORTED} on devices where statistics aren't available.
    405      */
    406     public static long getTotalTxPackets() {
    407         return nativeGetTotalStat(TYPE_TX_PACKETS);
    408     }
    409 
    410     /**
    411      * Return number of packets received since device boot. Counts packets
    412      * across all network interfaces, and always increases monotonically since
    413      * device boot. Statistics are measured at the network layer, so they
    414      * include both TCP and UDP usage.
    415      * <p>
    416      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
    417      * return {@link #UNSUPPORTED} on devices where statistics aren't available.
    418      */
    419     public static long getTotalRxPackets() {
    420         return nativeGetTotalStat(TYPE_RX_PACKETS);
    421     }
    422 
    423     /**
    424      * Return number of bytes transmitted since device boot. Counts packets
    425      * across all network interfaces, and always increases monotonically since
    426      * device boot. Statistics are measured at the network layer, so they
    427      * include both TCP and UDP usage.
    428      * <p>
    429      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
    430      * return {@link #UNSUPPORTED} on devices where statistics aren't available.
    431      */
    432     public static long getTotalTxBytes() {
    433         return nativeGetTotalStat(TYPE_TX_BYTES);
    434     }
    435 
    436     /**
    437      * Return number of bytes received since device boot. Counts packets across
    438      * all network interfaces, and always increases monotonically since device
    439      * boot. Statistics are measured at the network layer, so they include both
    440      * TCP and UDP usage.
    441      * <p>
    442      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
    443      * return {@link #UNSUPPORTED} on devices where statistics aren't available.
    444      */
    445     public static long getTotalRxBytes() {
    446         return nativeGetTotalStat(TYPE_RX_BYTES);
    447     }
    448 
    449     /**
    450      * Return number of bytes transmitted by the given UID since device boot.
    451      * Counts packets across all network interfaces, and always increases
    452      * monotonically since device boot. Statistics are measured at the network
    453      * layer, so they include both TCP and UDP usage.
    454      * <p>
    455      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
    456      * {@link #UNSUPPORTED} on devices where statistics aren't available.
    457      *
    458      * @see android.os.Process#myUid()
    459      * @see android.content.pm.ApplicationInfo#uid
    460      */
    461     public static long getUidTxBytes(int uid) {
    462         return nativeGetUidStat(uid, TYPE_TX_BYTES);
    463     }
    464 
    465     /**
    466      * Return number of bytes received by the given UID since device boot.
    467      * Counts packets across all network interfaces, and always increases
    468      * monotonically since device boot. Statistics are measured at the network
    469      * layer, so they include both TCP and UDP usage.
    470      * <p>
    471      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
    472      * {@link #UNSUPPORTED} on devices where statistics aren't available.
    473      *
    474      * @see android.os.Process#myUid()
    475      * @see android.content.pm.ApplicationInfo#uid
    476      */
    477     public static long getUidRxBytes(int uid) {
    478         return nativeGetUidStat(uid, TYPE_RX_BYTES);
    479     }
    480 
    481     /**
    482      * Return number of packets transmitted by the given UID since device boot.
    483      * Counts packets across all network interfaces, and always increases
    484      * monotonically since device boot. Statistics are measured at the network
    485      * layer, so they include both TCP and UDP usage.
    486      * <p>
    487      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
    488      * {@link #UNSUPPORTED} on devices where statistics aren't available.
    489      *
    490      * @see android.os.Process#myUid()
    491      * @see android.content.pm.ApplicationInfo#uid
    492      */
    493     public static long getUidTxPackets(int uid) {
    494         return nativeGetUidStat(uid, TYPE_TX_PACKETS);
    495     }
    496 
    497     /**
    498      * Return number of packets received by the given UID since device boot.
    499      * Counts packets across all network interfaces, and always increases
    500      * monotonically since device boot. Statistics are measured at the network
    501      * layer, so they include both TCP and UDP usage.
    502      * <p>
    503      * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
    504      * {@link #UNSUPPORTED} on devices where statistics aren't available.
    505      *
    506      * @see android.os.Process#myUid()
    507      * @see android.content.pm.ApplicationInfo#uid
    508      */
    509     public static long getUidRxPackets(int uid) {
    510         return nativeGetUidStat(uid, TYPE_RX_PACKETS);
    511     }
    512 
    513     /**
    514      * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
    515      *             transport layer statistics are no longer available, and will
    516      *             always return {@link #UNSUPPORTED}.
    517      * @see #getUidTxBytes(int)
    518      */
    519     @Deprecated
    520     public static long getUidTcpTxBytes(int uid) {
    521         return UNSUPPORTED;
    522     }
    523 
    524     /**
    525      * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
    526      *             transport layer statistics are no longer available, and will
    527      *             always return {@link #UNSUPPORTED}.
    528      * @see #getUidRxBytes(int)
    529      */
    530     @Deprecated
    531     public static long getUidTcpRxBytes(int uid) {
    532         return UNSUPPORTED;
    533     }
    534 
    535     /**
    536      * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
    537      *             transport layer statistics are no longer available, and will
    538      *             always return {@link #UNSUPPORTED}.
    539      * @see #getUidTxBytes(int)
    540      */
    541     @Deprecated
    542     public static long getUidUdpTxBytes(int uid) {
    543         return UNSUPPORTED;
    544     }
    545 
    546     /**
    547      * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
    548      *             transport layer statistics are no longer available, and will
    549      *             always return {@link #UNSUPPORTED}.
    550      * @see #getUidRxBytes(int)
    551      */
    552     @Deprecated
    553     public static long getUidUdpRxBytes(int uid) {
    554         return UNSUPPORTED;
    555     }
    556 
    557     /**
    558      * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
    559      *             transport layer statistics are no longer available, and will
    560      *             always return {@link #UNSUPPORTED}.
    561      * @see #getUidTxPackets(int)
    562      */
    563     @Deprecated
    564     public static long getUidTcpTxSegments(int uid) {
    565         return UNSUPPORTED;
    566     }
    567 
    568     /**
    569      * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
    570      *             transport layer statistics are no longer available, and will
    571      *             always return {@link #UNSUPPORTED}.
    572      * @see #getUidRxPackets(int)
    573      */
    574     @Deprecated
    575     public static long getUidTcpRxSegments(int uid) {
    576         return UNSUPPORTED;
    577     }
    578 
    579     /**
    580      * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
    581      *             transport layer statistics are no longer available, and will
    582      *             always return {@link #UNSUPPORTED}.
    583      * @see #getUidTxPackets(int)
    584      */
    585     @Deprecated
    586     public static long getUidUdpTxPackets(int uid) {
    587         return UNSUPPORTED;
    588     }
    589 
    590     /**
    591      * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
    592      *             transport layer statistics are no longer available, and will
    593      *             always return {@link #UNSUPPORTED}.
    594      * @see #getUidRxPackets(int)
    595      */
    596     @Deprecated
    597     public static long getUidUdpRxPackets(int uid) {
    598         return UNSUPPORTED;
    599     }
    600 
    601     /**
    602      * Return detailed {@link NetworkStats} for the current UID. Requires no
    603      * special permission.
    604      */
    605     private static NetworkStats getDataLayerSnapshotForUid(Context context) {
    606         // TODO: take snapshot locally, since proc file is now visible
    607         final int uid = android.os.Process.myUid();
    608         try {
    609             return getStatsService().getDataLayerSnapshotForUid(uid);
    610         } catch (RemoteException e) {
    611             throw new RuntimeException(e);
    612         }
    613     }
    614 
    615     /**
    616      * Return set of any ifaces associated with mobile networks since boot.
    617      * Interfaces are never removed from this list, so counters should always be
    618      * monotonic.
    619      */
    620     private static String[] getMobileIfaces() {
    621         try {
    622             return getStatsService().getMobileIfaces();
    623         } catch (RemoteException e) {
    624             throw new RuntimeException(e);
    625         }
    626     }
    627 
    628     // NOTE: keep these in sync with android_net_TrafficStats.cpp
    629     private static final int TYPE_RX_BYTES = 0;
    630     private static final int TYPE_RX_PACKETS = 1;
    631     private static final int TYPE_TX_BYTES = 2;
    632     private static final int TYPE_TX_PACKETS = 3;
    633     private static final int TYPE_TCP_RX_PACKETS = 4;
    634     private static final int TYPE_TCP_TX_PACKETS = 5;
    635 
    636     private static native long nativeGetTotalStat(int type);
    637     private static native long nativeGetIfaceStat(String iface, int type);
    638     private static native long nativeGetUidStat(int uid, int type);
    639 }
    640