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 */ Key()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 */ Role()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 */ LinkCapabilities()174 public LinkCapabilities() { 175 mCapabilities = new HashMap<Integer, String>(); 176 } 177 178 /** 179 * Copy constructor. 180 * 181 * @param source 182 */ LinkCapabilities(LinkCapabilities source)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 */ createNeedsMap(String applicationRole)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 */ clear()204 public void clear() { 205 mCapabilities.clear(); 206 } 207 208 /** 209 * Returns whether this map is empty. 210 */ isEmpty()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 */ size()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 */ get(int key)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 */ put(int key, String value)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 */ containsKey(int key)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 */ containsValue(String value)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 */ entrySet()273 public Set<Entry<Integer, String>> entrySet() { 274 return mCapabilities.entrySet(); 275 } 276 277 /** 278 * @return the set of the keys. 279 */ keySet()280 public Set<Integer> keySet() { 281 return mCapabilities.keySet(); 282 } 283 284 /** 285 * @return the set of values 286 */ values()287 public Collection<String> values() { 288 return mCapabilities.values(); 289 } 290 291 /** 292 * Implement the Parcelable interface 293 * @hide 294 */ describeContents()295 public int describeContents() { 296 return 0; 297 } 298 299 /** 300 * Convert to string for debugging 301 */ 302 @Override toString()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 return mCapabilities.toString(); 318 } 319 return sb.toString(); 320 } 321 322 /** 323 * Implement the Parcelable interface. 324 * @hide 325 */ writeToParcel(Parcel dest, int flags)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 */ log(String s)359 protected static void log(String s) { 360 Log.d(TAG, s); 361 } 362 } 363