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