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