LinkProperties.java revision 76ea6c68d3222441970ef98079ba30710ac8c595
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
19207900c23b26d0df9ab28c709db4a1007d7d7904Jason Monkimport android.net.ProxyInfo;
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;
33df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwaltimport java.util.List;
34c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colittiimport java.util.Objects;
3547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
3647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt/**
3737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt * Describes the properties of a network link.
38992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt *
39992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * A link represents a connection to a network.
40992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt * It may have multiple addresses and multiple gateways,
414f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt * multiple dns servers but only one http proxy and one
424f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt * network interface.
43992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt *
444f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt * Note that this is just a holder of data.  Modifying it
454f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt * does not affect live networks.
46992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt *
4747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt */
48e595b97ff470a5e92151350e4d7b4173032fde23Robert Greenwaltpublic final class LinkProperties implements Parcelable {
49419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    // The interface described by the network link.
504717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt    private String mIfaceName;
5164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti    private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
5264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti    private ArrayList<InetAddress> mDnses = new ArrayList<InetAddress>();
538058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt    private String mDomains;
5464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti    private ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
55207900c23b26d0df9ab28c709db4a1007d7d7904Jason Monk    private ProxyInfo mHttpProxy;
569d9b74a900696191048aa97cc3c854072640428bsy.yun    private int mMtu;
5747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
58419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    // Stores the properties of links that are "stacked" above this link.
59419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    // Indexed by interface name to allow modification and to prevent duplicates being added.
60419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    private Hashtable<String, LinkProperties> mStackedLinks =
61419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        new Hashtable<String, LinkProperties>();
62419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
63df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    /**
64df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
65df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     */
660a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public static class CompareResult<T> {
67df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        public List<T> removed = new ArrayList<T>();
68df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        public List<T> added = new ArrayList<T>();
69e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
70e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        @Override
71e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        public String toString() {
720a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            String retVal = "removed=[";
730a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (T addr : removed) retVal += addr.toString() + ",";
740a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            retVal += "] added=[";
750a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (T addr : added) retVal += addr.toString() + ",";
76e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            retVal += "]";
77e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            return retVal;
78e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        }
79e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
80e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
81cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
82cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @hide
83cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
8437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public LinkProperties() {
8547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
8647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
87cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran    /**
88cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * @hide
89cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     */
9037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public LinkProperties(LinkProperties source) {
91ef6c1431fa2039a4b8c604d651bb8f4dc0806581Irfan Sheriff        if (source != null) {
92ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            mIfaceName = source.getInterfaceName();
930d8acea9bb452d1fdbb3d811041f7bdb1b0ef8a3Robert Greenwalt            for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
94df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt            for (InetAddress i : source.getDnsServers()) mDnses.add(i);
958058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt            mDomains = source.getDomains();
960d8acea9bb452d1fdbb3d811041f7bdb1b0ef8a3Robert Greenwalt            for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
97be2b058ec1e11e1d33b6d03230c21e5d2d7ac40cWink Saville            mHttpProxy = (source.getHttpProxy() == null)  ?
98207900c23b26d0df9ab28c709db4a1007d7d7904Jason Monk                    null : new ProxyInfo(source.getHttpProxy());
99419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            for (LinkProperties l: source.mStackedLinks.values()) {
100419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                addStackedLink(l);
101419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            }
1029d9b74a900696191048aa97cc3c854072640428bsy.yun            setMtu(source.getMtu());
103ef6c1431fa2039a4b8c604d651bb8f4dc0806581Irfan Sheriff        }
10437e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    }
10537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt
1064f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
1074f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Sets the interface name for this link.  All {@link RouteInfo} already set for this
1084f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * will have their interface changed to match this new value.
1094f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
1104f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @param iface The name of the network interface used for this link.
111df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
1124f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
113ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    public void setInterfaceName(String iface) {
114ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        mIfaceName = iface;
11545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        ArrayList<RouteInfo> newRoutes = new ArrayList<RouteInfo>(mRoutes.size());
11645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        for (RouteInfo route : mRoutes) {
11745b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            newRoutes.add(routeWithInterface(route));
11845b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        }
11945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        mRoutes = newRoutes;
12047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
121ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
1224f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
1234f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Gets the interface name for this link.  May be {@code null} if not set.
1244f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
1254f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @return The interface name set for this link or {@code null}.
1264f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
12737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public String getInterfaceName() {
128ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        return mIfaceName;
12947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
13047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
131df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    /**
132df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
133df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     */
134df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public List<String> getAllInterfaceNames() {
135df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
13655187f18505aad67f824094061af1b6d0a0ebb38Robert Greenwalt        if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
1374aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti        for (LinkProperties stacked: mStackedLinks.values()) {
1384aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti            interfaceNames.addAll(stacked.getAllInterfaceNames());
1394aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti        }
1404aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti        return interfaceNames;
1414aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti    }
1424aa9bcf414282e4bdd10900832baaeaa349bda50Lorenzo Colitti
143d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    /**
1444f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Returns all the addresses on this link.  We often think of a link having a single address,
1454f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * however, particularly with Ipv6 several addresses are typical.  Note that the
1464f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * {@code LinkProperties} actually contains {@link LinkAddress} objects which also include
1474f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * prefix lengths for each address.  This is a simplified utility alternative to
1484f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * {@link LinkProperties#getLinkAddresses}.
1494f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
150df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @return An umodifiable {@link List} of {@link InetAddress} for this link.
1514f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
152d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     */
153df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public List<InetAddress> getAddresses() {
154df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        List<InetAddress> addresses = new ArrayList<InetAddress>();
155ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        for (LinkAddress linkAddress : mLinkAddresses) {
156ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            addresses.add(linkAddress.getAddress());
157ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        }
158df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        return Collections.unmodifiableList(addresses);
159ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    }
160ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
161d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    /**
162d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Returns all the addresses on this link and all the links stacked above it.
1634f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
164d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     */
165df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public List<InetAddress> getAllAddresses() {
166df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        List<InetAddress> addresses = new ArrayList<InetAddress>();
167d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        for (LinkAddress linkAddress : mLinkAddresses) {
168d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti            addresses.add(linkAddress.getAddress());
169d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        }
170d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        for (LinkProperties stacked: mStackedLinks.values()) {
171d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti            addresses.addAll(stacked.getAllAddresses());
172d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        }
173d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        return addresses;
174d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    }
175d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti
17664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti    private int findLinkAddressIndex(LinkAddress address) {
17764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        for (int i = 0; i < mLinkAddresses.size(); i++) {
17864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            if (mLinkAddresses.get(i).isSameAddressAs(address)) {
17964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti                return i;
18064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            }
18164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        }
18264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        return -1;
18364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti    }
18464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti
1854faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    /**
1864f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Adds a {@link LinkAddress} to this {@code LinkProperties} if a {@link LinkAddress} of the
1874f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * same address/prefix does not already exist.  If it does exist it is replaced.
1884faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @param address The {@code LinkAddress} to add.
18964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti     * @return true if {@code address} was added or updated, false otherwise.
190df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
1914faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     */
1924faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    public boolean addLinkAddress(LinkAddress address) {
19364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        if (address == null) {
19464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            return false;
19564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        }
19664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        int i = findLinkAddressIndex(address);
19764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        if (i < 0) {
19864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            // Address was not present. Add it.
1994faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            mLinkAddresses.add(address);
2004faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            return true;
20164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        } else if (mLinkAddresses.get(i).equals(address)) {
20264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            // Address was present and has same properties. Do nothing.
20364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            return false;
20464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        } else {
20564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            // Address was present and has different properties. Update it.
20664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            mLinkAddresses.set(i, address);
20764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            return true;
2084faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        }
2094faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    }
2104faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti
2114faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    /**
2124f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Removes a {@link LinkAddress} from this {@code LinkProperties}.  Specifically, matches
2134f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * and {@link LinkAddress} with the same address and prefix.
2144f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
2154f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @param toRemove A {@link LinkAddress} specifying the address to remove.
2164faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @return true if the address was removed, false if it did not exist.
217df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
2184faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     */
2194faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    public boolean removeLinkAddress(LinkAddress toRemove) {
22064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        int i = findLinkAddressIndex(toRemove);
22164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        if (i >= 0) {
22264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            mLinkAddresses.remove(i);
22364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti            return true;
22464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        }
22564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        return false;
226ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff    }
227ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
228d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    /**
2294f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Returns all the {@link LinkAddress} on this link.  Typically a link will have
2304f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * one IPv4 address and one or more IPv6 addresses.
2314f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
232df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
233d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     */
234df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public List<LinkAddress> getLinkAddresses() {
235df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        return Collections.unmodifiableList(mLinkAddresses);
23647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
23747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
238d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    /**
239d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Returns all the addresses on this link and all the links stacked above it.
2404f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
241d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     */
242df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public List<LinkAddress> getAllLinkAddresses() {
243df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        List<LinkAddress> addresses = new ArrayList<LinkAddress>();
244d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        addresses.addAll(mLinkAddresses);
245d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        for (LinkProperties stacked: mStackedLinks.values()) {
246d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti            addresses.addAll(stacked.getAllLinkAddresses());
247d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        }
248d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti        return addresses;
249d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    }
250d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti
25122f407b11e11cfdb336e06e8c0d4a7ef1eafc783Lorenzo Colitti    /**
2524f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Replaces the {@link LinkAddress} in this {@code LinkProperties} with
2534f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * the given {@link Collection} of {@link LinkAddress}.
2544f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
2554f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @param addresses The {@link Collection} of {@link LinkAddress} to set in this
2564f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *                  object.
257df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
25822f407b11e11cfdb336e06e8c0d4a7ef1eafc783Lorenzo Colitti     */
25922f407b11e11cfdb336e06e8c0d4a7ef1eafc783Lorenzo Colitti    public void setLinkAddresses(Collection<LinkAddress> addresses) {
26022f407b11e11cfdb336e06e8c0d4a7ef1eafc783Lorenzo Colitti        mLinkAddresses.clear();
26122f407b11e11cfdb336e06e8c0d4a7ef1eafc783Lorenzo Colitti        for (LinkAddress address: addresses) {
26222f407b11e11cfdb336e06e8c0d4a7ef1eafc783Lorenzo Colitti            addLinkAddress(address);
26322f407b11e11cfdb336e06e8c0d4a7ef1eafc783Lorenzo Colitti        }
26422f407b11e11cfdb336e06e8c0d4a7ef1eafc783Lorenzo Colitti    }
26522f407b11e11cfdb336e06e8c0d4a7ef1eafc783Lorenzo Colitti
2664f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
2674f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Adds the given {@link InetAddress} to the list of DNS servers.
2684f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
269df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
270df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
2714f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
272df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public void addDnsServer(InetAddress dnsServer) {
273df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        if (dnsServer != null) mDnses.add(dnsServer);
27447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
275ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
2764f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
277cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran     * Returns all the {@link InetAddress} for DNS servers on this link.
2784f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
279df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on
2804f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *         this link.
2814f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
282df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public List<InetAddress> getDnsServers() {
283df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        return Collections.unmodifiableList(mDnses);
28447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
28547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
2864f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
2874f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Sets the DNS domain search path used on this link.
2884f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
2894f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @param domains A {@link String} listing in priority order the comma separated
2904f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *                domains to search when resolving host names on this link.
291df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
2924f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
2938058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt    public void setDomains(String domains) {
2948058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        mDomains = domains;
2958058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt    }
2968058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt
2974f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
2984f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Get the DNS domains search path set for this link.
2994f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
3004f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @return A {@link String} containing the comma separated domains to search when resolving
3014f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *         host names on this link.
3024f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
3034f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    public String getDomains() {
3044f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt        return mDomains;
3054f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    }
3064f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt
3074f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
3084f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Sets the Maximum Transmission Unit size to use on this link.  This should not be used
3094f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * unless the system default (1500) is incorrect.  Values less than 68 or greater than
3104f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * 10000 will be ignored.
3114f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
3124f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @param mtu The MTU to use for this link.
3134f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
3144f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
3159d9b74a900696191048aa97cc3c854072640428bsy.yun    public void setMtu(int mtu) {
3169d9b74a900696191048aa97cc3c854072640428bsy.yun        mMtu = mtu;
3179d9b74a900696191048aa97cc3c854072640428bsy.yun    }
3189d9b74a900696191048aa97cc3c854072640428bsy.yun
3194f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
3204f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Gets any non-default MTU size set for this link.  Note that if the default is being used
3214f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * this will return 0.
3224f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
3234f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @return The mtu value set for this link.
3244f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
3254f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
3269d9b74a900696191048aa97cc3c854072640428bsy.yun    public int getMtu() {
3279d9b74a900696191048aa97cc3c854072640428bsy.yun        return mMtu;
3289d9b74a900696191048aa97cc3c854072640428bsy.yun    }
3299d9b74a900696191048aa97cc3c854072640428bsy.yun
33045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    private RouteInfo routeWithInterface(RouteInfo route) {
33145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        return new RouteInfo(
33245b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            route.getDestination(),
33345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            route.getGateway(),
33445b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            mIfaceName);
33545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti    }
33645b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
3374f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
338c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * Adds a {@link RouteInfo} to this {@code LinkProperties}, if not present. If the
339c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * {@link RouteInfo} had an interface name set and that differs from the interface set for this
340c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown.  The proper
341c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * course is to add either un-named or properly named {@link RouteInfo}.
3424f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
3434f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @param route A {@link RouteInfo} to add to this object.
344c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * @return {@code false} if the route was already present, {@code true} if it was added.
345c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     *
346df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
3474f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
348c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti    public boolean addRoute(RouteInfo route) {
34945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        if (route != null) {
35045b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            String routeIface = route.getInterface();
35145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            if (routeIface != null && !routeIface.equals(mIfaceName)) {
3521994bc14ab9fd3a3c5dca8851cfc0042bcb25d46Lorenzo Colitti                throw new IllegalArgumentException(
35345b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti                   "Route added with non-matching interface: " + routeIface +
3541994bc14ab9fd3a3c5dca8851cfc0042bcb25d46Lorenzo Colitti                   " vs. " + mIfaceName);
35545b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti            }
356c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti            route = routeWithInterface(route);
357c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti            if (!mRoutes.contains(route)) {
358c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti                mRoutes.add(route);
359c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti                return true;
360c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti            }
36145b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti        }
362c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti        return false;
363c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti    }
364c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti
365c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti    /**
366c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * Removes a {@link RouteInfo} from this {@code LinkProperties}, if present. The route must
367c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * specify an interface and the interface must match the interface of this
368c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * {@code LinkProperties}, or it will not be removed.
369c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     *
370c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * @return {@code true} if the route was removed, {@code false} if it was not present.
371c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     *
372c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     * @hide
373c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti     */
374c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti    public boolean removeRoute(RouteInfo route) {
375c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti        return route != null &&
376c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti                Objects.equals(mIfaceName, route.getInterface()) &&
377c17a1b9ee4e2e72d640b97ef174d9a78a8ef9a8aLorenzo Colitti                mRoutes.remove(route);
37847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
37945b9a5bb93569ca49bbd44f7a518091371687f96Lorenzo Colitti
380419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
3814f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Returns all the {@link RouteInfo} set on this link.
3824f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
383df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
384419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
385df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public List<RouteInfo> getRoutes() {
386df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        return Collections.unmodifiableList(mRoutes);
38747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
38847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
389419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
390419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Returns all the routes on this link and all the links stacked above it.
3914f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
392419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
393df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public List<RouteInfo> getAllRoutes() {
394df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        List<RouteInfo> routes = new ArrayList();
395419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        routes.addAll(mRoutes);
396419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        for (LinkProperties stacked: mStackedLinks.values()) {
397419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            routes.addAll(stacked.getAllRoutes());
398419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
3996629bcd6608cccbd5997ac99bf4474c00def0431Robert Greenwalt        return routes;
400419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
401419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
4024f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
4034f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Sets the recommended {@link ProxyInfo} to use on this link, or {@code null} for none.
4044f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Note that Http Proxies are only a hint - the system recommends their use, but it does
4054f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * not enforce it and applications may ignore them.
4064f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
4074f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
408df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
4094f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
410207900c23b26d0df9ab28c709db4a1007d7d7904Jason Monk    public void setHttpProxy(ProxyInfo proxy) {
41147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        mHttpProxy = proxy;
41247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
4134f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt
4144f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
4154f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Gets the recommended {@link ProxyInfo} (or {@code null}) set on this link.
4164f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     *
4174f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @return The {@link ProxyInfo} set on this link
4184f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
419207900c23b26d0df9ab28c709db4a1007d7d7904Jason Monk    public ProxyInfo getHttpProxy() {
42047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        return mHttpProxy;
42147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
42247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
423419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
424419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Adds a stacked link.
425419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
426419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * If there is already a stacked link with the same interfacename as link,
427419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * that link is replaced with link. Otherwise, link is added to the list
428419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * of stacked links. If link is null, nothing changes.
429419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
430419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * @param link The link to add.
4314faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @return true if the link was stacked, false otherwise.
4324f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
433419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
4344faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    public boolean addStackedLink(LinkProperties link) {
435419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        if (link != null && link.getInterfaceName() != null) {
436419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            mStackedLinks.put(link.getInterfaceName(), link);
4374faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            return true;
438419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
4394faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        return false;
440419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
441419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
442419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
443419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Removes a stacked link.
444419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
445419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * If there a stacked link with the same interfacename as link, it is
446419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * removed. Otherwise, nothing changes.
447419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
4484faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @param link The link to remove.
4494faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     * @return true if the link was removed, false otherwise.
4504f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
451419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
4524faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    public boolean removeStackedLink(LinkProperties link) {
453419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        if (link != null && link.getInterfaceName() != null) {
4544faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            LinkProperties removed = mStackedLinks.remove(link.getInterfaceName());
4554faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            return removed != null;
456419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
4574faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        return false;
458419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
459419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
460419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
461419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Returns all the links stacked on top of this link.
4624f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
463419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
464df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt    public List<LinkProperties> getStackedLinks() {
465df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        List<LinkProperties> stacked = new ArrayList<LinkProperties>();
466419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        for (LinkProperties link : mStackedLinks.values()) {
467419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti          stacked.add(new LinkProperties(link));
468419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
469df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        return Collections.unmodifiableList(stacked);
470419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
471419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
4724f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt    /**
4734f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * Clears this object to its initial state.
474df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
4754f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     */
47637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void clear() {
477ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        mIfaceName = null;
478e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mLinkAddresses.clear();
479e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mDnses.clear();
4808058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        mDomains = null;
481e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mRoutes.clear();
48247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        mHttpProxy = null;
483419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        mStackedLinks.clear();
4849d9b74a900696191048aa97cc3c854072640428bsy.yun        mMtu = 0;
48547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
48647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
48747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    /**
48847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * Implement the Parcelable interface
48947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     */
49047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    public int describeContents() {
49147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        return 0;
49247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
49347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
4941f6408a96c757b3001c553f8f34ef0bda00a224dWink Saville    @Override
49537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public String toString() {
496ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " ");
49747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
498ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        String linkAddresses = "LinkAddresses: [";
4994e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString() + ",";
500ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        linkAddresses += "] ";
50147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
50247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        String dns = "DnsAddresses: [";
5031f6408a96c757b3001c553f8f34ef0bda00a224dWink Saville        for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
50447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        dns += "] ";
50547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
5068058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        String domainName = "Domains: " + mDomains;
5078058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt
508cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        String mtu = " MTU: " + mMtu;
5099d9b74a900696191048aa97cc3c854072640428bsy.yun
5108058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        String routes = " Routes: [";
511aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        for (RouteInfo route : mRoutes) routes += route.toString() + ",";
512aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        routes += "] ";
513cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        String proxy = (mHttpProxy == null ? "" : " HttpProxy: " + mHttpProxy.toString() + " ");
51447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
515419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        String stacked = "";
516419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        if (mStackedLinks.values().size() > 0) {
517419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            stacked += " Stacked: [";
518419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            for (LinkProperties link: mStackedLinks.values()) {
519419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                stacked += " [" + link.toString() + " ],";
520419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            }
521419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            stacked += "] ";
522419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
5239d9b74a900696191048aa97cc3c854072640428bsy.yun        return "{" + ifaceName + linkAddresses + routes + dns + domainName + mtu
5249d9b74a900696191048aa97cc3c854072640428bsy.yun            + proxy + stacked + "}";
525419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
526419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
527419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
528419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Returns true if this link has an IPv4 address.
529419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
530419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
531df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
532419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
533419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    public boolean hasIPv4Address() {
534419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        for (LinkAddress address : mLinkAddresses) {
535419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti          if (address.getAddress() instanceof Inet4Address) {
536419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            return true;
537419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti          }
538419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
539419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        return false;
54047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
54147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
542e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
54376ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * Returns true if this link has a global preferred IPv6 address.
5444faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     *
54576ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise.
546df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt     * @hide
5474faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti     */
54876ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    public boolean hasGlobalIPv6Address() {
5494faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        for (LinkAddress address : mLinkAddresses) {
55076ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti          if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) {
5514faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti            return true;
5524faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti          }
5534faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        }
5544faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti        return false;
5554faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    }
5564faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti
5574faa027df03c241c92a12a437f20767ab4d6ee64Lorenzo Colitti    /**
55876ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * Returns true if this link has an IPv4 default route.
55976ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     *
56076ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @return {@code true} if there is an IPv4 default route, {@code false} otherwise.
56176ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @hide
56276ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     */
56376ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    public boolean hasIPv4DefaultRoute() {
56476ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        for (RouteInfo r : mRoutes) {
56576ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti          if (r.isIPv4Default()) {
56676ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti            return true;
56776ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti          }
56876ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        }
56976ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        return false;
57076ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    }
57176ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti
57276ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    /**
57376ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * Returns true if this link has an IPv6 default route.
57476ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     *
57576ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @return {@code true} if there is an IPv6 default route, {@code false} otherwise.
57676ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @hide
57776ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     */
57876ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    public boolean hasIPv6DefaultRoute() {
57976ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        for (RouteInfo r : mRoutes) {
58076ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti          if (r.isIPv6Default()) {
58176ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti            return true;
58276ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti          }
58376ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        }
58476ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        return false;
58576ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    }
58676ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti
58776ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    /**
58876ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * Returns true if this link has an IPv4 DNS server.
58976ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     *
59076ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise.
59176ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @hide
59276ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     */
59376ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    public boolean hasIPv4DnsServer() {
59476ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        for (InetAddress ia : mDnses) {
59576ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti          if (ia instanceof Inet4Address) {
59676ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti            return true;
59776ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti          }
59876ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        }
59976ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        return false;
60076ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    }
60176ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti
60276ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    /**
60376ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * Returns true if this link has an IPv6 DNS server.
60476ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     *
60576ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise.
60676ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @hide
60776ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     */
60876ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    public boolean hasIPv6DnsServer() {
60976ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        for (InetAddress ia : mDnses) {
61076ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti          if (ia instanceof Inet6Address) {
61176ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti            return true;
61276ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti          }
61376ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        }
61476ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        return false;
61576ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    }
61676ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti
61776ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    /**
61876ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * Returns true if this link is provisioned for global connectivity. For IPv6, this requires an
61976ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * IP address, default route, and DNS server. For IPv4, this requires only an IPv4 address,
62076ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * because WifiStateMachine accepts static configurations that only specify an address but not
62176ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * DNS servers or a default route.
62276ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     *
62376ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @return {@code true} if the link is provisioned, {@code false} otherwise.
62476ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     * @hide
62576ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti     */
62676ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    public boolean isProvisioned() {
62776ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti        return (hasIPv4Address() ||
62876ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti                (hasGlobalIPv6Address() && hasIPv6DefaultRoute() && hasIPv6DnsServer()));
62976ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    }
63076ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti
63176ea6c68d3222441970ef98079ba30710ac8c595Lorenzo Colitti    /**
632e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} interface name against the target
633e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
634e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
635e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
6364f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
637e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
638e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalInterfaceName(LinkProperties target) {
639e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
640e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
641e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
642e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
6434717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt     * Compares this {@code LinkProperties} interface addresses against the target
644e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
645e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
646e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
6474f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
648e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
649e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalAddresses(LinkProperties target) {
650e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<InetAddress> targetAddresses = target.getAddresses();
651e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<InetAddress> sourceAddresses = getAddresses();
652e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return (sourceAddresses.size() == targetAddresses.size()) ?
653e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    sourceAddresses.containsAll(targetAddresses) : false;
654e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
655e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
656e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
657e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} DNS addresses against the target
658e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
659e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
660e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
6614f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
662e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
663e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalDnses(LinkProperties target) {
664df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt        Collection<InetAddress> targetDnses = target.getDnsServers();
6658058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        String targetDomains = target.getDomains();
6668058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        if (mDomains == null) {
6678058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt            if (targetDomains != null) return false;
6688058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        } else {
6698058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt            if (mDomains.equals(targetDomains) == false) return false;
6708058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        }
671e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return (mDnses.size() == targetDnses.size()) ?
672e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    mDnses.containsAll(targetDnses) : false;
673e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
674e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
675e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
676e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} Routes against the target
677e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
678e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
679e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
6804f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
681e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
682e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalRoutes(LinkProperties target) {
683e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        Collection<RouteInfo> targetRoutes = target.getRoutes();
684e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return (mRoutes.size() == targetRoutes.size()) ?
685e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    mRoutes.containsAll(targetRoutes) : false;
686e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
687e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
688e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
689e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * Compares this {@code LinkProperties} HttpProxy against the target
690e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
691e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @param target LinkProperties to compare.
692e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * @return {@code true} if both are identical, {@code false} otherwise.
6934f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
694e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
695e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    public boolean isIdenticalHttpProxy(LinkProperties target) {
696e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return getHttpProxy() == null ? target.getHttpProxy() == null :
697e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    getHttpProxy().equals(target.getHttpProxy());
698e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
6994e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
700419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    /**
701419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * Compares this {@code LinkProperties} stacked links against the target
702419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     *
703419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * @param target LinkProperties to compare.
704419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     * @return {@code true} if both are identical, {@code false} otherwise.
7054f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
706419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti     */
707419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    public boolean isIdenticalStackedLinks(LinkProperties target) {
708213f98b6fe81c73f0d182fb5af312d4ce4a08041Lorenzo Colitti        if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) {
709419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            return false;
710419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
711419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        for (LinkProperties stacked : mStackedLinks.values()) {
712419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            // Hashtable values can never be null.
713419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            String iface = stacked.getInterfaceName();
714419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            if (!stacked.equals(target.mStackedLinks.get(iface))) {
715419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                return false;
716419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            }
717419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        }
718419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        return true;
719419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti    }
720419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti
7219d9b74a900696191048aa97cc3c854072640428bsy.yun    /**
7229d9b74a900696191048aa97cc3c854072640428bsy.yun     * Compares this {@code LinkProperties} MTU against the target
7239d9b74a900696191048aa97cc3c854072640428bsy.yun     *
724d57de6afb8981dc1663d41a842ab7cdae93427a1Ying Wang     * @param target LinkProperties to compare.
7259d9b74a900696191048aa97cc3c854072640428bsy.yun     * @return {@code true} if both are identical, {@code false} otherwise.
7264f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
7279d9b74a900696191048aa97cc3c854072640428bsy.yun     */
7289d9b74a900696191048aa97cc3c854072640428bsy.yun    public boolean isIdenticalMtu(LinkProperties target) {
7299d9b74a900696191048aa97cc3c854072640428bsy.yun        return getMtu() == target.getMtu();
7309d9b74a900696191048aa97cc3c854072640428bsy.yun    }
7319d9b74a900696191048aa97cc3c854072640428bsy.yun
7324e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    @Override
7334e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    /**
7344e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * Compares this {@code LinkProperties} instance against the target
7354e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
7364e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * all their fields are equal in values.
7374e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     *
7384e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * For collection fields, such as mDnses, containsAll() is used to check
7394e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * if two collections contains the same elements, independent of order.
7404e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * There are two thoughts regarding containsAll()
7414e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
7424e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * 2. Worst case performance is O(n^2).
7434e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     *
7444e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * @param obj the object to be tested for equality.
7454e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * @return {@code true} if both objects are equal, {@code false} otherwise.
7464e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     */
7474e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    public boolean equals(Object obj) {
7484e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        if (this == obj) return true;
7494e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
7504e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        if (!(obj instanceof LinkProperties)) return false;
7514e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
7524e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        LinkProperties target = (LinkProperties) obj;
7534f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt        /**
7544f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt         * This method does not check that stacked interfaces are equal, because
7554f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt         * stacked interfaces are not so much a property of the link as a
7564f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt         * description of connections between links.
7574f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt         */
758e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return isIdenticalInterfaceName(target) &&
759e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalAddresses(target) &&
760e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalDnses(target) &&
761e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                isIdenticalRoutes(target) &&
762419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                isIdenticalHttpProxy(target) &&
7639d9b74a900696191048aa97cc3c854072640428bsy.yun                isIdenticalStackedLinks(target) &&
7649d9b74a900696191048aa97cc3c854072640428bsy.yun                isIdenticalMtu(target);
765e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    }
7664e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
767e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
768d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Compares the addresses in this LinkProperties with another
769d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * LinkProperties, examining only addresses on the base link.
770e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     *
771d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @param target a LinkProperties with the new list of addresses
772d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @return the differences between the addresses.
7734f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
774e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
7750a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
776e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        /*
777e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * Duplicate the LinkAddresses into removed, we will be removing
778e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * address which are common between mLinkAddresses and target
779e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * leaving the addresses that are different. And address which
780e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * are in target but not in mLinkAddresses are placed in the
781e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         * addedAddresses.
782e822225f7a01ef088ff01f7613f953d5d89945edWink Saville         */
7830a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        CompareResult<LinkAddress> result = new CompareResult<LinkAddress>();
784e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
785e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        result.added.clear();
7860a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (target != null) {
7870a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            for (LinkAddress newAddress : target.getLinkAddresses()) {
7880a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (! result.removed.remove(newAddress)) {
7890a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    result.added.add(newAddress);
7900a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
791e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            }
792e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        }
793e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        return result;
7944e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    }
7954e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
7960a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    /**
797d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Compares the DNS addresses in this LinkProperties with another
798d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * LinkProperties, examining only DNS addresses on the base link.
7990a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     *
800d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @param target a LinkProperties with the new list of dns addresses
801d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @return the differences between the DNS addresses.
8024f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
8030a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     */
8040a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    public CompareResult<InetAddress> compareDnses(LinkProperties target) {
8050a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        /*
8060a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * Duplicate the InetAddresses into removed, we will be removing
8070a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * dns address which are common between mDnses and target
8080a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * leaving the addresses that are different. And dns address which
8090a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * are in target but not in mDnses are placed in the
8100a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * addedAddresses.
8110a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         */
8120a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        CompareResult<InetAddress> result = new CompareResult<InetAddress>();
8130a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
8140a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.removed = new ArrayList<InetAddress>(mDnses);
8150a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.added.clear();
8160a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (target != null) {
817df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt            for (InetAddress newAddress : target.getDnsServers()) {
8180a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (! result.removed.remove(newAddress)) {
8190a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    result.added.add(newAddress);
8200a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
8210a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
8220a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        }
8230a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return result;
8240a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
8250a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
8260a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    /**
827d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * Compares all routes in this LinkProperties with another LinkProperties,
828d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * examining both the the base link and all stacked links.
8290a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     *
830d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @param target a LinkProperties with the new list of routes
831d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti     * @return the differences between the routes.
8324f05d5529625fd2f0ad13ff9974c338d2f847934Robert Greenwalt     * @hide
8330a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     */
834d1e0fae2bc5c98b1f00b185d7be7219dc7e1d0f7Lorenzo Colitti    public CompareResult<RouteInfo> compareAllRoutes(LinkProperties target) {
8350a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        /*
8360a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * Duplicate the RouteInfos into removed, we will be removing
8371994bc14ab9fd3a3c5dca8851cfc0042bcb25d46Lorenzo Colitti         * routes which are common between mRoutes and target
8380a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * leaving the routes that are different. And route address which
8390a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         * are in target but not in mRoutes are placed in added.
8400a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt         */
8410a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        CompareResult<RouteInfo> result = new CompareResult<RouteInfo>();
8420a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
843419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        result.removed = getAllRoutes();
8440a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        result.added.clear();
8450a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (target != null) {
846419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti            for (RouteInfo r : target.getAllRoutes()) {
8470a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (! result.removed.remove(r)) {
8480a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    result.added.add(r);
8490a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
8500a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
8510a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        }
8520a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return result;
8530a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
8540a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
855992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    /**
856992f25257938ecc0378514f21c6e6e6375272976Paul Jensen     * Compares all interface names in this LinkProperties with another
857992f25257938ecc0378514f21c6e6e6375272976Paul Jensen     * LinkProperties, examining both the the base link and all stacked links.
858992f25257938ecc0378514f21c6e6e6375272976Paul Jensen     *
859992f25257938ecc0378514f21c6e6e6375272976Paul Jensen     * @param target a LinkProperties with the new list of interface names
860992f25257938ecc0378514f21c6e6e6375272976Paul Jensen     * @return the differences between the interface names.
861992f25257938ecc0378514f21c6e6e6375272976Paul Jensen     * @hide
862992f25257938ecc0378514f21c6e6e6375272976Paul Jensen     */
863992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    public CompareResult<String> compareAllInterfaceNames(LinkProperties target) {
864992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        /*
865992f25257938ecc0378514f21c6e6e6375272976Paul Jensen         * Duplicate the interface names into removed, we will be removing
866992f25257938ecc0378514f21c6e6e6375272976Paul Jensen         * interface names which are common between this and target
867992f25257938ecc0378514f21c6e6e6375272976Paul Jensen         * leaving the interface names that are different. And interface names which
868992f25257938ecc0378514f21c6e6e6375272976Paul Jensen         * are in target but not in this are placed in added.
869992f25257938ecc0378514f21c6e6e6375272976Paul Jensen         */
870992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        CompareResult<String> result = new CompareResult<String>();
871992f25257938ecc0378514f21c6e6e6375272976Paul Jensen
872992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        result.removed = getAllInterfaceNames();
873992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        result.added.clear();
874992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        if (target != null) {
875992f25257938ecc0378514f21c6e6e6375272976Paul Jensen            for (String r : target.getAllInterfaceNames()) {
876992f25257938ecc0378514f21c6e6e6375272976Paul Jensen                if (! result.removed.remove(r)) {
877992f25257938ecc0378514f21c6e6e6375272976Paul Jensen                    result.added.add(r);
878992f25257938ecc0378514f21c6e6e6375272976Paul Jensen                }
879992f25257938ecc0378514f21c6e6e6375272976Paul Jensen            }
880992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        }
881992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        return result;
882992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    }
883992f25257938ecc0378514f21c6e6e6375272976Paul Jensen
8840a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
8854e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    @Override
8864e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    /**
8874e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * generate hashcode based on significant fields
8884e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * Equal objects must produce the same hash code, while unequal objects
8894e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     * may have the same hash codes.
8904e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang     */
8914e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    public int hashCode() {
8924e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang        return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
8934e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang                + mLinkAddresses.size() * 31
8944e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang                + mDnses.size() * 37
8958058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt                + ((null == mDomains) ? 0 : mDomains.hashCode())
896aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                + mRoutes.size() * 41
897419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())
8989d9b74a900696191048aa97cc3c854072640428bsy.yun                + mStackedLinks.hashCode() * 47)
8999d9b74a900696191048aa97cc3c854072640428bsy.yun                + mMtu * 51;
9004e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang    }
9014e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang
90247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    /**
90347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * Implement the Parcelable interface.
90447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     */
90537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public void writeToParcel(Parcel dest, int flags) {
90647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        dest.writeString(getInterfaceName());
907ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        dest.writeInt(mLinkAddresses.size());
908ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff        for(LinkAddress linkAddress : mLinkAddresses) {
909ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff            dest.writeParcelable(linkAddress, flags);
91047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
911ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff
91247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        dest.writeInt(mDnses.size());
91347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        for(InetAddress d : mDnses) {
91447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeByteArray(d.getAddress());
91547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
9168058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt        dest.writeString(mDomains);
9179d9b74a900696191048aa97cc3c854072640428bsy.yun        dest.writeInt(mMtu);
918aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        dest.writeInt(mRoutes.size());
919aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt        for(RouteInfo route : mRoutes) {
920aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt            dest.writeParcelable(route, flags);
92147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
922992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt
92347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        if (mHttpProxy != null) {
92447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeByte((byte)1);
92547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeParcelable(mHttpProxy, flags);
92647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        } else {
92747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            dest.writeByte((byte)0);
92847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        }
929419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        ArrayList<LinkProperties> stackedLinks = new ArrayList(mStackedLinks.values());
930419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti        dest.writeList(stackedLinks);
93147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    }
93247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
93347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt    /**
93447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     * Implement the Parcelable interface.
93547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt     */
93637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt    public static final Creator<LinkProperties> CREATOR =
93737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt        new Creator<LinkProperties>() {
93837e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt            public LinkProperties createFromParcel(Parcel in) {
93937e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                LinkProperties netProp = new LinkProperties();
9404717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt
94147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                String iface = in.readString();
94247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                if (iface != null) {
9434717c261b2c670d5c0925e3527a864aa52db6ac0Robert Greenwalt                    netProp.setInterfaceName(iface);
94447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
94547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                int addressCount = in.readInt();
94647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                for (int i=0; i<addressCount; i++) {
947ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff                    netProp.addLinkAddress((LinkAddress)in.readParcelable(null));
94847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
94947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                addressCount = in.readInt();
95047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                for (int i=0; i<addressCount; i++) {
95147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    try {
952df2b878ff4e7b4a258588d3a93574c399db78a07Robert Greenwalt                        netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
95347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                    } catch (UnknownHostException e) { }
95447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
9558058f621891b41c6864b6004c1c47647436a0ac1Robert Greenwalt                netProp.setDomains(in.readString());
9569d9b74a900696191048aa97cc3c854072640428bsy.yun                netProp.setMtu(in.readInt());
957992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                addressCount = in.readInt();
958992564e481af13cbcb058ee801f9254a520c54a1Robert Greenwalt                for (int i=0; i<addressCount; i++) {
959aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwalt                    netProp.addRoute((RouteInfo)in.readParcelable(null));
96047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
96147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                if (in.readByte() == 1) {
962207900c23b26d0df9ab28c709db4a1007d7d7904Jason Monk                    netProp.setHttpProxy((ProxyInfo)in.readParcelable(null));
96347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                }
964419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
965419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                in.readList(stackedLinks, LinkProperties.class.getClassLoader());
966419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                for (LinkProperties stackedLink: stackedLinks) {
967419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                    netProp.addStackedLink(stackedLink);
968419a4ce9e461177d75eca5fd71fc8c275969e479Lorenzo Colitti                }
96947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                return netProp;
97047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            }
97147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt
97237e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt            public LinkProperties[] newArray(int size) {
97337e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                return new LinkProperties[size];
97447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt            }
97547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        };
97647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt}
977