blob: 47b74ab4d23f458e3fcfc9631418cb3920496880 [file] [log] [blame]
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001/*
Wink Saville6e809972010-09-21 09:15:35 -07002 * Copyright (C) 2010 The Android Open Source Project
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07003 *
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
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -070019import android.annotation.NonNull;
Jason Monk207900c2014-04-25 15:00:09 -040020import android.net.ProxyInfo;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070021import android.os.Parcelable;
22import android.os.Parcel;
John Wang4e900092011-04-04 12:35:42 -070023import android.text.TextUtils;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070024
25import java.net.InetAddress;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080026import java.net.Inet4Address;
Lorenzo Colitti4faa0272013-08-08 11:00:12 +090027import java.net.Inet6Address;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070028import java.net.UnknownHostException;
29import java.util.ArrayList;
30import java.util.Collection;
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070031import java.util.Collections;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080032import java.util.Hashtable;
Robert Greenwaltdf2b8782014-06-06 10:30:11 -070033import java.util.List;
Lorenzo Colittic17a1b92014-06-12 23:10:17 +090034import java.util.Objects;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070035
36/**
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070037 * Describes the properties of a network link.
Robert Greenwalt992564e2011-02-09 13:56:06 -080038 *
39 * A link represents a connection to a network.
40 * It may have multiple addresses and multiple gateways,
Robert Greenwalt4f05d552014-05-18 22:01:38 -070041 * multiple dns servers but only one http proxy and one
42 * network interface.
Robert Greenwalt992564e2011-02-09 13:56:06 -080043 *
Robert Greenwalt4f05d552014-05-18 22:01:38 -070044 * Note that this is just a holder of data. Modifying it
45 * does not affect live networks.
Robert Greenwalt992564e2011-02-09 13:56:06 -080046 *
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070047 */
Robert Greenwalte595b972014-06-12 16:24:38 -070048public final class LinkProperties implements Parcelable {
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080049 // The interface described by the network link.
Robert Greenwalt4717c262012-10-31 14:32:53 -070050 private String mIfaceName;
Lorenzo Colitti64483942013-11-15 18:43:52 +090051 private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
52 private ArrayList<InetAddress> mDnses = new ArrayList<InetAddress>();
Robert Greenwalt8058f622012-11-09 10:52:27 -080053 private String mDomains;
Lorenzo Colitti64483942013-11-15 18:43:52 +090054 private ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
Jason Monk207900c2014-04-25 15:00:09 -040055 private ProxyInfo mHttpProxy;
sy.yun9d9b74a2013-09-02 05:24:09 +090056 private int mMtu;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070057
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080058 // Stores the properties of links that are "stacked" above this link.
59 // Indexed by interface name to allow modification and to prevent duplicates being added.
60 private Hashtable<String, LinkProperties> mStackedLinks =
61 new Hashtable<String, LinkProperties>();
62
Robert Greenwaltdf2b8782014-06-06 10:30:11 -070063 /**
64 * @hide
65 */
Robert Greenwalt0a46db52011-07-14 14:28:05 -070066 public static class CompareResult<T> {
Robert Greenwaltdf2b8782014-06-06 10:30:11 -070067 public List<T> removed = new ArrayList<T>();
68 public List<T> added = new ArrayList<T>();
Wink Savillee8222252011-07-13 13:44:13 -070069
70 @Override
71 public String toString() {
Robert Greenwalt0a46db52011-07-14 14:28:05 -070072 String retVal = "removed=[";
73 for (T addr : removed) retVal += addr.toString() + ",";
74 retVal += "] added=[";
75 for (T addr : added) retVal += addr.toString() + ",";
Wink Savillee8222252011-07-13 13:44:13 -070076 retVal += "]";
77 return retVal;
78 }
79 }
80
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -070081 /**
82 * @hide
83 */
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070084 public LinkProperties() {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -070085 }
86
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -070087 /**
88 * @hide
89 */
Robert Greenwalt37e65eb2010-08-30 10:56:47 -070090 public LinkProperties(LinkProperties source) {
Irfan Sheriffef6c1432010-08-30 20:37:17 -070091 if (source != null) {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -070092 mIfaceName = source.getInterfaceName();
Robert Greenwalt0d8acea2011-07-28 17:21:25 -070093 for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
Robert Greenwaltdf2b8782014-06-06 10:30:11 -070094 for (InetAddress i : source.getDnsServers()) mDnses.add(i);
Robert Greenwalt8058f622012-11-09 10:52:27 -080095 mDomains = source.getDomains();
Robert Greenwalt0d8acea2011-07-28 17:21:25 -070096 for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
Wink Savillebe2b0582011-05-18 15:59:04 -070097 mHttpProxy = (source.getHttpProxy() == null) ?
Jason Monk207900c2014-04-25 15:00:09 -040098 null : new ProxyInfo(source.getHttpProxy());
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -080099 for (LinkProperties l: source.mStackedLinks.values()) {
100 addStackedLink(l);
101 }
sy.yun9d9b74a2013-09-02 05:24:09 +0900102 setMtu(source.getMtu());
Irfan Sheriffef6c1432010-08-30 20:37:17 -0700103 }
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700104 }
105
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700106 /**
107 * Sets the interface name for this link. All {@link RouteInfo} already set for this
108 * will have their interface changed to match this new value.
109 *
110 * @param iface The name of the network interface used for this link.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700111 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700112 */
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700113 public void setInterfaceName(String iface) {
114 mIfaceName = iface;
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800115 ArrayList<RouteInfo> newRoutes = new ArrayList<RouteInfo>(mRoutes.size());
116 for (RouteInfo route : mRoutes) {
117 newRoutes.add(routeWithInterface(route));
118 }
119 mRoutes = newRoutes;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700120 }
121
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700122 /**
123 * Gets the interface name for this link. May be {@code null} if not set.
124 *
125 * @return The interface name set for this link or {@code null}.
126 */
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700127 public String getInterfaceName() {
128 return mIfaceName;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700129 }
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700130
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700131 /**
132 * @hide
133 */
134 public List<String> getAllInterfaceNames() {
135 List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
Robert Greenwalt55187f12013-03-22 12:00:17 -0700136 if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
Lorenzo Colitti4aa9bcf2013-03-20 19:22:58 +0900137 for (LinkProperties stacked: mStackedLinks.values()) {
138 interfaceNames.addAll(stacked.getAllInterfaceNames());
139 }
140 return interfaceNames;
141 }
142
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900143 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700144 * Returns all the addresses on this link. We often think of a link having a single address,
145 * however, particularly with Ipv6 several addresses are typical. Note that the
146 * {@code LinkProperties} actually contains {@link LinkAddress} objects which also include
147 * prefix lengths for each address. This is a simplified utility alternative to
148 * {@link LinkProperties#getLinkAddresses}.
149 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700150 * @return An umodifiable {@link List} of {@link InetAddress} for this link.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700151 * @hide
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900152 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700153 public List<InetAddress> getAddresses() {
154 List<InetAddress> addresses = new ArrayList<InetAddress>();
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700155 for (LinkAddress linkAddress : mLinkAddresses) {
156 addresses.add(linkAddress.getAddress());
157 }
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700158 return Collections.unmodifiableList(addresses);
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700159 }
160
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900161 /**
162 * Returns all the addresses on this link and all the links stacked above it.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700163 * @hide
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900164 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700165 public List<InetAddress> getAllAddresses() {
166 List<InetAddress> addresses = new ArrayList<InetAddress>();
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900167 for (LinkAddress linkAddress : mLinkAddresses) {
168 addresses.add(linkAddress.getAddress());
169 }
170 for (LinkProperties stacked: mStackedLinks.values()) {
171 addresses.addAll(stacked.getAllAddresses());
172 }
173 return addresses;
174 }
175
Lorenzo Colitti64483942013-11-15 18:43:52 +0900176 private int findLinkAddressIndex(LinkAddress address) {
177 for (int i = 0; i < mLinkAddresses.size(); i++) {
178 if (mLinkAddresses.get(i).isSameAddressAs(address)) {
179 return i;
180 }
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900181 }
Lorenzo Colitti64483942013-11-15 18:43:52 +0900182 return -1;
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900183 }
184
185 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700186 * Adds a {@link LinkAddress} to this {@code LinkProperties} if a {@link LinkAddress} of the
187 * same address/prefix does not already exist. If it does exist it is replaced.
Lorenzo Colitti64483942013-11-15 18:43:52 +0900188 * @param address The {@code LinkAddress} to add.
189 * @return true if {@code address} was added or updated, false otherwise.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700190 * @hide
Lorenzo Colitti64483942013-11-15 18:43:52 +0900191 */
192 public boolean addLinkAddress(LinkAddress address) {
193 if (address == null) {
194 return false;
195 }
196 int i = findLinkAddressIndex(address);
197 if (i < 0) {
198 // Address was not present. Add it.
199 mLinkAddresses.add(address);
200 return true;
201 } else if (mLinkAddresses.get(i).equals(address)) {
202 // Address was present and has same properties. Do nothing.
203 return false;
204 } else {
205 // Address was present and has different properties. Update it.
206 mLinkAddresses.set(i, address);
207 return true;
208 }
209 }
210
211 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700212 * Removes a {@link LinkAddress} from this {@code LinkProperties}. Specifically, matches
213 * and {@link LinkAddress} with the same address and prefix.
214 *
215 * @param toRemove A {@link LinkAddress} specifying the address to remove.
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900216 * @return true if the address was removed, false if it did not exist.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700217 * @hide
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900218 */
219 public boolean removeLinkAddress(LinkAddress toRemove) {
Lorenzo Colitti64483942013-11-15 18:43:52 +0900220 int i = findLinkAddressIndex(toRemove);
221 if (i >= 0) {
222 mLinkAddresses.remove(i);
223 return true;
224 }
225 return false;
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700226 }
227
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900228 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700229 * Returns all the {@link LinkAddress} on this link. Typically a link will have
230 * one IPv4 address and one or more IPv6 addresses.
231 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700232 * @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900233 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700234 public List<LinkAddress> getLinkAddresses() {
235 return Collections.unmodifiableList(mLinkAddresses);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700236 }
237
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900238 /**
239 * Returns all the addresses on this link and all the links stacked above it.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700240 * @hide
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900241 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700242 public List<LinkAddress> getAllLinkAddresses() {
243 List<LinkAddress> addresses = new ArrayList<LinkAddress>();
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900244 addresses.addAll(mLinkAddresses);
245 for (LinkProperties stacked: mStackedLinks.values()) {
246 addresses.addAll(stacked.getAllLinkAddresses());
247 }
248 return addresses;
249 }
250
Lorenzo Colitti22f407b2013-08-23 20:54:49 +0900251 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700252 * Replaces the {@link LinkAddress} in this {@code LinkProperties} with
253 * the given {@link Collection} of {@link LinkAddress}.
254 *
255 * @param addresses The {@link Collection} of {@link LinkAddress} to set in this
256 * object.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700257 * @hide
Lorenzo Colitti22f407b2013-08-23 20:54:49 +0900258 */
259 public void setLinkAddresses(Collection<LinkAddress> addresses) {
260 mLinkAddresses.clear();
261 for (LinkAddress address: addresses) {
262 addLinkAddress(address);
263 }
264 }
265
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700266 /**
Lorenzo Colitti309a75d2014-06-24 00:34:39 +0900267 * Adds the given {@link InetAddress} to the list of DNS servers, if not present.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700268 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700269 * @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
Lorenzo Colitti309a75d2014-06-24 00:34:39 +0900270 * @return true if the DNS server was added, false if it was already present.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700271 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700272 */
Lorenzo Colitti309a75d2014-06-24 00:34:39 +0900273 public boolean addDnsServer(InetAddress dnsServer) {
274 if (dnsServer != null && !mDnses.contains(dnsServer)) {
275 mDnses.add(dnsServer);
276 return true;
277 }
278 return false;
279 }
280
281 /**
282 * Replaces the DNS servers in this {@code LinkProperties} with
283 * the given {@link Collection} of {@link InetAddress} objects.
284 *
285 * @param addresses The {@link Collection} of DNS servers to set in this object.
286 * @hide
287 */
288 public void setDnsServers(Collection<InetAddress> dnsServers) {
289 mDnses.clear();
290 for (InetAddress dnsServer: dnsServers) {
291 addDnsServer(dnsServer);
292 }
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700293 }
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700294
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700295 /**
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700296 * Returns all the {@link InetAddress} for DNS servers on this link.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700297 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700298 * @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700299 * this link.
300 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700301 public List<InetAddress> getDnsServers() {
302 return Collections.unmodifiableList(mDnses);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700303 }
304
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700305 /**
306 * Sets the DNS domain search path used on this link.
307 *
308 * @param domains A {@link String} listing in priority order the comma separated
309 * domains to search when resolving host names on this link.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700310 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700311 */
Robert Greenwalt8058f622012-11-09 10:52:27 -0800312 public void setDomains(String domains) {
313 mDomains = domains;
314 }
315
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700316 /**
317 * Get the DNS domains search path set for this link.
318 *
319 * @return A {@link String} containing the comma separated domains to search when resolving
320 * host names on this link.
321 */
322 public String getDomains() {
323 return mDomains;
324 }
325
326 /**
327 * Sets the Maximum Transmission Unit size to use on this link. This should not be used
328 * unless the system default (1500) is incorrect. Values less than 68 or greater than
329 * 10000 will be ignored.
330 *
331 * @param mtu The MTU to use for this link.
332 * @hide
333 */
sy.yun9d9b74a2013-09-02 05:24:09 +0900334 public void setMtu(int mtu) {
335 mMtu = mtu;
336 }
337
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700338 /**
339 * Gets any non-default MTU size set for this link. Note that if the default is being used
340 * this will return 0.
341 *
342 * @return The mtu value set for this link.
343 * @hide
344 */
sy.yun9d9b74a2013-09-02 05:24:09 +0900345 public int getMtu() {
346 return mMtu;
347 }
348
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800349 private RouteInfo routeWithInterface(RouteInfo route) {
350 return new RouteInfo(
351 route.getDestination(),
352 route.getGateway(),
353 mIfaceName);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700354 }
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800355
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700356 /**
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900357 * Adds a {@link RouteInfo} to this {@code LinkProperties}, if not present. If the
358 * {@link RouteInfo} had an interface name set and that differs from the interface set for this
359 * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown. The proper
360 * course is to add either un-named or properly named {@link RouteInfo}.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700361 *
362 * @param route A {@link RouteInfo} to add to this object.
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900363 * @return {@code false} if the route was already present, {@code true} if it was added.
364 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700365 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700366 */
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900367 public boolean addRoute(RouteInfo route) {
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800368 if (route != null) {
369 String routeIface = route.getInterface();
370 if (routeIface != null && !routeIface.equals(mIfaceName)) {
Lorenzo Colitti1994bc12013-03-08 19:11:40 -0800371 throw new IllegalArgumentException(
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800372 "Route added with non-matching interface: " + routeIface +
Lorenzo Colitti1994bc12013-03-08 19:11:40 -0800373 " vs. " + mIfaceName);
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800374 }
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900375 route = routeWithInterface(route);
376 if (!mRoutes.contains(route)) {
377 mRoutes.add(route);
378 return true;
379 }
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800380 }
Lorenzo Colittic17a1b92014-06-12 23:10:17 +0900381 return false;
382 }
383
384 /**
385 * Removes a {@link RouteInfo} from this {@code LinkProperties}, if present. The route must
386 * specify an interface and the interface must match the interface of this
387 * {@code LinkProperties}, or it will not be removed.
388 *
389 * @return {@code true} if the route was removed, {@code false} if it was not present.
390 *
391 * @hide
392 */
393 public boolean removeRoute(RouteInfo route) {
394 return route != null &&
395 Objects.equals(mIfaceName, route.getInterface()) &&
396 mRoutes.remove(route);
Lorenzo Colitti45b9a5b2013-03-08 11:30:39 -0800397 }
398
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800399 /**
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700400 * Returns all the {@link RouteInfo} set on this link.
401 *
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700402 * @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800403 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700404 public List<RouteInfo> getRoutes() {
405 return Collections.unmodifiableList(mRoutes);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700406 }
407
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800408 /**
409 * Returns all the routes on this link and all the links stacked above it.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700410 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800411 */
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700412 public List<RouteInfo> getAllRoutes() {
413 List<RouteInfo> routes = new ArrayList();
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800414 routes.addAll(mRoutes);
415 for (LinkProperties stacked: mStackedLinks.values()) {
416 routes.addAll(stacked.getAllRoutes());
417 }
Robert Greenwalt6629bcd2013-03-15 11:28:50 -0700418 return routes;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800419 }
420
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700421 /**
422 * Sets the recommended {@link ProxyInfo} to use on this link, or {@code null} for none.
423 * Note that Http Proxies are only a hint - the system recommends their use, but it does
424 * not enforce it and applications may ignore them.
425 *
426 * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700427 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700428 */
Jason Monk207900c2014-04-25 15:00:09 -0400429 public void setHttpProxy(ProxyInfo proxy) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700430 mHttpProxy = proxy;
431 }
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700432
433 /**
434 * Gets the recommended {@link ProxyInfo} (or {@code null}) set on this link.
435 *
436 * @return The {@link ProxyInfo} set on this link
437 */
Jason Monk207900c2014-04-25 15:00:09 -0400438 public ProxyInfo getHttpProxy() {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700439 return mHttpProxy;
440 }
441
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800442 /**
443 * Adds a stacked link.
444 *
445 * If there is already a stacked link with the same interfacename as link,
446 * that link is replaced with link. Otherwise, link is added to the list
447 * of stacked links. If link is null, nothing changes.
448 *
449 * @param link The link to add.
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900450 * @return true if the link was stacked, false otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700451 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800452 */
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900453 public boolean addStackedLink(LinkProperties link) {
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800454 if (link != null && link.getInterfaceName() != null) {
455 mStackedLinks.put(link.getInterfaceName(), link);
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900456 return true;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800457 }
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900458 return false;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800459 }
460
461 /**
462 * Removes a stacked link.
463 *
464 * If there a stacked link with the same interfacename as link, it is
465 * removed. Otherwise, nothing changes.
466 *
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900467 * @param link The link to remove.
468 * @return true if the link was removed, false otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700469 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800470 */
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900471 public boolean removeStackedLink(LinkProperties link) {
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800472 if (link != null && link.getInterfaceName() != null) {
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900473 LinkProperties removed = mStackedLinks.remove(link.getInterfaceName());
474 return removed != null;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800475 }
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900476 return false;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800477 }
478
479 /**
480 * Returns all the links stacked on top of this link.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700481 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800482 */
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700483 public @NonNull List<LinkProperties> getStackedLinks() {
484 if (mStackedLinks.isEmpty()) {
485 return Collections.EMPTY_LIST;
486 }
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700487 List<LinkProperties> stacked = new ArrayList<LinkProperties>();
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800488 for (LinkProperties link : mStackedLinks.values()) {
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700489 stacked.add(new LinkProperties(link));
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800490 }
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700491 return Collections.unmodifiableList(stacked);
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800492 }
493
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700494 /**
495 * Clears this object to its initial state.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700496 * @hide
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700497 */
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700498 public void clear() {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700499 mIfaceName = null;
Wink Savillee8222252011-07-13 13:44:13 -0700500 mLinkAddresses.clear();
501 mDnses.clear();
Robert Greenwalt8058f622012-11-09 10:52:27 -0800502 mDomains = null;
Wink Savillee8222252011-07-13 13:44:13 -0700503 mRoutes.clear();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700504 mHttpProxy = null;
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800505 mStackedLinks.clear();
sy.yun9d9b74a2013-09-02 05:24:09 +0900506 mMtu = 0;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700507 }
508
509 /**
510 * Implement the Parcelable interface
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700511 */
512 public int describeContents() {
513 return 0;
514 }
515
Wink Saville1f6408a2010-08-27 11:15:18 -0700516 @Override
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700517 public String toString() {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700518 String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " ");
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700519
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700520 String linkAddresses = "LinkAddresses: [";
John Wang4e900092011-04-04 12:35:42 -0700521 for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString() + ",";
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700522 linkAddresses += "] ";
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700523
524 String dns = "DnsAddresses: [";
Wink Saville1f6408a2010-08-27 11:15:18 -0700525 for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700526 dns += "] ";
527
Robert Greenwalt8058f622012-11-09 10:52:27 -0800528 String domainName = "Domains: " + mDomains;
529
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700530 String mtu = " MTU: " + mMtu;
sy.yun9d9b74a2013-09-02 05:24:09 +0900531
Robert Greenwalt8058f622012-11-09 10:52:27 -0800532 String routes = " Routes: [";
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700533 for (RouteInfo route : mRoutes) routes += route.toString() + ",";
534 routes += "] ";
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -0700535 String proxy = (mHttpProxy == null ? "" : " HttpProxy: " + mHttpProxy.toString() + " ");
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700536
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800537 String stacked = "";
538 if (mStackedLinks.values().size() > 0) {
539 stacked += " Stacked: [";
540 for (LinkProperties link: mStackedLinks.values()) {
541 stacked += " [" + link.toString() + " ],";
542 }
543 stacked += "] ";
544 }
sy.yun9d9b74a2013-09-02 05:24:09 +0900545 return "{" + ifaceName + linkAddresses + routes + dns + domainName + mtu
546 + proxy + stacked + "}";
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800547 }
548
549 /**
550 * Returns true if this link has an IPv4 address.
551 *
552 * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700553 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800554 */
555 public boolean hasIPv4Address() {
556 for (LinkAddress address : mLinkAddresses) {
557 if (address.getAddress() instanceof Inet4Address) {
558 return true;
559 }
560 }
561 return false;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700562 }
563
Wink Savillee8222252011-07-13 13:44:13 -0700564 /**
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +0900565 * Returns true if this link has a global preferred IPv6 address.
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900566 *
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +0900567 * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise.
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700568 * @hide
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900569 */
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +0900570 public boolean hasGlobalIPv6Address() {
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900571 for (LinkAddress address : mLinkAddresses) {
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +0900572 if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) {
Lorenzo Colitti4faa0272013-08-08 11:00:12 +0900573 return true;
574 }
575 }
576 return false;
577 }
578
579 /**
Lorenzo Colitti76ea6c62014-06-23 22:33:43 +0900580 * Returns true if this link has an IPv4 default route.
581 *
582 * @return {@code true} if there is an IPv4 default route, {@code false} otherwise.
583 * @hide
584 */
585 public boolean hasIPv4DefaultRoute() {
586 for (RouteInfo r : mRoutes) {
587 if (r.isIPv4Default()) {
588 return true;
589 }
590 }
591 return false;
592 }
593
594 /**
595 * Returns true if this link has an IPv6 default route.
596 *
597 * @return {@code true} if there is an IPv6 default route, {@code false} otherwise.
598 * @hide
599 */
600 public boolean hasIPv6DefaultRoute() {
601 for (RouteInfo r : mRoutes) {
602 if (r.isIPv6Default()) {
603 return true;
604 }
605 }
606 return false;
607 }
608
609 /**
610 * Returns true if this link has an IPv4 DNS server.
611 *
612 * @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise.
613 * @hide
614 */
615 public boolean hasIPv4DnsServer() {
616 for (InetAddress ia : mDnses) {
617 if (ia instanceof Inet4Address) {
618 return true;
619 }
620 }
621 return false;
622 }
623
624 /**
625 * Returns true if this link has an IPv6 DNS server.
626 *
627 * @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise.
628 * @hide
629 */
630 public boolean hasIPv6DnsServer() {
631 for (InetAddress ia : mDnses) {
632 if (ia instanceof Inet6Address) {
633 return true;
634 }
635 }
636 return false;
637 }
638
639 /**
640 * Returns true if this link is provisioned for global connectivity. For IPv6, this requires an
641 * IP address, default route, and DNS server. For IPv4, this requires only an IPv4 address,
642 * because WifiStateMachine accepts static configurations that only specify an address but not
643 * DNS servers or a default route.
644 *
645 * @return {@code true} if the link is provisioned, {@code false} otherwise.
646 * @hide
647 */
648 public boolean isProvisioned() {
649 return (hasIPv4Address() ||
650 (hasGlobalIPv6Address() && hasIPv6DefaultRoute() && hasIPv6DnsServer()));
651 }
652
653 /**
Wink Savillee8222252011-07-13 13:44:13 -0700654 * Compares this {@code LinkProperties} interface name against the target
655 *
656 * @param target LinkProperties to compare.
657 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700658 * @hide
Wink Savillee8222252011-07-13 13:44:13 -0700659 */
660 public boolean isIdenticalInterfaceName(LinkProperties target) {
661 return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
662 }
663
664 /**
Robert Greenwalt4717c262012-10-31 14:32:53 -0700665 * Compares this {@code LinkProperties} interface addresses against the target
Wink Savillee8222252011-07-13 13:44:13 -0700666 *
667 * @param target LinkProperties to compare.
668 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700669 * @hide
Wink Savillee8222252011-07-13 13:44:13 -0700670 */
671 public boolean isIdenticalAddresses(LinkProperties target) {
672 Collection<InetAddress> targetAddresses = target.getAddresses();
673 Collection<InetAddress> sourceAddresses = getAddresses();
674 return (sourceAddresses.size() == targetAddresses.size()) ?
675 sourceAddresses.containsAll(targetAddresses) : false;
676 }
677
678 /**
679 * Compares this {@code LinkProperties} DNS addresses against the target
680 *
681 * @param target LinkProperties to compare.
682 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700683 * @hide
Wink Savillee8222252011-07-13 13:44:13 -0700684 */
685 public boolean isIdenticalDnses(LinkProperties target) {
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700686 Collection<InetAddress> targetDnses = target.getDnsServers();
Robert Greenwalt8058f622012-11-09 10:52:27 -0800687 String targetDomains = target.getDomains();
688 if (mDomains == null) {
689 if (targetDomains != null) return false;
690 } else {
691 if (mDomains.equals(targetDomains) == false) return false;
692 }
Wink Savillee8222252011-07-13 13:44:13 -0700693 return (mDnses.size() == targetDnses.size()) ?
694 mDnses.containsAll(targetDnses) : false;
695 }
696
697 /**
698 * Compares this {@code LinkProperties} Routes against the target
699 *
700 * @param target LinkProperties to compare.
701 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700702 * @hide
Wink Savillee8222252011-07-13 13:44:13 -0700703 */
704 public boolean isIdenticalRoutes(LinkProperties target) {
705 Collection<RouteInfo> targetRoutes = target.getRoutes();
706 return (mRoutes.size() == targetRoutes.size()) ?
707 mRoutes.containsAll(targetRoutes) : false;
708 }
709
710 /**
711 * Compares this {@code LinkProperties} HttpProxy against the target
712 *
713 * @param target LinkProperties to compare.
714 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700715 * @hide
Wink Savillee8222252011-07-13 13:44:13 -0700716 */
717 public boolean isIdenticalHttpProxy(LinkProperties target) {
718 return getHttpProxy() == null ? target.getHttpProxy() == null :
719 getHttpProxy().equals(target.getHttpProxy());
720 }
John Wang4e900092011-04-04 12:35:42 -0700721
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800722 /**
723 * Compares this {@code LinkProperties} stacked links against the target
724 *
725 * @param target LinkProperties to compare.
726 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700727 * @hide
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800728 */
729 public boolean isIdenticalStackedLinks(LinkProperties target) {
Lorenzo Colitti213f98b2013-04-01 10:47:43 +0900730 if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) {
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800731 return false;
732 }
733 for (LinkProperties stacked : mStackedLinks.values()) {
734 // Hashtable values can never be null.
735 String iface = stacked.getInterfaceName();
736 if (!stacked.equals(target.mStackedLinks.get(iface))) {
737 return false;
738 }
739 }
740 return true;
741 }
742
sy.yun9d9b74a2013-09-02 05:24:09 +0900743 /**
744 * Compares this {@code LinkProperties} MTU against the target
745 *
Ying Wangd57de6a2013-09-06 22:53:16 -0700746 * @param target LinkProperties to compare.
sy.yun9d9b74a2013-09-02 05:24:09 +0900747 * @return {@code true} if both are identical, {@code false} otherwise.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700748 * @hide
sy.yun9d9b74a2013-09-02 05:24:09 +0900749 */
750 public boolean isIdenticalMtu(LinkProperties target) {
751 return getMtu() == target.getMtu();
752 }
753
John Wang4e900092011-04-04 12:35:42 -0700754 @Override
755 /**
756 * Compares this {@code LinkProperties} instance against the target
757 * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
758 * all their fields are equal in values.
759 *
760 * For collection fields, such as mDnses, containsAll() is used to check
761 * if two collections contains the same elements, independent of order.
762 * There are two thoughts regarding containsAll()
763 * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
764 * 2. Worst case performance is O(n^2).
765 *
766 * @param obj the object to be tested for equality.
767 * @return {@code true} if both objects are equal, {@code false} otherwise.
768 */
769 public boolean equals(Object obj) {
770 if (this == obj) return true;
771
772 if (!(obj instanceof LinkProperties)) return false;
773
John Wang4e900092011-04-04 12:35:42 -0700774 LinkProperties target = (LinkProperties) obj;
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700775 /**
776 * This method does not check that stacked interfaces are equal, because
777 * stacked interfaces are not so much a property of the link as a
778 * description of connections between links.
779 */
Wink Savillee8222252011-07-13 13:44:13 -0700780 return isIdenticalInterfaceName(target) &&
781 isIdenticalAddresses(target) &&
782 isIdenticalDnses(target) &&
783 isIdenticalRoutes(target) &&
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800784 isIdenticalHttpProxy(target) &&
sy.yun9d9b74a2013-09-02 05:24:09 +0900785 isIdenticalStackedLinks(target) &&
786 isIdenticalMtu(target);
Wink Savillee8222252011-07-13 13:44:13 -0700787 }
John Wang4e900092011-04-04 12:35:42 -0700788
Wink Savillee8222252011-07-13 13:44:13 -0700789 /**
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900790 * Compares the addresses in this LinkProperties with another
791 * LinkProperties, examining only addresses on the base link.
Wink Savillee8222252011-07-13 13:44:13 -0700792 *
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900793 * @param target a LinkProperties with the new list of addresses
794 * @return the differences between the addresses.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700795 * @hide
Wink Savillee8222252011-07-13 13:44:13 -0700796 */
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700797 public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
Wink Savillee8222252011-07-13 13:44:13 -0700798 /*
799 * Duplicate the LinkAddresses into removed, we will be removing
800 * address which are common between mLinkAddresses and target
801 * leaving the addresses that are different. And address which
802 * are in target but not in mLinkAddresses are placed in the
803 * addedAddresses.
804 */
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700805 CompareResult<LinkAddress> result = new CompareResult<LinkAddress>();
Wink Savillee8222252011-07-13 13:44:13 -0700806 result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
807 result.added.clear();
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700808 if (target != null) {
809 for (LinkAddress newAddress : target.getLinkAddresses()) {
810 if (! result.removed.remove(newAddress)) {
811 result.added.add(newAddress);
812 }
Wink Savillee8222252011-07-13 13:44:13 -0700813 }
814 }
815 return result;
John Wang4e900092011-04-04 12:35:42 -0700816 }
817
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700818 /**
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900819 * Compares the DNS addresses in this LinkProperties with another
820 * LinkProperties, examining only DNS addresses on the base link.
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700821 *
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900822 * @param target a LinkProperties with the new list of dns addresses
823 * @return the differences between the DNS addresses.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700824 * @hide
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700825 */
826 public CompareResult<InetAddress> compareDnses(LinkProperties target) {
827 /*
828 * Duplicate the InetAddresses into removed, we will be removing
829 * dns address which are common between mDnses and target
830 * leaving the addresses that are different. And dns address which
831 * are in target but not in mDnses are placed in the
832 * addedAddresses.
833 */
834 CompareResult<InetAddress> result = new CompareResult<InetAddress>();
835
836 result.removed = new ArrayList<InetAddress>(mDnses);
837 result.added.clear();
838 if (target != null) {
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700839 for (InetAddress newAddress : target.getDnsServers()) {
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700840 if (! result.removed.remove(newAddress)) {
841 result.added.add(newAddress);
842 }
843 }
844 }
845 return result;
846 }
847
848 /**
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900849 * Compares all routes in this LinkProperties with another LinkProperties,
850 * examining both the the base link and all stacked links.
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700851 *
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900852 * @param target a LinkProperties with the new list of routes
853 * @return the differences between the routes.
Robert Greenwalt4f05d552014-05-18 22:01:38 -0700854 * @hide
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700855 */
Lorenzo Colittid1e0fae2013-07-31 23:23:21 +0900856 public CompareResult<RouteInfo> compareAllRoutes(LinkProperties target) {
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700857 /*
858 * Duplicate the RouteInfos into removed, we will be removing
Lorenzo Colitti1994bc12013-03-08 19:11:40 -0800859 * routes which are common between mRoutes and target
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700860 * leaving the routes that are different. And route address which
861 * are in target but not in mRoutes are placed in added.
862 */
863 CompareResult<RouteInfo> result = new CompareResult<RouteInfo>();
864
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800865 result.removed = getAllRoutes();
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700866 result.added.clear();
867 if (target != null) {
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800868 for (RouteInfo r : target.getAllRoutes()) {
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700869 if (! result.removed.remove(r)) {
870 result.added.add(r);
871 }
872 }
873 }
874 return result;
875 }
876
Paul Jensen992f2522014-04-28 10:33:11 -0400877 /**
878 * Compares all interface names in this LinkProperties with another
879 * LinkProperties, examining both the the base link and all stacked links.
880 *
881 * @param target a LinkProperties with the new list of interface names
882 * @return the differences between the interface names.
883 * @hide
884 */
885 public CompareResult<String> compareAllInterfaceNames(LinkProperties target) {
886 /*
887 * Duplicate the interface names into removed, we will be removing
888 * interface names which are common between this and target
889 * leaving the interface names that are different. And interface names which
890 * are in target but not in this are placed in added.
891 */
892 CompareResult<String> result = new CompareResult<String>();
893
894 result.removed = getAllInterfaceNames();
895 result.added.clear();
896 if (target != null) {
897 for (String r : target.getAllInterfaceNames()) {
898 if (! result.removed.remove(r)) {
899 result.added.add(r);
900 }
901 }
902 }
903 return result;
904 }
905
Robert Greenwalt0a46db52011-07-14 14:28:05 -0700906
John Wang4e900092011-04-04 12:35:42 -0700907 @Override
908 /**
909 * generate hashcode based on significant fields
910 * Equal objects must produce the same hash code, while unequal objects
911 * may have the same hash codes.
912 */
913 public int hashCode() {
914 return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
915 + mLinkAddresses.size() * 31
916 + mDnses.size() * 37
Robert Greenwalt8058f622012-11-09 10:52:27 -0800917 + ((null == mDomains) ? 0 : mDomains.hashCode())
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700918 + mRoutes.size() * 41
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800919 + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())
sy.yun9d9b74a2013-09-02 05:24:09 +0900920 + mStackedLinks.hashCode() * 47)
921 + mMtu * 51;
John Wang4e900092011-04-04 12:35:42 -0700922 }
923
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700924 /**
925 * Implement the Parcelable interface.
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700926 */
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700927 public void writeToParcel(Parcel dest, int flags) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700928 dest.writeString(getInterfaceName());
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700929 dest.writeInt(mLinkAddresses.size());
930 for(LinkAddress linkAddress : mLinkAddresses) {
931 dest.writeParcelable(linkAddress, flags);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700932 }
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700933
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700934 dest.writeInt(mDnses.size());
935 for(InetAddress d : mDnses) {
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700936 dest.writeByteArray(d.getAddress());
937 }
Robert Greenwalt8058f622012-11-09 10:52:27 -0800938 dest.writeString(mDomains);
sy.yun9d9b74a2013-09-02 05:24:09 +0900939 dest.writeInt(mMtu);
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700940 dest.writeInt(mRoutes.size());
941 for(RouteInfo route : mRoutes) {
942 dest.writeParcelable(route, flags);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700943 }
Robert Greenwalt992564e2011-02-09 13:56:06 -0800944
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700945 if (mHttpProxy != null) {
946 dest.writeByte((byte)1);
947 dest.writeParcelable(mHttpProxy, flags);
948 } else {
949 dest.writeByte((byte)0);
950 }
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800951 ArrayList<LinkProperties> stackedLinks = new ArrayList(mStackedLinks.values());
952 dest.writeList(stackedLinks);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700953 }
954
955 /**
956 * Implement the Parcelable interface.
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700957 */
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700958 public static final Creator<LinkProperties> CREATOR =
959 new Creator<LinkProperties>() {
960 public LinkProperties createFromParcel(Parcel in) {
961 LinkProperties netProp = new LinkProperties();
Robert Greenwalt4717c262012-10-31 14:32:53 -0700962
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700963 String iface = in.readString();
964 if (iface != null) {
Robert Greenwalt4717c262012-10-31 14:32:53 -0700965 netProp.setInterfaceName(iface);
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700966 }
967 int addressCount = in.readInt();
968 for (int i=0; i<addressCount; i++) {
Irfan Sheriffed5d7d12010-10-01 16:08:28 -0700969 netProp.addLinkAddress((LinkAddress)in.readParcelable(null));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700970 }
971 addressCount = in.readInt();
972 for (int i=0; i<addressCount; i++) {
973 try {
Robert Greenwaltdf2b8782014-06-06 10:30:11 -0700974 netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700975 } catch (UnknownHostException e) { }
976 }
Robert Greenwalt8058f622012-11-09 10:52:27 -0800977 netProp.setDomains(in.readString());
sy.yun9d9b74a2013-09-02 05:24:09 +0900978 netProp.setMtu(in.readInt());
Robert Greenwalt992564e2011-02-09 13:56:06 -0800979 addressCount = in.readInt();
980 for (int i=0; i<addressCount; i++) {
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700981 netProp.addRoute((RouteInfo)in.readParcelable(null));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700982 }
983 if (in.readByte() == 1) {
Jason Monk207900c2014-04-25 15:00:09 -0400984 netProp.setHttpProxy((ProxyInfo)in.readParcelable(null));
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700985 }
Lorenzo Colitti419a4ce2013-03-07 10:59:25 -0800986 ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
987 in.readList(stackedLinks, LinkProperties.class.getClassLoader());
988 for (LinkProperties stackedLink: stackedLinks) {
989 netProp.addStackedLink(stackedLink);
990 }
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700991 return netProp;
992 }
993
Robert Greenwalt37e65eb2010-08-30 10:56:47 -0700994 public LinkProperties[] newArray(int size) {
995 return new LinkProperties[size];
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700996 }
997 };
998}