Merge "Notify network observers of route changes."

This commit is contained in:
Lorenzo Colitti
2014-06-17 04:26:21 +00:00
committed by Android (Google) Code Review
4 changed files with 122 additions and 0 deletions

View File

@@ -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);
}

View File

@@ -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
}
}

View File

@@ -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.
*/

View File

@@ -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;