Add address flags and scope to LinkAddress.
This is necessary so that the framework can know whether an IPv6
address is likely to be usable (i.e., if it's global scope and
preferred). Also, it will simplify the address notification
methods in INetworkManagementEventObserver, which currently take
the address, the flags, and the scope as separate arguments.
1. Add flags and scope to the class and update the unit test.
Use the IFA_F_* and RT_SCOPE_* constants defined by libcore.
Since most callers don't know about flags and scope, provide
constructors that default the flags to zero and determine the
scope from the address. Addresses notified by the kernel will
have these properly set. Make multicast addresses invalid.
Update the class documentation.
2. Provide an isSameAddressAs() method that compares only the
address and prefix information between two LinkAddress
objects. This is necessary because an interface can't have
two addresses with the same address/prefix but different
flags.
3. Update LinkProperties's addLinkAddress and removeLinkAddress
to identify existing addresses to add/remove using
isSameAddressAs instead of implicit equals(). Specifically:
- If addLinkAddress is called with an address that is already
present, the existing address's flags and scope are updated.
This allows, for example, an address on an interface to go
from preferred to deprecated when it expires, without it
having to be removed and re-added.
- If removeLinkAddress is called with an address that is
present but with different flags, it deletes that address
instead of failing to find a match.
4. Update the INetworkManagementEventObserver address
notification methods to take just a LinkAddress instead of
LinkAddress, flags, and scope. While I'm at it, change the
order of the arguments for consistency with the other
functions in the interface.
Change-Id: Id8fe0f09a7e8f6bee1ea3b52102178b689a9336e
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 40ea49e..ad7ec99 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -405,11 +405,11 @@
/**
* Notify our observers of a new or updated interface address.
*/
- private void notifyAddressUpdated(LinkAddress address, String iface, int flags, int scope) {
+ private void notifyAddressUpdated(String iface, LinkAddress address) {
final int length = mObservers.beginBroadcast();
for (int i = 0; i < length; i++) {
try {
- mObservers.getBroadcastItem(i).addressUpdated(address, iface, flags, scope);
+ mObservers.getBroadcastItem(i).addressUpdated(iface, address);
} catch (RemoteException e) {
} catch (RuntimeException e) {
}
@@ -420,11 +420,11 @@
/**
* Notify our observers of a deleted interface address.
*/
- private void notifyAddressRemoved(LinkAddress address, String iface, int flags, int scope) {
+ private void notifyAddressRemoved(String iface, LinkAddress address) {
final int length = mObservers.beginBroadcast();
for (int i = 0; i < length; i++) {
try {
- mObservers.getBroadcastItem(i).addressRemoved(address, iface, flags, scope);
+ mObservers.getBroadcastItem(i).addressRemoved(iface, address);
} catch (RemoteException e) {
} catch (RuntimeException e) {
}
@@ -535,23 +535,22 @@
throw new IllegalStateException(errorMessage);
}
- int flags;
- int scope;
+ String iface = cooked[4];
LinkAddress address;
try {
- flags = Integer.parseInt(cooked[5]);
- scope = Integer.parseInt(cooked[6]);
- address = new LinkAddress(cooked[3]);
+ int flags = Integer.parseInt(cooked[5]);
+ int scope = Integer.parseInt(cooked[6]);
+ address = new LinkAddress(cooked[3], flags, scope);
} catch(NumberFormatException e) { // Non-numeric lifetime or scope.
throw new IllegalStateException(errorMessage, e);
- } catch(IllegalArgumentException e) { // Malformed IP address.
+ } catch(IllegalArgumentException e) { // Malformed/invalid IP address.
throw new IllegalStateException(errorMessage, e);
}
if (cooked[2].equals("updated")) {
- notifyAddressUpdated(address, cooked[4], flags, scope);
+ notifyAddressUpdated(iface, address);
} else {
- notifyAddressRemoved(address, cooked[4], flags, scope);
+ notifyAddressRemoved(iface, address);
}
return true;
// break;