LinkProperties.java revision 4faa027df03c241c92a12a437f20767ab4d6ee64
147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt/*
26e80997a9a7b6a15370544edde322cd8833e9524Wink Saville * Copyright (C) 2010 The Android Open Source Project
347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt *
447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License");
547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * you may not use this file except in compliance with the License.
647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * You may obtain a copy of the License at
747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt *
847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt *      http://www.apache.org/licenses/LICENSE-2.0
947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt *
1047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * Unless required by applicable law or agreed to in writing, software
1147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS,
1247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * See the License for the specific language governing permissions and
1447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * limitations under the License.
1547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt */
1647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
1747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltpackage android.net;
1847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
1937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwaltimport android.net.ProxyProperties;
2047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport android.os.Parcelable;
2147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport android.os.Parcel;
224e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wangimport android.text.TextUtils;
2347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
2447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.InetAddress;
25419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colittiimport java.net.Inet4Address;
264faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colittiimport java.net.Inet6Address;
27419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
2847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.UnknownHostException;
2947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.util.ArrayList;
3047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.util.Collection;
3137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwaltimport java.util.Collections;
32419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colittiimport java.util.Hashtable;
3347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
3447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt/**
3537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt * Describes the properties of a network link.
36992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt *
37992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * A link represents a connection to a network.
38992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * It may have multiple addresses and multiple gateways,
39992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * multiple dns servers but only one http proxy.
40992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt *
41992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * Because it's a single network, the dns's
42992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * are interchangeable and don't need associating with
43992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * particular addresses.  The gateways similarly don't
44992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * need associating with particular addresses.
45992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt *
46992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * A dual stack interface works fine in this model:
47992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * each address has it's own prefix length to describe
48992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * the local network.  The dns servers all return
49992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * both v4 addresses and v6 addresses regardless of the
50992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * address family of the server itself (rfc4213) and we
51992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * don't care which is used.  The gateways will be
52992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * selected based on the destination address and the
53992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * source address has no relavence.
54419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti *
55419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti * Links can also be stacked on top of each other.
56419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti * This can be used, for example, to represent a tunnel
57419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti * interface that runs on top of a physical interface.
58419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti *
5947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt * @hide
6047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt */
6137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwaltpublic class LinkProperties implements Parcelable {
62419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    // The interface described by the network link.
634717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    private String mIfaceName;
64e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private Collection<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
65e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private Collection<InetAddress> mDnses = new ArrayList<InetAddress>();
668058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt    private String mDomains;
67e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private Collection<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
6847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    private ProxyProperties mHttpProxy;
6947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
70419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    // Stores the properties of links that are "stacked" above this link.
71419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    // Indexed by interface name to allow modification and to prevent duplicates being added.
72419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    private Hashtable<String, LinkProperties> mStackedLinks =
73419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        new Hashtable<String, LinkProperties>();
74419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
750a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public static class CompareResult<T> {
76ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        public Collection<T> removed = new ArrayList<T>();
77ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        public Collection<T> added = new ArrayList<T>();
78e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
79e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        @Override
80e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        public String toString() {
810a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            String retVal = "removed=[";
820a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (T addr : removed) retVal += addr.toString() + ",";
830a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            retVal += "] added=[";
840a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (T addr : added) retVal += addr.toString() + ",";
85e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            retVal += "]";
86e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            return retVal;
87e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        }
88e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
89e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
9037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public LinkProperties() {
9147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        clear();
9247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
9347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
9437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    // copy constructor instead of clone
9537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public LinkProperties(LinkProperties source) {
96ef6c1431fa2039a4b8c604d651bb8f4dc0806581Irfan Sheriff        if (source != null) {
97ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            mIfaceName = source.getInterfaceName();
980d8acea9bb452d1fdbb3d811041f7bdb1b0ef8a3Robert Greenwalt            for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
990d8acea9bb452d1fdbb3d811041f7bdb1b0ef8a3Robert Greenwalt            for (InetAddress i : source.getDnses()) mDnses.add(i);
1008058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt            mDomains = source.getDomains();
1010d8acea9bb452d1fdbb3d811041f7bdb1b0ef8a3Robert Greenwalt            for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
102be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville            mHttpProxy = (source.getHttpProxy() == null)  ?
1038058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt                    null : new ProxyProperties(source.getHttpProxy());
104419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            for (LinkProperties l: source.mStackedLinks.values()) {
105419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                addStackedLink(l);
106419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            }
107ef6c1431fa2039a4b8c604d651bb8f4dc0806581Irfan Sheriff        }
10837e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    }
10937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt
110ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    public void setInterfaceName(String iface) {
111ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        mIfaceName = iface;
11245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        ArrayList<RouteInfo> newRoutes = new ArrayList<RouteInfo>(mRoutes.size());
11345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        for (RouteInfo route : mRoutes) {
11445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            newRoutes.add(routeWithInterface(route));
11545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        }
11645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        mRoutes = newRoutes;
11747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
118ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
11937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public String getInterfaceName() {
120ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        return mIfaceName;
12147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
12247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
1234aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti    public Collection<String> getAllInterfaceNames() {
1244aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti        Collection interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
12555187f18505aad67f824094061af1b6d0a0ebb38Robert Greenwalt        if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
1264aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti        for (LinkProperties stacked: mStackedLinks.values()) {
1274aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti            interfaceNames.addAll(stacked.getAllInterfaceNames());
1284aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti        }
1294aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti        return interfaceNames;
1304aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti    }
1314aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti
132d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    /**
133d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Returns all the addresses on this link.
134d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     */
13537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public Collection<InetAddress> getAddresses() {
136ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        Collection<InetAddress> addresses = new ArrayList<InetAddress>();
137ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        for (LinkAddress linkAddress : mLinkAddresses) {
138ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            addresses.add(linkAddress.getAddress());
139ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        }
140ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        return Collections.unmodifiableCollection(addresses);
141ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    }
142ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
143d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    /**
144d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Returns all the addresses on this link and all the links stacked above it.
145d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     */
146d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    public Collection<InetAddress> getAllAddresses() {
147d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        Collection<InetAddress> addresses = new ArrayList<InetAddress>();
148d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        for (LinkAddress linkAddress : mLinkAddresses) {
149d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti            addresses.add(linkAddress.getAddress());
150d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        }
151d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        for (LinkProperties stacked: mStackedLinks.values()) {
152d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti            addresses.addAll(stacked.getAllAddresses());
153d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        }
154d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        return addresses;
155d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    }
156d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti
1574faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    /**
1584faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * Adds a link address if it does not exist, or update it if it does.
1594faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @param address The {@code LinkAddress} to add.
1604faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @return true if the address was added, false if it already existed.
1614faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     */
1624faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    public boolean addLinkAddress(LinkAddress address) {
1634faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        // TODO: when the LinkAddress has other attributes beyond the
1644faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        // address and the prefix length, update them here.
1654faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        if (address != null && !mLinkAddresses.contains(address)) {
1664faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            mLinkAddresses.add(address);
1674faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            return true;
1684faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        }
1694faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        return false;
1704faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    }
1714faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti
1724faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    /**
1734faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * Removes a link address.
1744faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @param address The {@code LinkAddress} to remove.
1754faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @return true if the address was removed, false if it did not exist.
1764faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     */
1774faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    public boolean removeLinkAddress(LinkAddress toRemove) {
1784faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        return mLinkAddresses.remove(toRemove);
179ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    }
180ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
181d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    /**
182d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Returns all the addresses on this link.
183d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     */
184ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    public Collection<LinkAddress> getLinkAddresses() {
185ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        return Collections.unmodifiableCollection(mLinkAddresses);
18647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
18747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
188d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    /**
189d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Returns all the addresses on this link and all the links stacked above it.
190d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     */
191d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    public Collection<LinkAddress> getAllLinkAddresses() {
192d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        Collection<LinkAddress> addresses = new ArrayList<LinkAddress>();
193d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        addresses.addAll(mLinkAddresses);
194d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        for (LinkProperties stacked: mStackedLinks.values()) {
195d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti            addresses.addAll(stacked.getAllLinkAddresses());
196d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        }
197d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        return addresses;
198d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    }
199d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti
20037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void addDns(InetAddress dns) {
20104cac40ff86e175444991c07869cb85219db1019Robert Greenwalt        if (dns != null) mDnses.add(dns);
20247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
203ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
20437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public Collection<InetAddress> getDnses() {
20537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        return Collections.unmodifiableCollection(mDnses);
20647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
20747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
2088058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt    public String getDomains() {
2098058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        return mDomains;
2108058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt    }
2118058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt
2128058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt    public void setDomains(String domains) {
2138058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        mDomains = domains;
2148058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt    }
2158058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt
21645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    private RouteInfo routeWithInterface(RouteInfo route) {
21745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        return new RouteInfo(
21845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            route.getDestination(),
21945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            route.getGateway(),
22045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            mIfaceName);
22145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    }
22245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
223aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public void addRoute(RouteInfo route) {
22445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        if (route != null) {
22545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            String routeIface = route.getInterface();
22645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            if (routeIface != null && !routeIface.equals(mIfaceName)) {
2271994bc14ab9fd3a3c5dca8851cfc0042bcb25d46Lorenzo Colitti                throw new IllegalArgumentException(
22845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti                   "Route added with non-matching interface: " + routeIface +
2291994bc14ab9fd3a3c5dca8851cfc0042bcb25d46Lorenzo Colitti                   " vs. " + mIfaceName);
23045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            }
23145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            mRoutes.add(routeWithInterface(route));
23245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        }
23347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
23445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
235419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
236419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Returns all the routes on this link.
237419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
238aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt    public Collection<RouteInfo> getRoutes() {
239aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        return Collections.unmodifiableCollection(mRoutes);
24047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
24147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
242419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
243419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Returns all the routes on this link and all the links stacked above it.
244419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
245419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    public Collection<RouteInfo> getAllRoutes() {
246419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        Collection<RouteInfo> routes = new ArrayList();
247419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        routes.addAll(mRoutes);
248419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        for (LinkProperties stacked: mStackedLinks.values()) {
249419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            routes.addAll(stacked.getAllRoutes());
250419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
2516629bcd6608cccbd5997ac99bf4474c00def0431Robert Greenwalt        return routes;
252419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
253419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
25437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void setHttpProxy(ProxyProperties proxy) {
25547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        mHttpProxy = proxy;
25647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
25737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public ProxyProperties getHttpProxy() {
25847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        return mHttpProxy;
25947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
26047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
261419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
262419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Adds a stacked link.
263419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
264419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * If there is already a stacked link with the same interfacename as link,
265419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * that link is replaced with link. Otherwise, link is added to the list
266419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * of stacked links. If link is null, nothing changes.
267419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
268419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * @param link The link to add.
2694faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @return true if the link was stacked, false otherwise.
270419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
2714faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    public boolean addStackedLink(LinkProperties link) {
272419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        if (link != null && link.getInterfaceName() != null) {
273419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            mStackedLinks.put(link.getInterfaceName(), link);
2744faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            return true;
275419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
2764faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        return false;
277419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
278419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
279419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
280419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Removes a stacked link.
281419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
282419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * If there a stacked link with the same interfacename as link, it is
283419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * removed. Otherwise, nothing changes.
284419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
2854faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @param link The link to remove.
2864faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @return true if the link was removed, false otherwise.
287419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
2884faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    public boolean removeStackedLink(LinkProperties link) {
289419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        if (link != null && link.getInterfaceName() != null) {
2904faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            LinkProperties removed = mStackedLinks.remove(link.getInterfaceName());
2914faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            return removed != null;
292419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
2934faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        return false;
294419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
295419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
296419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
297419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Returns all the links stacked on top of this link.
298419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
299419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    public Collection<LinkProperties> getStackedLinks() {
300419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        Collection<LinkProperties> stacked = new ArrayList<LinkProperties>();
301419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        for (LinkProperties link : mStackedLinks.values()) {
302419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti          stacked.add(new LinkProperties(link));
303419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
304419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        return Collections.unmodifiableCollection(stacked);
305419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
306419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
30737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void clear() {
308ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        mIfaceName = null;
309e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mLinkAddresses.clear();
310e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mDnses.clear();
3118058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        mDomains = null;
312e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mRoutes.clear();
31347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        mHttpProxy = null;
314419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        mStackedLinks.clear();
31547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
31647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
31747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    /**
31847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * Implement the Parcelable interface
31947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * @hide
32047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     */
32147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    public int describeContents() {
32247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        return 0;
32347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
32447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
3251f6408a96c757b3001c553f8f34ef0bda00a224dWink Saville    @Override
32637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public String toString() {
327ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " ");
32847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
329ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        String linkAddresses = "LinkAddresses: [";
3304e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString() + ",";
331ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        linkAddresses += "] ";
33247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
33347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        String dns = "DnsAddresses: [";
3341f6408a96c757b3001c553f8f34ef0bda00a224dWink Saville        for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
33547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        dns += "] ";
33647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
3378058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        String domainName = "Domains: " + mDomains;
3388058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt
3398058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        String routes = " Routes: [";
340aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        for (RouteInfo route : mRoutes) routes += route.toString() + ",";
341aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        routes += "] ";
34247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " ");
34347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
344419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        String stacked = "";
345419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        if (mStackedLinks.values().size() > 0) {
346419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            stacked += " Stacked: [";
347419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            for (LinkProperties link: mStackedLinks.values()) {
348419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                stacked += " [" + link.toString() + " ],";
349419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            }
350419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            stacked += "] ";
351419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
35215bc62fe205b755582845829821373985efc60afWink Saville        return "{" + ifaceName + linkAddresses + routes + dns + domainName + proxy + stacked + "}";
353419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
354419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
355419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
356419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Returns true if this link has an IPv4 address.
357419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
358419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
359419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
360419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    public boolean hasIPv4Address() {
361419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        for (LinkAddress address : mLinkAddresses) {
362419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti          if (address.getAddress() instanceof Inet4Address) {
363419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            return true;
364419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti          }
365419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
366419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        return false;
36747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
36847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
369e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
3704faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * Returns true if this link has an IPv6 address.
3714faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     *
3724faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @return {@code true} if there is an IPv6 address, {@code false} otherwise.
3734faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     */
3744faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    public boolean hasIPv6Address() {
3754faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        for (LinkAddress address : mLinkAddresses) {
3764faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti          if (address.getAddress() instanceof Inet6Address) {
3774faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            return true;
3784faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti          }
3794faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        }
3804faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        return false;
3814faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    }
3824faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti
3834faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    /**
384e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} interface name against the target
385e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
386e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
387e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
388e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
389e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalInterfaceName(LinkProperties target) {
390e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
391e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
392e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
393e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
3944717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt     * Compares this {@code LinkProperties} interface addresses against the target
395e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
396e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
397e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
398e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
399e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalAddresses(LinkProperties target) {
400e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<InetAddress> targetAddresses = target.getAddresses();
401e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<InetAddress> sourceAddresses = getAddresses();
402e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return (sourceAddresses.size() == targetAddresses.size()) ?
403e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    sourceAddresses.containsAll(targetAddresses) : false;
404e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
405e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
406e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
407e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} DNS addresses against the target
408e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
409e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
410e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
411e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
412e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalDnses(LinkProperties target) {
413e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<InetAddress> targetDnses = target.getDnses();
4148058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        String targetDomains = target.getDomains();
4158058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        if (mDomains == null) {
4168058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt            if (targetDomains != null) return false;
4178058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        } else {
4188058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt            if (mDomains.equals(targetDomains) == false) return false;
4198058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        }
420e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return (mDnses.size() == targetDnses.size()) ?
421e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    mDnses.containsAll(targetDnses) : false;
422e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
423e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
424e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
425e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} Routes against the target
426e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
427e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
428e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
429e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
430e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalRoutes(LinkProperties target) {
431e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<RouteInfo> targetRoutes = target.getRoutes();
432e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return (mRoutes.size() == targetRoutes.size()) ?
433e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    mRoutes.containsAll(targetRoutes) : false;
434e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
435e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
436e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
437e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} HttpProxy against the target
438e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
439e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
440e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
441e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
442e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalHttpProxy(LinkProperties target) {
443e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return getHttpProxy() == null ? target.getHttpProxy() == null :
444e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    getHttpProxy().equals(target.getHttpProxy());
445e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
4464e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
447419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
448419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Compares this {@code LinkProperties} stacked links against the target
449419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
450419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * @param target LinkProperties to compare.
451419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * @return {@code true} if both are identical, {@code false} otherwise.
452419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
453419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    public boolean isIdenticalStackedLinks(LinkProperties target) {
454213f98b6fe81c73f0d182fb5af312d4ce4a08041Lorenzo Colitti        if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) {
455419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            return false;
456419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
457419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        for (LinkProperties stacked : mStackedLinks.values()) {
458419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            // Hashtable values can never be null.
459419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            String iface = stacked.getInterfaceName();
460419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            if (!stacked.equals(target.mStackedLinks.get(iface))) {
461419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                return false;
462419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            }
463419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
464419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        return true;
465419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
466419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
4674e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    @Override
4684e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    /**
4694e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * Compares this {@code LinkProperties} instance against the target
4704e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
4714e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * all their fields are equal in values.
4724e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     *
4734e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * For collection fields, such as mDnses, containsAll() is used to check
4744e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * if two collections contains the same elements, independent of order.
4754e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * There are two thoughts regarding containsAll()
4764e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
4774e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * 2. Worst case performance is O(n^2).
4784e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     *
479419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * This method does not check that stacked interfaces are equal, because
480419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * stacked interfaces are not so much a property of the link as a
481419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * description of connections between links.
482419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
4834e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * @param obj the object to be tested for equality.
4844e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * @return {@code true} if both objects are equal, {@code false} otherwise.
4854e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     */
4864e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    public boolean equals(Object obj) {
4874e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        if (this == obj) return true;
4884e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
4894e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        if (!(obj instanceof LinkProperties)) return false;
4904e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
4914e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        LinkProperties target = (LinkProperties) obj;
4924e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
493e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return isIdenticalInterfaceName(target) &&
494e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalAddresses(target) &&
495e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalDnses(target) &&
496e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalRoutes(target) &&
497419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                isIdenticalHttpProxy(target) &&
498419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                isIdenticalStackedLinks(target);
499e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
5004e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
501e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
502d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Compares the addresses in this LinkProperties with another
503d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * LinkProperties, examining only addresses on the base link.
504e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
505d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @param target a LinkProperties with the new list of addresses
506d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @return the differences between the addresses.
507e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
5080a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
509e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        /*
510e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * Duplicate the LinkAddresses into removed, we will be removing
511e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * address which are common between mLinkAddresses and target
512e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * leaving the addresses that are different. And address which
513e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * are in target but not in mLinkAddresses are placed in the
514e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * addedAddresses.
515e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         */
5160a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        CompareResult<LinkAddress> result = new CompareResult<LinkAddress>();
517e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
518e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        result.added.clear();
5190a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (target != null) {
5200a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (LinkAddress newAddress : target.getLinkAddresses()) {
5210a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (! result.removed.remove(newAddress)) {
5220a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    result.added.add(newAddress);
5230a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
524e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            }
525e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        }
526e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return result;
5274e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    }
5284e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
5290a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    /**
530d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Compares the DNS addresses in this LinkProperties with another
531d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * LinkProperties, examining only DNS addresses on the base link.
5320a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     *
533d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @param target a LinkProperties with the new list of dns addresses
534d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @return the differences between the DNS addresses.
5350a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     */
5360a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public CompareResult<InetAddress> compareDnses(LinkProperties target) {
5370a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        /*
5380a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * Duplicate the InetAddresses into removed, we will be removing
5390a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * dns address which are common between mDnses and target
5400a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * leaving the addresses that are different. And dns address which
5410a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * are in target but not in mDnses are placed in the
5420a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * addedAddresses.
5430a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         */
5440a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        CompareResult<InetAddress> result = new CompareResult<InetAddress>();
5450a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
5460a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.removed = new ArrayList<InetAddress>(mDnses);
5470a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.added.clear();
5480a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (target != null) {
5490a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (InetAddress newAddress : target.getDnses()) {
5500a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (! result.removed.remove(newAddress)) {
5510a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    result.added.add(newAddress);
5520a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
5530a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
5540a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        }
5550a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return result;
5560a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
5570a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
5580a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    /**
559d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Compares all routes in this LinkProperties with another LinkProperties,
560d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * examining both the the base link and all stacked links.
5610a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     *
562d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @param target a LinkProperties with the new list of routes
563d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @return the differences between the routes.
5640a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     */
565d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    public CompareResult<RouteInfo> compareAllRoutes(LinkProperties target) {
5660a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        /*
5670a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * Duplicate the RouteInfos into removed, we will be removing
5681994bc14ab9fd3a3c5dca8851cfc0042bcb25d46Lorenzo Colitti         * routes which are common between mRoutes and target
5690a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * leaving the routes that are different. And route address which
5700a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * are in target but not in mRoutes are placed in added.
5710a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         */
5720a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        CompareResult<RouteInfo> result = new CompareResult<RouteInfo>();
5730a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
574419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        result.removed = getAllRoutes();
5750a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.added.clear();
5760a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (target != null) {
577419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            for (RouteInfo r : target.getAllRoutes()) {
5780a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (! result.removed.remove(r)) {
5790a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    result.added.add(r);
5800a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
5810a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
5820a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        }
5830a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return result;
5840a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
5850a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
5860a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
5874e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    @Override
5884e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    /**
5894e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * generate hashcode based on significant fields
5904e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * Equal objects must produce the same hash code, while unequal objects
5914e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * may have the same hash codes.
5924e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     */
5934e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    public int hashCode() {
5944e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
5954e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang                + mLinkAddresses.size() * 31
5964e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang                + mDnses.size() * 37
5978058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt                + ((null == mDomains) ? 0 : mDomains.hashCode())
598aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                + mRoutes.size() * 41
599419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())
600419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                + mStackedLinks.hashCode() * 47);
6014e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    }
6024e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
60347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    /**
60447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * Implement the Parcelable interface.
60547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     */
60637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void writeToParcel(Parcel dest, int flags) {
60747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        dest.writeString(getInterfaceName());
608ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        dest.writeInt(mLinkAddresses.size());
609ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        for(LinkAddress linkAddress : mLinkAddresses) {
610ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            dest.writeParcelable(linkAddress, flags);
61147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
612ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
61347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        dest.writeInt(mDnses.size());
61447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        for(InetAddress d : mDnses) {
61547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeByteArray(d.getAddress());
61647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
6178058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        dest.writeString(mDomains);
618992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt
619aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        dest.writeInt(mRoutes.size());
620aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        for(RouteInfo route : mRoutes) {
621aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeParcelable(route, flags);
62247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
623992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt
62447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        if (mHttpProxy != null) {
62547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeByte((byte)1);
62647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeParcelable(mHttpProxy, flags);
62747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        } else {
62847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeByte((byte)0);
62947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
630419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        ArrayList<LinkProperties> stackedLinks = new ArrayList(mStackedLinks.values());
631419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        dest.writeList(stackedLinks);
63247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
63347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
63447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    /**
63547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * Implement the Parcelable interface.
63647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     */
63737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public static final Creator<LinkProperties> CREATOR =
63837e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        new Creator<LinkProperties>() {
63937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt            public LinkProperties createFromParcel(Parcel in) {
64037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                LinkProperties netProp = new LinkProperties();
6414717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt
64247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                String iface = in.readString();
64347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                if (iface != null) {
6444717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt                    netProp.setInterfaceName(iface);
64547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
64647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                int addressCount = in.readInt();
64747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                for (int i=0; i<addressCount; i++) {
648ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff                    netProp.addLinkAddress((LinkAddress)in.readParcelable(null));
64947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
65047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                addressCount = in.readInt();
65147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                for (int i=0; i<addressCount; i++) {
65247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    try {
6531cf56ab9c68334d9124c52bcede06aaa0b17c730Irfan Sheriff                        netProp.addDns(InetAddress.getByAddress(in.createByteArray()));
65447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    } catch (UnknownHostException e) { }
65547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
6568058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt                netProp.setDomains(in.readString());
657992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                addressCount = in.readInt();
658992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                for (int i=0; i<addressCount; i++) {
659aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                    netProp.addRoute((RouteInfo)in.readParcelable(null));
66047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
66147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                if (in.readByte() == 1) {
66247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    netProp.setHttpProxy((ProxyProperties)in.readParcelable(null));
66347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
664419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
665419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                in.readList(stackedLinks, LinkProperties.class.getClassLoader());
666419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                for (LinkProperties stackedLink: stackedLinks) {
667419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                    netProp.addStackedLink(stackedLink);
668419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                }
66947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                return netProp;
67047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            }
67147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
67237e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt            public LinkProperties[] newArray(int size) {
67337e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                return new LinkProperties[size];
67447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            }
67547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        };
67647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt}
677