Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2010 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.os.Parcelable;
     20 import android.os.Parcel;
     21 import android.util.Log;
     22 
     23 import java.util.Collection;
     24 import java.util.HashMap;
     25 import java.util.Map;
     26 import java.util.Map.Entry;
     27 import java.util.Set;
     28 
     29 /**
     30  * A class representing the capabilities of a link
     31  *
     32  * @hide
     33  */
     34 public class LinkCapabilities implements Parcelable {
     35     private static final String TAG = "LinkCapabilities";
     36     private static final boolean DBG = false;
     37 
     38     /** The Map of Keys to Values */
     39     private HashMap<Integer, String> mCapabilities;
     40 
     41 
     42     /**
     43      * The set of keys defined for a links capabilities.
     44      *
     45      * Keys starting with RW are read + write, i.e. the application
     46      * can request for a certain requirement corresponding to that key.
     47      * Keys starting with RO are read only, i.e. the the application
     48      * can read the value of that key from the socket but cannot request
     49      * a corresponding requirement.
     50      *
     51      * TODO: Provide a documentation technique for concisely and precisely
     52      * define the syntax for each value string associated with a key.
     53      */
     54     public static final class Key {
     55         /** No constructor */
     56         private Key() {}
     57 
     58         /**
     59          * An integer representing the network type.
     60          * @see ConnectivityManager
     61          */
     62         public final static int RO_NETWORK_TYPE = 1;
     63 
     64         /**
     65          * Desired minimum forward link (download) bandwidth for the
     66          * in kilobits per second (kbps). Values should be strings such
     67          * "50", "100", "1500", etc.
     68          */
     69         public final static int RW_DESIRED_FWD_BW = 2;
     70 
     71         /**
     72          * Required minimum forward link (download) bandwidth, in
     73          * per second (kbps), below which the socket cannot function.
     74          * Values should be strings such as "50", "100", "1500", etc.
     75          */
     76         public final static int RW_REQUIRED_FWD_BW = 3;
     77 
     78         /**
     79          * Available forward link (download) bandwidth for the socket.
     80          * This value is in kilobits per second (kbps).
     81          * Values will be strings such as "50", "100", "1500", etc.
     82          */
     83         public final static int RO_AVAILABLE_FWD_BW = 4;
     84 
     85         /**
     86          * Desired minimum reverse link (upload) bandwidth for the socket
     87          * in kilobits per second (kbps).
     88          * Values should be strings such as "50", "100", "1500", etc.
     89          * <p>
     90          * This key is set via the needs map.
     91          */
     92         public final static int RW_DESIRED_REV_BW = 5;
     93 
     94         /**
     95          * Required minimum reverse link (upload) bandwidth, in kilobits
     96          * per second (kbps), below which the socket cannot function.
     97          * If a rate is not specified, the default rate of kbps will be
     98          * Values should be strings such as "50", "100", "1500", etc.
     99          */
    100         public final static int RW_REQUIRED_REV_BW = 6;
    101 
    102         /**
    103          * Available reverse link (upload) bandwidth for the socket.
    104          * This value is in kilobits per second (kbps).
    105          * Values will be strings such as "50", "100", "1500", etc.
    106          */
    107         public final static int RO_AVAILABLE_REV_BW = 7;
    108 
    109         /**
    110          * Maximum latency for the socket, in milliseconds, above which
    111          * socket cannot function.
    112          * Values should be strings such as "50", "300", "500", etc.
    113          */
    114         public final static int RW_MAX_ALLOWED_LATENCY = 8;
    115 
    116         /**
    117          * Interface that the socket is bound to. This can be a virtual
    118          * interface (e.g. VPN or Mobile IP) or a physical interface
    119          * (e.g. wlan0 or rmnet0).
    120          * Values will be strings such as "wlan0", "rmnet0"
    121          */
    122         public final static int RO_BOUND_INTERFACE = 9;
    123 
    124         /**
    125          * Physical interface that the socket is routed on.
    126          * This can be different from BOUND_INTERFACE in cases such as
    127          * VPN or Mobile IP. The physical interface may change over time
    128          * if seamless mobility is supported.
    129          * Values will be strings such as "wlan0", "rmnet0"
    130          */
    131         public final static int RO_PHYSICAL_INTERFACE = 10;
    132     }
    133 
    134     /**
    135      * Role informs the LinkSocket about the data usage patterns of your
    136      * application.
    137      * <P>
    138      * {@code Role.DEFAULT} is the default role, and is used whenever
    139      * a role isn't set.
    140      */
    141     public static final class Role {
    142         /** No constructor */
    143         private Role() {}
    144 
    145         // examples only, discuss which roles should be defined, and then
    146         // code these to match
    147 
    148         /** Default Role */
    149         public static final String DEFAULT = "default";
    150         /** Bulk down load */
    151         public static final String BULK_DOWNLOAD = "bulk.download";
    152         /** Bulk upload */
    153         public static final String BULK_UPLOAD = "bulk.upload";
    154 
    155         /** VoIP Application at 24kbps */
    156         public static final String VOIP_24KBPS = "voip.24k";
    157         /** VoIP Application at 32kbps */
    158         public static final String VOIP_32KBPS = "voip.32k";
    159 
    160         /** Video Streaming at 480p */
    161         public static final String VIDEO_STREAMING_480P = "video.streaming.480p";
    162         /** Video Streaming at 720p */
    163         public static final String VIDEO_STREAMING_720I = "video.streaming.720i";
    164 
    165         /** Video Chat Application at 360p */
    166         public static final String VIDEO_CHAT_360P = "video.chat.360p";
    167         /** Video Chat Application at 480p */
    168         public static final String VIDEO_CHAT_480P = "video.chat.480i";
    169     }
    170 
    171     /**
    172      * Constructor
    173      */
    174     public LinkCapabilities() {
    175         mCapabilities = new HashMap<Integer, String>();
    176     }
    177 
    178     /**
    179      * Copy constructor.
    180      *
    181      * @param source
    182      */
    183     public LinkCapabilities(LinkCapabilities source) {
    184         if (source != null) {
    185             mCapabilities = new HashMap<Integer, String>(source.mCapabilities);
    186         } else {
    187             mCapabilities = new HashMap<Integer, String>();
    188         }
    189     }
    190 
    191     /**
    192      * Create the {@code LinkCapabilities} with values depending on role type.
    193      * @param applicationRole a {@code LinkSocket.Role}
    194      * @return the {@code LinkCapabilities} associated with the applicationRole, empty if none
    195      */
    196     public static LinkCapabilities createNeedsMap(String applicationRole) {
    197         if (DBG) log("createNeededCapabilities(applicationRole) EX");
    198         return new LinkCapabilities();
    199     }
    200 
    201     /**
    202      * Remove all capabilities
    203      */
    204     public void clear() {
    205         mCapabilities.clear();
    206     }
    207 
    208     /**
    209      * Returns whether this map is empty.
    210      */
    211     public boolean isEmpty() {
    212         return mCapabilities.isEmpty();
    213     }
    214 
    215     /**
    216      * Returns the number of elements in this map.
    217      *
    218      * @return the number of elements in this map.
    219      */
    220     public int size() {
    221         return mCapabilities.size();
    222     }
    223 
    224     /**
    225      * Given the key return the capability string
    226      *
    227      * @param key
    228      * @return the capability string
    229      */
    230     public String get(int key) {
    231         return mCapabilities.get(key);
    232     }
    233 
    234     /**
    235      * Store the key/value capability pair
    236      *
    237      * @param key
    238      * @param value
    239      */
    240     public void put(int key, String value) {
    241         mCapabilities.put(key, value);
    242     }
    243 
    244     /**
    245      * Returns whether this map contains the specified key.
    246      *
    247      * @param key to search for.
    248      * @return {@code true} if this map contains the specified key,
    249      *         {@code false} otherwise.
    250      */
    251     public boolean containsKey(int key) {
    252         return mCapabilities.containsKey(key);
    253     }
    254 
    255     /**
    256      * Returns whether this map contains the specified value.
    257      *
    258      * @param value to search for.
    259      * @return {@code true} if this map contains the specified value,
    260      *         {@code false} otherwise.
    261      */
    262     public boolean containsValue(String value) {
    263         return mCapabilities.containsValue(value);
    264     }
    265 
    266     /**
    267      * Returns a set containing all of the mappings in this map. Each mapping is
    268      * an instance of {@link Map.Entry}. As the set is backed by this map,
    269      * changes in one will be reflected in the other.
    270      *
    271      * @return a set of the mappings.
    272      */
    273     public Set<Entry<Integer, String>> entrySet() {
    274         return mCapabilities.entrySet();
    275     }
    276 
    277     /**
    278      * @return the set of the keys.
    279      */
    280     public Set<Integer> keySet() {
    281         return mCapabilities.keySet();
    282     }
    283 
    284     /**
    285      * @return the set of values
    286      */
    287     public Collection<String> values() {
    288         return mCapabilities.values();
    289     }
    290 
    291     /**
    292      * Implement the Parcelable interface
    293      * @hide
    294      */
    295     public int describeContents() {
    296         return 0;
    297     }
    298 
    299     /**
    300      * Convert to string for debugging
    301      */
    302     @Override
    303     public String toString() {
    304         StringBuilder sb = new StringBuilder();
    305         sb.append("{");
    306         boolean firstTime = true;
    307         for (Entry<Integer, String> entry : mCapabilities.entrySet()) {
    308             if (firstTime) {
    309                 firstTime = false;
    310             } else {
    311                 sb.append(",");
    312             }
    313             sb.append(entry.getKey());
    314             sb.append(":\"");
    315             sb.append(entry.getValue());
    316             sb.append("\"");
    317         }
    318         sb.append("}");
    319         return sb.toString();
    320     }
    321 
    322     /**
    323      * Implement the Parcelable interface.
    324      * @hide
    325      */
    326     public void writeToParcel(Parcel dest, int flags) {
    327         dest.writeInt(mCapabilities.size());
    328         for (Entry<Integer, String> entry : mCapabilities.entrySet()) {
    329             dest.writeInt(entry.getKey().intValue());
    330             dest.writeString(entry.getValue());
    331         }
    332     }
    333 
    334     /**
    335      * Implement the Parcelable interface.
    336      * @hide
    337      */
    338     public static final Creator<LinkCapabilities> CREATOR =
    339         new Creator<LinkCapabilities>() {
    340             public LinkCapabilities createFromParcel(Parcel in) {
    341                 LinkCapabilities capabilities = new LinkCapabilities();
    342                 int size = in.readInt();
    343                 while (size-- != 0) {
    344                     int key = in.readInt();
    345                     String value = in.readString();
    346                     capabilities.mCapabilities.put(key, value);
    347                 }
    348                 return capabilities;
    349             }
    350 
    351             public LinkCapabilities[] newArray(int size) {
    352                 return new LinkCapabilities[size];
    353             }
    354         };
    355 
    356     /**
    357      * Debug logging
    358      */
    359     protected static void log(String s) {
    360         Log.d(TAG, s);
    361     }
    362 }
    363