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

Commit b86f752a authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Android (Google) Code Review
Browse files

Merge "Notify network observers of route changes."

parents 8c0d4594 c18cbfdf
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.net;

import android.net.LinkAddress;
import android.net.RouteInfo;

/**
 * Callback class for receiving events from an INetworkManagementService
@@ -98,4 +99,14 @@ interface INetworkManagementEventObserver {
     * @param servers The IP addresses of the DNS servers.
     */
    void interfaceDnsServerInfo(String iface, long lifetime, in String[] servers);

    /**
     * A route has been added or updated.
     */
    void routeUpdated(in RouteInfo route);

    /**
     * A route has been removed.
     */
    void routeRemoved(in RouteInfo route);
}
+11 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.net;

import android.net.INetworkManagementEventObserver;
import android.net.LinkAddress;
import android.net.RouteInfo;

/**
 * Base {@link INetworkManagementEventObserver} that provides no-op
@@ -70,4 +71,14 @@ public class BaseNetworkObserver extends INetworkManagementEventObserver.Stub {
    public void interfaceDnsServerInfo(String iface, long lifetime, String[] servers) {
        // default no-op
    }

    @Override
    public void routeUpdated(RouteInfo route) {
        // default no-op
    }

    @Override
    public void routeRemoved(RouteInfo route) {
        // default no-op
    }
}
+35 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.net;

import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.RouteInfo;
import android.util.Log;

/**
@@ -84,6 +85,12 @@ public class NetlinkTracker extends BaseNetworkObserver {
        }
    }

    private void maybeLog(String operation, Object o) {
        if (DBG) {
            Log.d(TAG, operation + ": " + o.toString());
        }
    }

    @Override
    public void addressUpdated(String iface, LinkAddress address) {
        if (mInterfaceName.equals(iface)) {
@@ -112,6 +119,34 @@ public class NetlinkTracker extends BaseNetworkObserver {
        }
    }

    @Override
    public void routeUpdated(RouteInfo route) {
        if (mInterfaceName.equals(route.getInterface())) {
            maybeLog("routeUpdated", route);
            boolean changed;
            synchronized (this) {
                changed = mLinkProperties.addRoute(route);
            }
            if (changed) {
                mCallback.update();
            }
        }
    }

    @Override
    public void routeRemoved(RouteInfo route) {
        if (mInterfaceName.equals(route.getInterface())) {
            maybeLog("routeRemoved", route);
            boolean changed;
            synchronized (this) {
                changed = mLinkProperties.removeRoute(route);
            }
            if (changed) {
                mCallback.update();
            }
        }
    }

    /**
     * Returns a copy of this object's LinkProperties.
     */
+65 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.content.Context;
import android.net.ConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.InterfaceConfiguration;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.NetworkStats;
import android.net.NetworkUtils;
@@ -145,6 +146,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
        public static final int InterfaceClassActivity    = 613;
        public static final int InterfaceAddressChange    = 614;
        public static final int InterfaceDnsServerInfo    = 615;
        public static final int RouteChange               = 616;
    }

    static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
@@ -580,6 +582,28 @@ public class NetworkManagementService extends INetworkManagementService.Stub
        }
    }

    /**
     * Notify our observers of a route change.
     */
    private void notifyRouteChange(String action, RouteInfo route) {
        final int length = mObservers.beginBroadcast();
        try {
            for (int i = 0; i < length; i++) {
                try {
                    if (action.equals("updated")) {
                        mObservers.getBroadcastItem(i).routeUpdated(route);
                    } else {
                        mObservers.getBroadcastItem(i).routeRemoved(route);
                    }
                } catch (RemoteException e) {
                } catch (RuntimeException e) {
                }
            }
        } finally {
            mObservers.finishBroadcast();
        }
    }

    //
    // Netd Callback handling
    //
@@ -722,6 +746,47 @@ public class NetworkManagementService extends INetworkManagementService.Stub
                    }
                    return true;
                    // break;
            case NetdResponseCode.RouteChange:
                    /*
                     * A route has been updated or removed.
                     * Format: "NNN Route <updated|removed> <dst> [via <gateway] [dev <iface>]"
                     */
                    if (!cooked[1].equals("Route") || cooked.length < 6) {
                        throw new IllegalStateException(errorMessage);
                    }

                    String via = null;
                    String dev = null;
                    boolean valid = true;
                    for (int i = 4; (i + 1) < cooked.length && valid; i += 2) {
                        if (cooked[i].equals("dev")) {
                            if (dev == null) {
                                dev = cooked[i+1];
                            } else {
                                valid = false;  // Duplicate interface.
                            }
                        } else if (cooked[i].equals("via")) {
                            if (via == null) {
                                via = cooked[i+1];
                            } else {
                                valid = false;  // Duplicate gateway.
                            }
                        } else {
                            valid = false;      // Unknown syntax.
                        }
                    }
                    if (valid) {
                        try {
                            // InetAddress.parseNumericAddress(null) inexplicably returns ::1.
                            InetAddress gateway = null;
                            if (via != null) gateway = InetAddress.parseNumericAddress(via);
                            RouteInfo route = new RouteInfo(new IpPrefix(cooked[3]), gateway, dev);
                            notifyRouteChange(cooked[2], route);
                            return true;
                        } catch (IllegalArgumentException e) {}
                    }
                    throw new IllegalStateException(errorMessage);
                    // break;
            default: break;
            }
            return false;