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