LinkProperties.java revision 4e900091c4da26eb1c9f0d232ee0e50f4522cc69
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 17package android.net; 18 19import android.net.ProxyProperties; 20import android.os.Parcelable; 21import android.os.Parcel; 22import android.text.TextUtils; 23 24import java.net.InetAddress; 25import java.net.UnknownHostException; 26import java.util.ArrayList; 27import java.util.Collection; 28import java.util.Collections; 29 30/** 31 * Describes the properties of a network link. 32 * 33 * A link represents a connection to a network. 34 * It may have multiple addresses and multiple gateways, 35 * multiple dns servers but only one http proxy. 36 * 37 * Because it's a single network, the dns's 38 * are interchangeable and don't need associating with 39 * particular addresses. The gateways similarly don't 40 * need associating with particular addresses. 41 * 42 * A dual stack interface works fine in this model: 43 * each address has it's own prefix length to describe 44 * the local network. The dns servers all return 45 * both v4 addresses and v6 addresses regardless of the 46 * address family of the server itself (rfc4213) and we 47 * don't care which is used. The gateways will be 48 * selected based on the destination address and the 49 * source address has no relavence. 50 * @hide 51 */ 52public class LinkProperties implements Parcelable { 53 54 String mIfaceName; 55 private Collection<LinkAddress> mLinkAddresses; 56 private Collection<InetAddress> mDnses; 57 private Collection<InetAddress> mGateways; 58 private ProxyProperties mHttpProxy; 59 60 public LinkProperties() { 61 clear(); 62 } 63 64 // copy constructor instead of clone 65 public LinkProperties(LinkProperties source) { 66 if (source != null) { 67 mIfaceName = source.getInterfaceName(); 68 mLinkAddresses = source.getLinkAddresses(); 69 mDnses = source.getDnses(); 70 mGateways = source.getGateways(); 71 mHttpProxy = new ProxyProperties(source.getHttpProxy()); 72 } 73 } 74 75 public void setInterfaceName(String iface) { 76 mIfaceName = iface; 77 } 78 79 public String getInterfaceName() { 80 return mIfaceName; 81 } 82 83 public Collection<InetAddress> getAddresses() { 84 Collection<InetAddress> addresses = new ArrayList<InetAddress>(); 85 for (LinkAddress linkAddress : mLinkAddresses) { 86 addresses.add(linkAddress.getAddress()); 87 } 88 return Collections.unmodifiableCollection(addresses); 89 } 90 91 public void addLinkAddress(LinkAddress address) { 92 if (address != null) mLinkAddresses.add(address); 93 } 94 95 public Collection<LinkAddress> getLinkAddresses() { 96 return Collections.unmodifiableCollection(mLinkAddresses); 97 } 98 99 public void addDns(InetAddress dns) { 100 if (dns != null) mDnses.add(dns); 101 } 102 103 public Collection<InetAddress> getDnses() { 104 return Collections.unmodifiableCollection(mDnses); 105 } 106 107 public void addGateway(InetAddress gateway) { 108 if (gateway != null) mGateways.add(gateway); 109 } 110 public Collection<InetAddress> getGateways() { 111 return Collections.unmodifiableCollection(mGateways); 112 } 113 114 public void setHttpProxy(ProxyProperties proxy) { 115 mHttpProxy = proxy; 116 } 117 public ProxyProperties getHttpProxy() { 118 return mHttpProxy; 119 } 120 121 public void clear() { 122 mIfaceName = null; 123 mLinkAddresses = new ArrayList<LinkAddress>(); 124 mDnses = new ArrayList<InetAddress>(); 125 mGateways = new ArrayList<InetAddress>(); 126 mHttpProxy = null; 127 } 128 129 /** 130 * Implement the Parcelable interface 131 * @hide 132 */ 133 public int describeContents() { 134 return 0; 135 } 136 137 @Override 138 public String toString() { 139 String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " "); 140 141 String linkAddresses = "LinkAddresses: ["; 142 for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString() + ","; 143 linkAddresses += "] "; 144 145 String dns = "DnsAddresses: ["; 146 for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ","; 147 dns += "] "; 148 149 String gateways = "Gateways: ["; 150 for (InetAddress gw : mGateways) gateways += gw.getHostAddress() + ","; 151 gateways += "] "; 152 String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " "); 153 154 return ifaceName + linkAddresses + gateways + dns + proxy; 155 } 156 157 158 @Override 159 /** 160 * Compares this {@code LinkProperties} instance against the target 161 * LinkProperties in {@code obj}. Two LinkPropertieses are equal if 162 * all their fields are equal in values. 163 * 164 * For collection fields, such as mDnses, containsAll() is used to check 165 * if two collections contains the same elements, independent of order. 166 * There are two thoughts regarding containsAll() 167 * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal. 168 * 2. Worst case performance is O(n^2). 169 * 170 * @param obj the object to be tested for equality. 171 * @return {@code true} if both objects are equal, {@code false} otherwise. 172 */ 173 public boolean equals(Object obj) { 174 if (this == obj) return true; 175 176 if (!(obj instanceof LinkProperties)) return false; 177 178 boolean sameAddresses; 179 boolean sameDnses; 180 boolean sameGateways; 181 182 LinkProperties target = (LinkProperties) obj; 183 184 Collection<InetAddress> targetAddresses = target.getAddresses(); 185 Collection<InetAddress> sourceAddresses = getAddresses(); 186 sameAddresses = (sourceAddresses.size() == targetAddresses.size()) ? 187 sourceAddresses.containsAll(targetAddresses) : false; 188 189 Collection<InetAddress> targetDnses = target.getDnses(); 190 sameDnses = (mDnses.size() == targetDnses.size()) ? 191 mDnses.containsAll(targetDnses) : false; 192 193 Collection<InetAddress> targetGateways = target.getGateways(); 194 sameGateways = (mGateways.size() == targetGateways.size()) ? 195 mGateways.containsAll(targetGateways) : false; 196 197 return 198 sameAddresses && sameDnses && sameGateways 199 && TextUtils.equals(getInterfaceName(), target.getInterfaceName()) 200 && (getHttpProxy() == null ? target.getHttpProxy() == null : 201 getHttpProxy().equals(target.getHttpProxy())); 202 } 203 204 @Override 205 /** 206 * generate hashcode based on significant fields 207 * Equal objects must produce the same hash code, while unequal objects 208 * may have the same hash codes. 209 */ 210 public int hashCode() { 211 return ((null == mIfaceName) ? 0 : mIfaceName.hashCode() 212 + mLinkAddresses.size() * 31 213 + mDnses.size() * 37 214 + mGateways.size() * 41 215 + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())); 216 } 217 218 /** 219 * Implement the Parcelable interface. 220 * @hide 221 */ 222 public void writeToParcel(Parcel dest, int flags) { 223 dest.writeString(getInterfaceName()); 224 dest.writeInt(mLinkAddresses.size()); 225 for(LinkAddress linkAddress : mLinkAddresses) { 226 dest.writeParcelable(linkAddress, flags); 227 } 228 229 dest.writeInt(mDnses.size()); 230 for(InetAddress d : mDnses) { 231 dest.writeByteArray(d.getAddress()); 232 } 233 234 dest.writeInt(mGateways.size()); 235 for(InetAddress gw : mGateways) { 236 dest.writeByteArray(gw.getAddress()); 237 } 238 239 if (mHttpProxy != null) { 240 dest.writeByte((byte)1); 241 dest.writeParcelable(mHttpProxy, flags); 242 } else { 243 dest.writeByte((byte)0); 244 } 245 } 246 247 /** 248 * Implement the Parcelable interface. 249 * @hide 250 */ 251 public static final Creator<LinkProperties> CREATOR = 252 new Creator<LinkProperties>() { 253 public LinkProperties createFromParcel(Parcel in) { 254 LinkProperties netProp = new LinkProperties(); 255 String iface = in.readString(); 256 if (iface != null) { 257 try { 258 netProp.setInterfaceName(iface); 259 } catch (Exception e) { 260 return null; 261 } 262 } 263 int addressCount = in.readInt(); 264 for (int i=0; i<addressCount; i++) { 265 netProp.addLinkAddress((LinkAddress)in.readParcelable(null)); 266 } 267 addressCount = in.readInt(); 268 for (int i=0; i<addressCount; i++) { 269 try { 270 netProp.addDns(InetAddress.getByAddress(in.createByteArray())); 271 } catch (UnknownHostException e) { } 272 } 273 addressCount = in.readInt(); 274 for (int i=0; i<addressCount; i++) { 275 try { 276 netProp.addGateway(InetAddress.getByAddress(in.createByteArray())); 277 } catch (UnknownHostException e) { } 278 } 279 if (in.readByte() == 1) { 280 netProp.setHttpProxy((ProxyProperties)in.readParcelable(null)); 281 } 282 return netProp; 283 } 284 285 public LinkProperties[] newArray(int size) { 286 return new LinkProperties[size]; 287 } 288 }; 289} 290