Merge "Remove STOPSHIP but allow seamless Handoff when possible." into honeycomb-LTE
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.net.EthernetDataTracker;
|
|||||||
import android.net.IConnectivityManager;
|
import android.net.IConnectivityManager;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
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;
|
||||||
@@ -61,6 +62,7 @@ import java.io.FileDescriptor;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
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.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
@@ -76,6 +78,7 @@ import java.util.List;
|
|||||||
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";
|
||||||
|
|
||||||
// how long to wait before switching back to a radio's default network
|
// how long to wait before switching back to a radio's default network
|
||||||
@@ -98,6 +101,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
|
||||||
@@ -302,6 +310,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();
|
||||||
|
|
||||||
@@ -442,6 +451,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
mNetConfigs[netType].radio);
|
mNetConfigs[netType].radio);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
mCurrentLinkProperties[netType] = mNetTrackers[netType].getLinkProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
mTethering = new Tethering(mContext, mHandler.getLooper());
|
mTethering = new Tethering(mContext, mHandler.getLooper());
|
||||||
@@ -1409,6 +1419,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.
|
||||||
@@ -1416,6 +1428,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]);
|
||||||
@@ -1430,15 +1481,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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class DataCallState {
|
|||||||
/**
|
/**
|
||||||
* Class returned by onSetupConnectionCompleted.
|
* Class returned by onSetupConnectionCompleted.
|
||||||
*/
|
*/
|
||||||
protected enum SetupResult {
|
public enum SetupResult {
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
ERR_BadCommand,
|
ERR_BadCommand,
|
||||||
ERR_UnacceptableParameter,
|
ERR_UnacceptableParameter,
|
||||||
|
|||||||
@@ -17,30 +17,25 @@
|
|||||||
package com.android.internal.telephony;
|
package com.android.internal.telephony;
|
||||||
|
|
||||||
|
|
||||||
|
import com.android.internal.telephony.DataCallState.SetupResult;
|
||||||
import com.android.internal.util.AsyncChannel;
|
import com.android.internal.util.AsyncChannel;
|
||||||
import com.android.internal.util.Protocol;
|
import com.android.internal.util.Protocol;
|
||||||
import com.android.internal.util.State;
|
import com.android.internal.util.State;
|
||||||
import com.android.internal.util.StateMachine;
|
import com.android.internal.util.StateMachine;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.net.LinkAddress;
|
|
||||||
import android.net.LinkCapabilities;
|
import android.net.LinkCapabilities;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.NetworkUtils;
|
import android.net.LinkProperties.CompareAddressesResult;
|
||||||
import android.net.ProxyProperties;
|
import android.net.ProxyProperties;
|
||||||
import android.os.AsyncResult;
|
import android.os.AsyncResult;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Parcel;
|
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@hide}
|
* {@hide}
|
||||||
@@ -497,8 +492,7 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
} else {
|
} else {
|
||||||
if (DBG) log("onSetupConnectionCompleted received DataCallState: " + response);
|
if (DBG) log("onSetupConnectionCompleted received DataCallState: " + response);
|
||||||
cid = response.cid;
|
cid = response.cid;
|
||||||
// set link properties based on data call response
|
result = updateLinkProperty(response).setupResult;
|
||||||
result = setLinkProperties(response, mLinkProperties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -527,48 +521,41 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
return response.setLinkProperties(lp, okToUseSystemPropertyDns);
|
return response.setLinkProperties(lp, okToUseSystemPropertyDns);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataConnectionAc.LinkPropertyChangeAction updateLinkProperty(
|
public static class UpdateLinkPropertyResult {
|
||||||
DataCallState newState) {
|
public DataCallState.SetupResult setupResult = DataCallState.SetupResult.SUCCESS;
|
||||||
DataConnectionAc.LinkPropertyChangeAction changed =
|
public LinkProperties oldLp;
|
||||||
DataConnectionAc.LinkPropertyChangeAction.NONE;
|
public LinkProperties newLp;
|
||||||
|
public UpdateLinkPropertyResult(LinkProperties curLp) {
|
||||||
|
oldLp = curLp;
|
||||||
|
newLp = curLp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newState == null) return changed;
|
private UpdateLinkPropertyResult updateLinkProperty(DataCallState newState) {
|
||||||
|
UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties);
|
||||||
|
|
||||||
DataCallState.SetupResult result;
|
if (newState == null) return result;
|
||||||
LinkProperties newLp = new LinkProperties();
|
|
||||||
|
DataCallState.SetupResult setupResult;
|
||||||
|
result.newLp = new LinkProperties();
|
||||||
|
|
||||||
// set link properties based on data call response
|
// set link properties based on data call response
|
||||||
result = setLinkProperties(newState, newLp);
|
result.setupResult = setLinkProperties(newState, result.newLp);
|
||||||
if (result != DataCallState.SetupResult.SUCCESS) {
|
if (result.setupResult != DataCallState.SetupResult.SUCCESS) {
|
||||||
if (DBG) log("UpdateLinkProperty failed : " + result);
|
if (DBG) log("updateLinkProperty failed : " + result.setupResult);
|
||||||
return changed;
|
return result;
|
||||||
}
|
}
|
||||||
// copy HTTP proxy as it is not part DataCallState.
|
// copy HTTP proxy as it is not part DataCallState.
|
||||||
newLp.setHttpProxy(mLinkProperties.getHttpProxy());
|
result.newLp.setHttpProxy(mLinkProperties.getHttpProxy());
|
||||||
|
|
||||||
if (DBG) log("old LP=" + mLinkProperties);
|
if (DBG && (! result.oldLp.equals(result.newLp))) {
|
||||||
if (DBG) log("new LP=" + newLp);
|
if (DBG) log("updateLinkProperty old != new");
|
||||||
|
if (VDBG) log("updateLinkProperty old LP=" + result.oldLp);
|
||||||
// Check consistency of link address. Currently we expect
|
if (VDBG) log("updateLinkProperty new LP=" + result.newLp);
|
||||||
// only one "global" address is assigned per each IP type.
|
|
||||||
Collection<LinkAddress> oLinks = mLinkProperties.getLinkAddresses();
|
|
||||||
Collection<LinkAddress> nLinks = newLp.getLinkAddresses();
|
|
||||||
for (LinkAddress oldLink : oLinks) {
|
|
||||||
for (LinkAddress newLink : nLinks) {
|
|
||||||
if ((NetworkUtils.addressTypeMatches(oldLink.getAddress(),
|
|
||||||
newLink.getAddress())) &&
|
|
||||||
(oldLink.equals(newLink) == false)) {
|
|
||||||
return DataConnectionAc.LinkPropertyChangeAction.RESET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
mLinkProperties = result.newLp;
|
||||||
|
|
||||||
if (mLinkProperties == null || !mLinkProperties.equals(newLp)) {
|
return result;
|
||||||
mLinkProperties = newLp;
|
|
||||||
changed = DataConnectionAc.LinkPropertyChangeAction.CHANGED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -643,14 +630,15 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
}
|
}
|
||||||
case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
|
case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
|
||||||
DataCallState newState = (DataCallState) msg.obj;
|
DataCallState newState = (DataCallState) msg.obj;
|
||||||
DataConnectionAc.LinkPropertyChangeAction action = updateLinkProperty(newState);
|
UpdateLinkPropertyResult result =
|
||||||
|
updateLinkProperty(newState);
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE action="
|
log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE result="
|
||||||
+ action + " newState=" + newState);
|
+ result + " newState=" + newState);
|
||||||
}
|
}
|
||||||
mAc.replyToMessage(msg,
|
mAc.replyToMessage(msg,
|
||||||
DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,
|
DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,
|
||||||
action.ordinal());
|
result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {
|
case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {
|
||||||
@@ -688,7 +676,7 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
case DataConnectionAc.REQ_GET_APNCONTEXT_LIST: {
|
case DataConnectionAc.REQ_GET_APNCONTEXT_LIST: {
|
||||||
if (VDBG) log("REQ_GET_APNCONTEXT_LIST num in list=" + mApnList.size());
|
if (VDBG) log("REQ_GET_APNCONTEXT_LIST num in list=" + mApnList.size());
|
||||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNCONTEXT_LIST,
|
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNCONTEXT_LIST,
|
||||||
new ArrayList(mApnList));
|
new ArrayList<ApnContext>(mApnList));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DataConnectionAc.REQ_SET_RECONNECT_INTENT: {
|
case DataConnectionAc.REQ_SET_RECONNECT_INTENT: {
|
||||||
|
|||||||
@@ -16,12 +16,14 @@
|
|||||||
|
|
||||||
package com.android.internal.telephony;
|
package com.android.internal.telephony;
|
||||||
|
|
||||||
|
import com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
|
||||||
import com.android.internal.util.AsyncChannel;
|
import com.android.internal.util.AsyncChannel;
|
||||||
import com.android.internal.util.Protocol;
|
import com.android.internal.util.Protocol;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.net.LinkCapabilities;
|
import android.net.LinkCapabilities;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
|
import android.net.LinkProperties.CompareAddressesResult;
|
||||||
import android.net.ProxyProperties;
|
import android.net.ProxyProperties;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
|
||||||
@@ -310,18 +312,18 @@ public class DataConnectionAc extends AsyncChannel {
|
|||||||
if (DBG) log("reqUpdateLinkPropertiesDataCallState");
|
if (DBG) log("reqUpdateLinkPropertiesDataCallState");
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkPropertyChangeAction rspUpdateLinkPropertiesDataCallState(Message response) {
|
public UpdateLinkPropertyResult rspUpdateLinkPropertiesDataCallState(Message response) {
|
||||||
LinkPropertyChangeAction retVal = LinkPropertyChangeAction.fromInt(response.arg1);
|
UpdateLinkPropertyResult retVal = (UpdateLinkPropertyResult)response.obj;
|
||||||
if (DBG) log("rspUpdateLinkPropertiesState=" + retVal);
|
if (DBG) log("rspUpdateLinkPropertiesState: retVal=" + retVal);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update link properties in the data connection
|
* Update link properties in the data connection
|
||||||
*
|
*
|
||||||
* @return true if link property has been updated. false otherwise.
|
* @return the removed and added addresses.
|
||||||
*/
|
*/
|
||||||
public LinkPropertyChangeAction updateLinkPropertiesDataCallStateSync(DataCallState newState) {
|
public UpdateLinkPropertyResult updateLinkPropertiesDataCallStateSync(DataCallState newState) {
|
||||||
Message response =
|
Message response =
|
||||||
sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
|
sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
|
||||||
if ((response != null) &&
|
if ((response != null) &&
|
||||||
@@ -329,7 +331,7 @@ public class DataConnectionAc extends AsyncChannel {
|
|||||||
return rspUpdateLinkPropertiesDataCallState(response);
|
return rspUpdateLinkPropertiesDataCallState(response);
|
||||||
} else {
|
} else {
|
||||||
log("getLinkProperties error response=" + response);
|
log("getLinkProperties error response=" + response);
|
||||||
return LinkPropertyChangeAction.NONE;
|
return new UpdateLinkPropertyResult(new LinkProperties());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ import android.content.IntentFilter;
|
|||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.LinkAddress;
|
||||||
|
import android.net.LinkProperties.CompareAddressesResult;
|
||||||
|
import android.net.NetworkUtils;
|
||||||
import android.net.ProxyProperties;
|
import android.net.ProxyProperties;
|
||||||
import android.net.TrafficStats;
|
import android.net.TrafficStats;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -53,6 +56,7 @@ import com.android.internal.telephony.ApnContext;
|
|||||||
import com.android.internal.telephony.ApnSetting;
|
import com.android.internal.telephony.ApnSetting;
|
||||||
import com.android.internal.telephony.DataCallState;
|
import com.android.internal.telephony.DataCallState;
|
||||||
import com.android.internal.telephony.DataConnection;
|
import com.android.internal.telephony.DataConnection;
|
||||||
|
import com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
|
||||||
import com.android.internal.telephony.DataConnectionAc;
|
import com.android.internal.telephony.DataConnectionAc;
|
||||||
import com.android.internal.telephony.DataConnectionTracker;
|
import com.android.internal.telephony.DataConnectionTracker;
|
||||||
import com.android.internal.telephony.Phone;
|
import com.android.internal.telephony.Phone;
|
||||||
@@ -1037,7 +1041,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param dcacs Collection of DataConnectionAc reported from RIL.
|
* @param dcacs Collection of DataConnectionAc reported from RIL.
|
||||||
* @return List of ApnContext whihc is connected, but does not present in
|
* @return List of ApnContext which is connected, but is not present in
|
||||||
* data connection list reported from RIL.
|
* data connection list reported from RIL.
|
||||||
*/
|
*/
|
||||||
private List<ApnContext> findApnContextToClean(Collection<DataConnectionAc> dcacs) {
|
private List<ApnContext> findApnContextToClean(Collection<DataConnectionAc> dcacs) {
|
||||||
@@ -1091,32 +1095,30 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size());
|
if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size());
|
||||||
|
|
||||||
// Create a hash map to store the dataCallState of each DataConnectionAc
|
// Create a hash map to store the dataCallState of each DataConnectionAc
|
||||||
// TODO: Depends on how frequent the DATA_CALL_LIST got updated,
|
HashMap<DataCallState, DataConnectionAc> dataCallStateToDcac;
|
||||||
// may cache response to reduce comparison.
|
dataCallStateToDcac = new HashMap<DataCallState, DataConnectionAc>();
|
||||||
HashMap<DataCallState, DataConnectionAc> response;
|
|
||||||
response = new HashMap<DataCallState, DataConnectionAc>();
|
|
||||||
for (DataCallState dataCallState : dataCallStates) {
|
for (DataCallState dataCallState : dataCallStates) {
|
||||||
DataConnectionAc dcac = findDataConnectionAcByCid(dataCallState.cid);
|
DataConnectionAc dcac = findDataConnectionAcByCid(dataCallState.cid);
|
||||||
|
|
||||||
if (dcac != null) response.put(dataCallState, dcac);
|
if (dcac != null) dataCallStateToDcac.put(dataCallState, dcac);
|
||||||
}
|
}
|
||||||
|
|
||||||
// step1: Find a list of "connected" APN which does not have reference to
|
// A list of apns to cleanup, those that aren't in the list we know we have to cleanup
|
||||||
// calls listed in the Data Call List.
|
List<ApnContext> apnsToCleanup = findApnContextToClean(dataCallStateToDcac.values());
|
||||||
List<ApnContext> apnsToClear = findApnContextToClean(response.values());
|
|
||||||
|
|
||||||
// step2: Check status of each calls in Data Call List.
|
// Find which connections have changed state and send a notification or cleanup
|
||||||
// Collect list of ApnContext associated with the data call if the link
|
|
||||||
// has to be cleared.
|
|
||||||
for (DataCallState newState : dataCallStates) {
|
for (DataCallState newState : dataCallStates) {
|
||||||
DataConnectionAc dcac = response.get(newState);
|
DataConnectionAc dcac = dataCallStateToDcac.get(newState);
|
||||||
|
|
||||||
// no associated DataConnection found. Ignore.
|
if (dcac == null) {
|
||||||
if (dcac == null) continue;
|
loge("onDataStateChanged(ar): No associated DataConnection ignore");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The list of apn's associated with this DataConnection
|
||||||
Collection<ApnContext> apns = dcac.getApnListSync();
|
Collection<ApnContext> apns = dcac.getApnListSync();
|
||||||
|
|
||||||
// filter out ApnContext with "Connected/Connecting" state.
|
// Find which ApnContexts of this DC are in the "Connected/Connecting" state.
|
||||||
ArrayList<ApnContext> connectedApns = new ArrayList<ApnContext>();
|
ArrayList<ApnContext> connectedApns = new ArrayList<ApnContext>();
|
||||||
for (ApnContext apnContext : apns) {
|
for (ApnContext apnContext : apns) {
|
||||||
if (apnContext.getState() == State.CONNECTED ||
|
if (apnContext.getState() == State.CONNECTED ||
|
||||||
@@ -1125,67 +1127,86 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
connectedApns.add(apnContext);
|
connectedApns.add(apnContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (connectedApns.size() == 0) {
|
||||||
// No "Connected" ApnContext associated with this CID. Ignore.
|
if (DBG) log("onDataStateChanged(ar): no connected apns");
|
||||||
if (connectedApns.isEmpty()) {
|
} else {
|
||||||
continue;
|
// Determine if the connection/apnContext should be cleaned up
|
||||||
}
|
// or just a notification should be sent out.
|
||||||
|
if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid
|
||||||
if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid
|
+ " newState=" + newState.toString());
|
||||||
+ " newState=" + newState.toString());
|
if (newState.active == 0) {
|
||||||
if (newState.active != 0) {
|
if (DBG) {
|
||||||
boolean resetConnection;
|
log("onDataStateChanged(ar): inactive, cleanup apns=" + connectedApns);
|
||||||
switch (dcac.updateLinkPropertiesDataCallStateSync(newState)) {
|
|
||||||
case NONE:
|
|
||||||
if (DBG) log("onDataStateChanged(ar): Found but no change, skip");
|
|
||||||
resetConnection = false;
|
|
||||||
break;
|
|
||||||
case CHANGED:
|
|
||||||
for (ApnContext apnContext : connectedApns) {
|
|
||||||
if (DBG) log("onDataStateChanged(ar): Found and changed, notify (" +
|
|
||||||
apnContext.toString() + ")");
|
|
||||||
mPhone.notifyDataConnection(Phone.REASON_LINK_PROPERTIES_CHANGED,
|
|
||||||
apnContext.getApnType());
|
|
||||||
}
|
}
|
||||||
// Temporary hack, at this time a transition from CDMA -> Global
|
apnsToCleanup.addAll(connectedApns);
|
||||||
// fails so we'll hope for the best and not reset the connection.
|
} else {
|
||||||
// @see bug/4455071
|
// Its active so update the DataConnections link properties
|
||||||
if (SystemProperties.getBoolean("telephony.ignore-state-changes",
|
UpdateLinkPropertyResult result =
|
||||||
true)) {
|
dcac.updateLinkPropertiesDataCallStateSync(newState);
|
||||||
log("onDataStateChanged(ar): STOPSHIP don't reset, continue");
|
if (result.oldLp.equals(result.newLp)) {
|
||||||
resetConnection = false;
|
if (DBG) log("onDataStateChanged(ar): no change");
|
||||||
} else {
|
} else {
|
||||||
// Things changed so reset connection, when hack is removed
|
if (result.oldLp.isIdenticalInterfaceName(result.newLp)) {
|
||||||
// this is the normal path.
|
if (! result.oldLp.isIdenticalDnses(result.newLp) ||
|
||||||
log("onDataStateChanged(ar): changed so resetting connection");
|
! result.oldLp.isIdenticalRoutes(result.newLp) ||
|
||||||
resetConnection = true;
|
! result.oldLp.isIdenticalHttpProxy(result.newLp) ||
|
||||||
|
! result.oldLp.isIdenticalAddresses(result.newLp)) {
|
||||||
|
// If the same address type was removed and added we need to cleanup
|
||||||
|
CompareAddressesResult car =
|
||||||
|
result.oldLp.compareAddresses(result.newLp);
|
||||||
|
boolean needToClean = false;
|
||||||
|
for (LinkAddress added : car.added) {
|
||||||
|
for (LinkAddress removed : car.removed) {
|
||||||
|
if (NetworkUtils.addressTypeMatches(removed.getAddress(),
|
||||||
|
added.getAddress())) {
|
||||||
|
needToClean = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needToClean) {
|
||||||
|
if (DBG) {
|
||||||
|
log("onDataStateChanged(ar): addr change, cleanup apns=" +
|
||||||
|
connectedApns);
|
||||||
|
}
|
||||||
|
apnsToCleanup.addAll(connectedApns);
|
||||||
|
} else {
|
||||||
|
if (DBG) log("onDataStateChanged(ar): simple change");
|
||||||
|
for (ApnContext apnContext : connectedApns) {
|
||||||
|
mPhone.notifyDataConnection(
|
||||||
|
Phone.REASON_LINK_PROPERTIES_CHANGED,
|
||||||
|
apnContext.getApnType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (DBG) {
|
||||||
|
log("onDataStateChanged(ar): no changes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (DBG) {
|
||||||
|
log("onDataStateChanged(ar): interface change, cleanup apns="
|
||||||
|
+ connectedApns);
|
||||||
|
}
|
||||||
|
apnsToCleanup.addAll(connectedApns);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case RESET:
|
|
||||||
default:
|
|
||||||
if (DBG) log("onDataStateChanged(ar): an error, reset connection");
|
|
||||||
resetConnection = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (resetConnection == false) continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DBG) log("onDataStateChanged(ar): reset connection.");
|
|
||||||
|
|
||||||
apnsToClear.addAll(connectedApns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// step3: Clear apn connection if applicable.
|
if (apnsToCleanup.size() != 0) {
|
||||||
if (!apnsToClear.isEmpty()) {
|
|
||||||
// Add an event log when the network drops PDP
|
// Add an event log when the network drops PDP
|
||||||
int cid = getCellLocationId();
|
int cid = getCellLocationId();
|
||||||
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
|
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
|
||||||
TelephonyManager.getDefault().getNetworkType());
|
TelephonyManager.getDefault().getNetworkType());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ApnContext apnContext : apnsToClear) {
|
// Cleanup those dropped connections
|
||||||
|
for (ApnContext apnContext : apnsToCleanup) {
|
||||||
cleanUpConnection(true, apnContext);
|
cleanUpConnection(true, apnContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DBG) log("onDataStateChanged(ar): X");
|
if (DBG) log("onDataStateChanged(ar): X");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user