am 6b5e201d: am 6d1d16c3: Merge "Remove STOPSHIP but allow seamless Handoff when possible." into honeycomb-LTE

* commit '6b5e201d4717091d1c54fb561ea2dea9f6e9b17a':
  Remove STOPSHIP but allow seamless Handoff when possible.
This commit is contained in:
Wink Saville
2011-07-14 10:55:58 -07:00
committed by Android Git Automerger
2 changed files with 164 additions and 32 deletions

View File

@@ -52,11 +52,26 @@ import java.util.Collections;
public class LinkProperties implements Parcelable { public class LinkProperties implements Parcelable {
String mIfaceName; String mIfaceName;
private Collection<LinkAddress> mLinkAddresses; private Collection<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
private Collection<InetAddress> mDnses; private Collection<InetAddress> mDnses = new ArrayList<InetAddress>();
private Collection<RouteInfo> mRoutes; private Collection<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
private ProxyProperties mHttpProxy; private ProxyProperties mHttpProxy;
public static class CompareAddressesResult {
public ArrayList<LinkAddress> removed = new ArrayList<LinkAddress>();
public ArrayList<LinkAddress> added = new ArrayList<LinkAddress>();
@Override
public String toString() {
String retVal = "removedAddresses=[";
for (LinkAddress addr : removed) retVal += addr.toString() + ",";
retVal += "] addedAddresses=[";
for (LinkAddress addr : added) retVal += addr.toString() + ",";
retVal += "]";
return retVal;
}
}
public LinkProperties() { public LinkProperties() {
clear(); clear();
} }
@@ -121,9 +136,9 @@ public class LinkProperties implements Parcelable {
public void clear() { public void clear() {
mIfaceName = null; mIfaceName = null;
mLinkAddresses = new ArrayList<LinkAddress>(); mLinkAddresses.clear();
mDnses = new ArrayList<InetAddress>(); mDnses.clear();
mRoutes = new ArrayList<RouteInfo>(); mRoutes.clear();
mHttpProxy = null; mHttpProxy = null;
} }
@@ -155,6 +170,63 @@ public class LinkProperties implements Parcelable {
return ifaceName + linkAddresses + routes + dns + proxy; return ifaceName + linkAddresses + routes + dns + proxy;
} }
/**
* Compares this {@code LinkProperties} interface name against the target
*
* @param target LinkProperties to compare.
* @return {@code true} if both are identical, {@code false} otherwise.
*/
public boolean isIdenticalInterfaceName(LinkProperties target) {
return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
}
/**
* Compares this {@code LinkProperties} interface name against the target
*
* @param target LinkProperties to compare.
* @return {@code true} if both are identical, {@code false} otherwise.
*/
public boolean isIdenticalAddresses(LinkProperties target) {
Collection<InetAddress> targetAddresses = target.getAddresses();
Collection<InetAddress> sourceAddresses = getAddresses();
return (sourceAddresses.size() == targetAddresses.size()) ?
sourceAddresses.containsAll(targetAddresses) : false;
}
/**
* Compares this {@code LinkProperties} DNS addresses against the target
*
* @param target LinkProperties to compare.
* @return {@code true} if both are identical, {@code false} otherwise.
*/
public boolean isIdenticalDnses(LinkProperties target) {
Collection<InetAddress> targetDnses = target.getDnses();
return (mDnses.size() == targetDnses.size()) ?
mDnses.containsAll(targetDnses) : false;
}
/**
* Compares this {@code LinkProperties} Routes against the target
*
* @param target LinkProperties to compare.
* @return {@code true} if both are identical, {@code false} otherwise.
*/
public boolean isIdenticalRoutes(LinkProperties target) {
Collection<RouteInfo> targetRoutes = target.getRoutes();
return (mRoutes.size() == targetRoutes.size()) ?
mRoutes.containsAll(targetRoutes) : false;
}
/**
* Compares this {@code LinkProperties} HttpProxy against the target
*
* @param target LinkProperties to compare.
* @return {@code true} if both are identical, {@code false} otherwise.
*/
public boolean isIdenticalHttpProxy(LinkProperties target) {
return getHttpProxy() == null ? target.getHttpProxy() == null :
getHttpProxy().equals(target.getHttpProxy());
}
@Override @Override
/** /**
@@ -176,30 +248,41 @@ public class LinkProperties implements Parcelable {
if (!(obj instanceof LinkProperties)) return false; if (!(obj instanceof LinkProperties)) return false;
boolean sameAddresses;
boolean sameDnses;
boolean sameRoutes;
LinkProperties target = (LinkProperties) obj; LinkProperties target = (LinkProperties) obj;
Collection<InetAddress> targetAddresses = target.getAddresses(); return isIdenticalInterfaceName(target) &&
Collection<InetAddress> sourceAddresses = getAddresses(); isIdenticalAddresses(target) &&
sameAddresses = (sourceAddresses.size() == targetAddresses.size()) ? isIdenticalDnses(target) &&
sourceAddresses.containsAll(targetAddresses) : false; isIdenticalRoutes(target) &&
isIdenticalHttpProxy(target);
}
Collection<InetAddress> targetDnses = target.getDnses(); /**
sameDnses = (mDnses.size() == targetDnses.size()) ? * Return two lists, a list of addresses that would be removed from
mDnses.containsAll(targetDnses) : false; * mLinkAddresses and a list of addresses that would be added to
* mLinkAddress which would then result in target and mLinkAddresses
Collection<RouteInfo> targetRoutes = target.getRoutes(); * being the same list.
sameRoutes = (mRoutes.size() == targetRoutes.size()) ? *
mRoutes.containsAll(targetRoutes) : false; * @param target is a new list of addresses
* @return the removed and added lists.
return */
sameAddresses && sameDnses && sameRoutes public CompareAddressesResult compareAddresses(LinkProperties target) {
&& TextUtils.equals(getInterfaceName(), target.getInterfaceName()) /*
&& (getHttpProxy() == null ? target.getHttpProxy() == null : * Duplicate the LinkAddresses into removed, we will be removing
getHttpProxy().equals(target.getHttpProxy())); * address which are common between mLinkAddresses and target
* leaving the addresses that are different. And address which
* are in target but not in mLinkAddresses are placed in the
* addedAddresses.
*/
CompareAddressesResult result = new CompareAddressesResult();
result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
result.added.clear();
for (LinkAddress newAddress : target.getLinkAddresses()) {
if (! result.removed.remove(newAddress)) {
result.added.add(newAddress);
}
}
return result;
} }
@Override @Override

View File

@@ -34,6 +34,7 @@ import android.net.IConnectivityManager;
import android.net.INetworkPolicyListener; import android.net.INetworkPolicyListener;
import android.net.INetworkPolicyManager; import android.net.INetworkPolicyManager;
import android.net.LinkProperties; import android.net.LinkProperties;
import android.net.LinkProperties.CompareAddressesResult;
import android.net.MobileDataStateTracker; import android.net.MobileDataStateTracker;
import android.net.NetworkConfig; import android.net.NetworkConfig;
import android.net.NetworkInfo; import android.net.NetworkInfo;
@@ -76,6 +77,7 @@ import com.google.android.collect.Sets;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -92,6 +94,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class ConnectivityService extends IConnectivityManager.Stub { public class ConnectivityService extends IConnectivityManager.Stub {
private static final boolean DBG = true; private static final boolean DBG = true;
private static final boolean VDBG = true;
private static final String TAG = "ConnectivityService"; private static final String TAG = "ConnectivityService";
private static final boolean LOGD_RULES = false; private static final boolean LOGD_RULES = false;
@@ -125,6 +128,11 @@ public class ConnectivityService extends IConnectivityManager.Stub {
*/ */
private NetworkStateTracker mNetTrackers[]; private NetworkStateTracker mNetTrackers[];
/**
* The link properties that define the current links
*/
private LinkProperties mCurrentLinkProperties[];
/** /**
* A per Net list of the PID's that requested access to the net * A per Net list of the PID's that requested access to the net
* used both as a refcount and for per-PID DNS selection * used both as a refcount and for per-PID DNS selection
@@ -332,6 +340,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
mNetTrackers = new NetworkStateTracker[ mNetTrackers = new NetworkStateTracker[
ConnectivityManager.MAX_NETWORK_TYPE+1]; ConnectivityManager.MAX_NETWORK_TYPE+1];
mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
mNetworkPreference = getPersistedNetworkPreference(); mNetworkPreference = getPersistedNetworkPreference();
@@ -468,6 +477,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
mNetConfigs[netType].radio); mNetConfigs[netType].radio);
continue; continue;
} }
mCurrentLinkProperties[netType] = mNetTrackers[netType].getLinkProperties();
} }
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
@@ -1563,6 +1573,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
* right routing table entries exist. * right routing table entries exist.
*/ */
private void handleConnectivityChange(int netType, boolean doReset) { private void handleConnectivityChange(int netType, boolean doReset) {
int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0;
/* /*
* If a non-default network is enabled, add the host routes that * If a non-default network is enabled, add the host routes that
* will allow it's DNS servers to be accessed. * will allow it's DNS servers to be accessed.
@@ -1570,6 +1582,45 @@ public class ConnectivityService extends IConnectivityManager.Stub {
handleDnsConfigurationChange(netType); handleDnsConfigurationChange(netType);
if (mNetTrackers[netType].getNetworkInfo().isConnected()) { if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
LinkProperties newLp = mNetTrackers[netType].getLinkProperties();
LinkProperties curLp = mCurrentLinkProperties[netType];
mCurrentLinkProperties[netType] = newLp;
if (VDBG) {
log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
" doReset=" + doReset + " resetMask=" + resetMask +
"\n curLp=" + curLp +
"\n newLp=" + newLp);
}
if (curLp.isIdenticalInterfaceName(newLp)) {
CompareAddressesResult car = curLp.compareAddresses(newLp);
if ((car.removed.size() != 0) || (car.added.size() != 0)) {
for (LinkAddress linkAddr : car.removed) {
if (linkAddr.getAddress() instanceof Inet4Address) {
resetMask |= NetworkUtils.RESET_IPV4_ADDRESSES;
}
if (linkAddr.getAddress() instanceof Inet6Address) {
resetMask |= NetworkUtils.RESET_IPV6_ADDRESSES;
}
}
if (DBG) {
log("handleConnectivityChange: addresses changed" +
" linkProperty[" + netType + "]:" + " resetMask=" + resetMask +
"\n car=" + car);
}
} else {
if (DBG) {
log("handleConnectivityChange: address are the same reset per doReset" +
" linkProperty[" + netType + "]:" +
" resetMask=" + resetMask);
}
}
} else {
resetMask = NetworkUtils.RESET_ALL_ADDRESSES;
log("handleConnectivityChange: interface not not equivalent reset both" +
" linkProperty[" + netType + "]:" +
" resetMask=" + resetMask);
}
if (mNetConfigs[netType].isDefault()) { if (mNetConfigs[netType].isDefault()) {
handleApplyDefaultProxy(netType); handleApplyDefaultProxy(netType);
addDefaultRoute(mNetTrackers[netType]); addDefaultRoute(mNetTrackers[netType]);
@@ -1597,15 +1648,13 @@ public class ConnectivityService extends IConnectivityManager.Stub {
} }
} }
if (doReset) { if (doReset || resetMask != 0) {
LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties(); LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
if (linkProperties != null) { if (linkProperties != null) {
String iface = linkProperties.getInterfaceName(); String iface = linkProperties.getInterfaceName();
if (TextUtils.isEmpty(iface) == false) { if (TextUtils.isEmpty(iface) == false) {
if (DBG) { if (DBG) log("resetConnections(" + iface + ", " + resetMask + ")");
log("resetConnections(" + iface + ", NetworkUtils.RESET_ALL_ADDRESSES)"); NetworkUtils.resetConnections(iface, resetMask);
}
NetworkUtils.resetConnections(iface, NetworkUtils.RESET_ALL_ADDRESSES);
} }
} }
} }