Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc5e367d authored by Robert Greenwalt's avatar Robert Greenwalt Committed by Android (Google) Code Review
Browse files

Merge "resolved conflicts for merge of 8550f3b8 to master"

parents e173b9d7 d9212d30
Loading
Loading
Loading
Loading
+77 −13
Original line number Diff line number Diff line
@@ -57,16 +57,16 @@ public class LinkProperties implements Parcelable {
    private Collection<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
    private ProxyProperties mHttpProxy;

    public static class CompareAddressesResult {
        public ArrayList<LinkAddress> removed = new ArrayList<LinkAddress>();
        public ArrayList<LinkAddress> added = new ArrayList<LinkAddress>();
    public static class CompareResult<T> {
        public ArrayList<T> removed = new ArrayList<T>();
        public ArrayList<T> added = new ArrayList<T>();

        @Override
        public String toString() {
            String retVal = "removedAddresses=[";
            for (LinkAddress addr : removed) retVal += addr.toString() + ",";
            retVal += "] addedAddresses=[";
            for (LinkAddress addr : added) retVal += addr.toString() + ",";
            String retVal = "removed=[";
            for (T addr : removed) retVal += addr.toString() + ",";
            retVal += "] added=[";
            for (T addr : added) retVal += addr.toString() + ",";
            retVal += "]";
            return retVal;
        }
@@ -263,10 +263,10 @@ public class LinkProperties implements Parcelable {
     * mLinkAddress which would then result in target and mLinkAddresses
     * being the same list.
     *
     * @param target is a new list of addresses
     * @param target is a LinkProperties with the new list of addresses
     * @return the removed and added lists.
     */
    public CompareAddressesResult compareAddresses(LinkProperties target) {
    public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
        /*
         * Duplicate the LinkAddresses into removed, we will be removing
         * address which are common between mLinkAddresses and target
@@ -274,17 +274,81 @@ public class LinkProperties implements Parcelable {
         * are in target but not in mLinkAddresses are placed in the
         * addedAddresses.
         */
        CompareAddressesResult result = new CompareAddressesResult();
        CompareResult<LinkAddress> result = new CompareResult<LinkAddress>();
        result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
        result.added.clear();
        if (target != null) {
            for (LinkAddress newAddress : target.getLinkAddresses()) {
                if (! result.removed.remove(newAddress)) {
                    result.added.add(newAddress);
                }
            }
        }
        return result;
    }

    /**
     * Return two lists, a list of dns addresses that would be removed from
     * mDnses and a list of addresses that would be added to
     * mDnses which would then result in target and mDnses
     * being the same list.
     *
     * @param target is a LinkProperties with the new list of dns addresses
     * @return the removed and added lists.
     */
    public CompareResult<InetAddress> compareDnses(LinkProperties target) {
        /*
         * Duplicate the InetAddresses into removed, we will be removing
         * dns address which are common between mDnses and target
         * leaving the addresses that are different. And dns address which
         * are in target but not in mDnses are placed in the
         * addedAddresses.
         */
        CompareResult<InetAddress> result = new CompareResult<InetAddress>();

        result.removed = new ArrayList<InetAddress>(mDnses);
        result.added.clear();
        if (target != null) {
            for (InetAddress newAddress : target.getDnses()) {
                if (! result.removed.remove(newAddress)) {
                    result.added.add(newAddress);
                }
            }
        }
        return result;
    }

    /**
     * Return two lists, a list of routes that would be removed from
     * mRoutes and a list of routes that would be added to
     * mRoutes which would then result in target and mRoutes
     * being the same list.
     *
     * @param target is a LinkProperties with the new list of routes
     * @return the removed and added lists.
     */
    public CompareResult<RouteInfo> compareRoutes(LinkProperties target) {
        /*
         * Duplicate the RouteInfos into removed, we will be removing
         * routes which are common between mDnses and target
         * leaving the routes that are different. And route address which
         * are in target but not in mRoutes are placed in added.
         */
        CompareResult<RouteInfo> result = new CompareResult<RouteInfo>();

        result.removed = new ArrayList<RouteInfo>(mRoutes);
        result.added.clear();
        if (target != null) {
            for (RouteInfo r : target.getRoutes()) {
                if (! result.removed.remove(r)) {
                    result.added.add(r);
                }
            }
        }
        return result;
    }


    @Override
    /**
     * generate hashcode based on significant fields
+11 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ public class RouteInfo implements Parcelable {
    private final InetAddress mGateway;

    private final boolean mIsDefault;
    private final boolean mIsHost;

    public RouteInfo(LinkAddress destination, InetAddress gateway) {
        if (destination == null) {
@@ -68,6 +69,7 @@ public class RouteInfo implements Parcelable {
                destination.getNetworkPrefixLength()), destination.getNetworkPrefixLength());
        mGateway = gateway;
        mIsDefault = isDefault();
        mIsHost = isHost();
    }

    public RouteInfo(InetAddress gateway) {
@@ -88,6 +90,10 @@ public class RouteInfo implements Parcelable {
        }
    }

    private boolean isHost() {
        return (mGateway.equals(Inet4Address.ANY) || mGateway.equals(Inet6Address.ANY));
    }

    private boolean isDefault() {
        boolean val = false;
        if (mGateway != null) {
@@ -100,6 +106,7 @@ public class RouteInfo implements Parcelable {
        return val;
    }


    public LinkAddress getDestination() {
        return mDestination;
    }
@@ -112,6 +119,10 @@ public class RouteInfo implements Parcelable {
        return mIsDefault;
    }

    public boolean isHostRoute() {
        return mIsHost;
    }

    public String toString() {
        String val = "";
        if (mDestination != null) val = mDestination.toString();
+133 −177
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ import android.net.INetworkPolicyListener;
import android.net.INetworkPolicyManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.LinkProperties.CompareAddressesResult;
import android.net.LinkProperties.CompareResult;
import android.net.MobileDataStateTracker;
import android.net.NetworkConfig;
import android.net.NetworkInfo;
@@ -260,6 +260,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {

    private InetAddress mDefaultDns;

    // this collection is used to refcount the added routes - if there are none left
    // it's time to remove the route from the route table
    private Collection<RouteInfo> mAddedRoutes = new ArrayList<RouteInfo>();

    // used in DBG mode to track inet condition reports
    private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
    private ArrayList mInetLog;
@@ -479,7 +483,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
                        mNetConfigs[netType].radio);
                continue;
            }
            mCurrentLinkProperties[netType] = mNetTrackers[netType].getLinkProperties();
            mCurrentLinkProperties[netType] = null;
        }

        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
@@ -1053,63 +1057,69 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        }
        try {
            InetAddress addr = InetAddress.getByAddress(hostAddress);
            return addHostRoute(tracker, addr, 0);
            LinkProperties lp = tracker.getLinkProperties();
            return addRoute(lp, RouteInfo.makeHostRoute(addr));
        } catch (UnknownHostException e) {}
        return false;
    }

    /**
     * Ensure that a network route exists to deliver traffic to the specified
     * host via the mobile data network.
     * @param hostAddress the IP address of the host to which the route is desired,
     * in network byte order.
     * TODO - deprecate
     * @return {@code true} on success, {@code false} on failure
     */
    private boolean addHostRoute(NetworkStateTracker nt, InetAddress hostAddress, int cycleCount) {
        LinkProperties lp = nt.getLinkProperties();
        if ((lp == null) || (hostAddress == null)) return false;
    private boolean addRoute(LinkProperties p, RouteInfo r) {
        return modifyRoute(p.getInterfaceName(), p, r, 0, true);
    }

        String interfaceName = lp.getInterfaceName();
        if (DBG) {
            log("Requested host route to " + hostAddress + "(" + interfaceName + "), cycleCount=" +
                    cycleCount);
    private boolean removeRoute(LinkProperties p, RouteInfo r) {
        return modifyRoute(p.getInterfaceName(), p, r, 0, false);
    }
        if (interfaceName == null) {
            if (DBG) loge("addHostRoute failed due to null interface name");

    private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
            boolean doAdd) {
        if ((ifaceName == null) || (lp == null) || (r == null)) return false;

        if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
            loge("Error adding route - too much recursion");
            return false;
        }

        RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), hostAddress);
        InetAddress gatewayAddress = null;
        if (r.isHostRoute() == false) {
            RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), r.getGateway());
            if (bestRoute != null) {
            gatewayAddress = bestRoute.getGateway();
            // if the best route is ourself, don't relf-reference, just add the host route
            if (hostAddress.equals(gatewayAddress)) gatewayAddress = null;
                if (bestRoute.getGateway().equals(r.getGateway()) == false) {
                    bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
                } else {
                    bestRoute = RouteInfo.makeHostRoute(r.getGateway());
                }
        if (gatewayAddress != null) {
            if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
                loge("Error adding hostroute - too much recursion");
                return false;
                if (!modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd)) return false;
            }
            if (!addHostRoute(nt, gatewayAddress, cycleCount+1)) return false;
        }

        RouteInfo route = RouteInfo.makeHostRoute(hostAddress, gatewayAddress);

        if (doAdd) {
            if (DBG) log("Adding " + r + " for interface " + ifaceName);
            mAddedRoutes.add(r);
            try {
            mNetd.addRoute(interfaceName, route);
            return true;
        } catch (Exception ex) {
                mNetd.addRoute(ifaceName, r);
            } catch (Exception e) {
                // never crash - catch them all
                loge("Exception trying to add a route: " + e);
                return false;
            }
    }

    // TODO support the removal of single host routes.  Keep a ref count of them so we
    // aren't over-zealous
    private boolean removeHostRoute(NetworkStateTracker nt, InetAddress hostAddress) {
        } else {
            // if we remove this one and there are no more like it, then refcount==0 and
            // we can remove it from the table
            mAddedRoutes.remove(r);
            if (mAddedRoutes.contains(r) == false) {
                if (DBG) log("Removing " + r + " for interface " + ifaceName);
                try {
                    mNetd.removeRoute(ifaceName, r);
                } catch (Exception e) {
                    // never crash - catch them all
                    loge("Exception trying to remove a route: " + e);
                    return false;
                }
            } else {
                if (DBG) log("not removing " + r + " as it's still in use");
            }
        }
        return true;
    }

    /**
     * @see ConnectivityManager#getBackgroundDataSetting()
@@ -1583,10 +1593,11 @@ public class ConnectivityService extends IConnectivityManager.Stub {
         */
        handleDnsConfigurationChange(netType);

        if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
            LinkProperties newLp = mNetTrackers[netType].getLinkProperties();
        LinkProperties curLp = mCurrentLinkProperties[netType];
            mCurrentLinkProperties[netType] = newLp;
        LinkProperties newLp = null;

        if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
            newLp = mNetTrackers[netType].getLinkProperties();
            if (VDBG) {
                log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
                        " doReset=" + doReset + " resetMask=" + resetMask +
@@ -1594,8 +1605,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
                        "\n   newLp=" + newLp);
            }

            if (curLp != null) {
                if (curLp.isIdenticalInterfaceName(newLp)) {
                CompareAddressesResult car = curLp.compareAddresses(newLp);
                    CompareResult<LinkAddress> car = curLp.compareAddresses(newLp);
                    if ((car.removed.size() != 0) || (car.added.size() != 0)) {
                        for (LinkAddress linkAddr : car.removed) {
                            if (linkAddr.getAddress() instanceof Inet4Address) {
@@ -1623,32 +1635,20 @@ public class ConnectivityService extends IConnectivityManager.Stub {
                            " linkProperty[" + netType + "]:" +
                            " resetMask=" + resetMask);
                }
            }
            if (mNetConfigs[netType].isDefault()) {
                handleApplyDefaultProxy(netType);
                addDefaultRoute(mNetTrackers[netType]);
            } else {
                // many radios add a default route even when we don't want one.
                // remove the default route unless we need it for our active network
                if (mActiveDefaultNetwork != -1) {
                    LinkProperties defaultLinkProperties =
                            mNetTrackers[mActiveDefaultNetwork].getLinkProperties();
                    LinkProperties newLinkProperties =
                            mNetTrackers[netType].getLinkProperties();
                    String defaultIface = defaultLinkProperties.getInterfaceName();
                    if (defaultIface != null &&
                            !defaultIface.equals(newLinkProperties.getInterfaceName())) {
                        removeDefaultRoute(mNetTrackers[netType]);
                    }
            }
                addPrivateDnsRoutes(mNetTrackers[netType]);
            }
        } else {
            if (mNetConfigs[netType].isDefault()) {
                removeDefaultRoute(mNetTrackers[netType]);
        } else {
                removePrivateDnsRoutes(mNetTrackers[netType]);
            if (VDBG) {
                log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
                        " doReset=" + doReset + " resetMask=" + resetMask +
                        "\n  curLp=" + curLp +
                        "\n  newLp= null");
            }
        }
        mCurrentLinkProperties[netType] = newLp;
        updateRoutes(newLp, curLp, mNetConfigs[netType].isDefault());

        if (doReset || resetMask != 0) {
            LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
@@ -1672,108 +1672,64 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        }
    }

    private void addPrivateDnsRoutes(NetworkStateTracker nt) {
        boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet();
        LinkProperties p = nt.getLinkProperties();
        if (p == null) return;
        String interfaceName = p.getInterfaceName();
    /**
     * Add and remove routes using the old properties (null if not previously connected),
     * new properties (null if becoming disconnected).  May even be double null, which
     * is a noop.
     * Uses isLinkDefault to determine if default routes should be set or conversely if
     * host routes should be set to the dns servers
     */
    private void updateRoutes(LinkProperties newLp, LinkProperties curLp, boolean isLinkDefault) {
        Collection<RouteInfo> routesToAdd = null;
        CompareResult<InetAddress> dnsDiff = null;

        if (DBG) {
            log("addPrivateDnsRoutes for " + nt +
                    "(" + interfaceName + ") - mPrivateDnsRouteSet = " + privateDnsRouteSet);
        }
        if (interfaceName != null && !privateDnsRouteSet) {
            Collection<InetAddress> dnsList = p.getDnses();
            for (InetAddress dns : dnsList) {
                addHostRoute(nt, dns, 0);
        if (curLp != null) {
            // check for the delta between the current set and the new
            CompareResult<RouteInfo> routeDiff = curLp.compareRoutes(newLp);
            dnsDiff = curLp.compareDnses(newLp);

            for (RouteInfo r : routeDiff.removed) {
                if (isLinkDefault || ! r.isDefaultRoute()) {
                    removeRoute(curLp, r);
                }
            nt.privateDnsRouteSet(true);
            }
            routesToAdd = routeDiff.added;
        }

    private void removePrivateDnsRoutes(NetworkStateTracker nt) {
        LinkProperties p = nt.getLinkProperties();
        if (p == null) return;
        String interfaceName = p.getInterfaceName();
        boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet();
        if (interfaceName != null && privateDnsRouteSet) {
            if (DBG) {
                log("removePrivateDnsRoutes for " + nt.getNetworkInfo().getTypeName() +
                        " (" + interfaceName + ")");
        if (newLp != null) {
            // if we didn't get a diff from cur -> new, then just use the new
            if (routesToAdd == null) {
                routesToAdd = newLp.getRoutes();
            }

            Collection<InetAddress> dnsList = p.getDnses();
            for (InetAddress dns : dnsList) {
                if (DBG) log("  removing " + dns);
                RouteInfo route = RouteInfo.makeHostRoute(dns);
                try {
                    mNetd.removeRoute(interfaceName, route);
                } catch (Exception ex) {
                    loge("error (" + ex + ") removing dns route " + route);
            for (RouteInfo r :  routesToAdd) {
                if (isLinkDefault || ! r.isDefaultRoute()) {
                    addRoute(newLp, r);
                }
            }
            nt.privateDnsRouteSet(false);
        }
    }


    private void addDefaultRoute(NetworkStateTracker nt) {
        LinkProperties p = nt.getLinkProperties();
        if (p == null) return;
        String interfaceName = p.getInterfaceName();
        if (TextUtils.isEmpty(interfaceName)) return;

        for (RouteInfo route : p.getRoutes()) {
            //TODO - handle non-default routes
            if (route.isDefaultRoute()) {
                if (DBG) log("adding default route " + route);
                InetAddress gateway = route.getGateway();
                if (addHostRoute(nt, gateway, 0)) {
                    try {
                        mNetd.addRoute(interfaceName, route);
                    } catch (Exception e) {
                        loge("error adding default route " + route);
                        continue;
        if (!isLinkDefault) {
            // handle DNS routes
            Collection<InetAddress> dnsToAdd = null;
            if (dnsDiff != null) {
                dnsToAdd = dnsDiff.added;
                for (InetAddress dnsAddress : dnsDiff.removed) {
                    removeRoute(curLp, RouteInfo.makeHostRoute(dnsAddress));
                }
                    if (DBG) {
                        NetworkInfo networkInfo = nt.getNetworkInfo();
                        log("addDefaultRoute for " + networkInfo.getTypeName() +
                                " (" + interfaceName + "), GatewayAddr=" +
                                gateway.getHostAddress());
            }
                } else {
                    loge("error adding host route for default route " + route);
            if (newLp != null) {
                if (dnsToAdd == null) {
                    dnsToAdd = newLp.getDnses();
                }
            }
        }
    }


    public void removeDefaultRoute(NetworkStateTracker nt) {
        LinkProperties p = nt.getLinkProperties();
        if (p == null) return;
        String interfaceName = p.getInterfaceName();

        if (interfaceName == null) return;

        for (RouteInfo route : p.getRoutes()) {
            //TODO - handle non-default routes
            if (route.isDefaultRoute()) {
                try {
                    mNetd.removeRoute(interfaceName, route);
                } catch (Exception ex) {
                    loge("error (" + ex + ") removing default route " + route);
                    continue;
                }
                if (DBG) {
                    NetworkInfo networkInfo = nt.getNetworkInfo();
                    log("removeDefaultRoute for " + networkInfo.getTypeName() + " (" +
                            interfaceName + ")");
                for(InetAddress dnsAddress : dnsToAdd) {
                    addRoute(newLp, RouteInfo.makeHostRoute(dnsAddress));
                }
            }
        }
    }


   /**
     * Reads the network specific TCP buffer sizes from SystemProperties
     * net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
+0 −1
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import com.android.internal.util.StateMachine;
import android.app.PendingIntent;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
import android.net.LinkProperties.CompareAddressesResult;
import android.net.ProxyProperties;
import android.os.AsyncResult;
import android.os.Message;
+0 −1
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import com.android.internal.util.Protocol;
import android.app.PendingIntent;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
import android.net.LinkProperties.CompareAddressesResult;
import android.net.ProxyProperties;
import android.os.Message;

Loading