am 3810361e: am 6d1d16c3: Merge "Remove STOPSHIP but allow seamless Handoff when possible." into honeycomb-LTE
* commit '3810361e4a3e93d3c8a10aaeec54f65dfcc2d03d':
Remove STOPSHIP but allow seamless Handoff when possible.
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 19894a0..f2f0e82 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -52,11 +52,26 @@
public class LinkProperties implements Parcelable {
String mIfaceName;
- private Collection<LinkAddress> mLinkAddresses;
- private Collection<InetAddress> mDnses;
- private Collection<RouteInfo> mRoutes;
+ private Collection<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
+ private Collection<InetAddress> mDnses = new ArrayList<InetAddress>();
+ private Collection<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
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() {
clear();
}
@@ -121,9 +136,9 @@
public void clear() {
mIfaceName = null;
- mLinkAddresses = new ArrayList<LinkAddress>();
- mDnses = new ArrayList<InetAddress>();
- mRoutes = new ArrayList<RouteInfo>();
+ mLinkAddresses.clear();
+ mDnses.clear();
+ mRoutes.clear();
mHttpProxy = null;
}
@@ -155,6 +170,63 @@
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
/**
@@ -176,30 +248,41 @@
if (!(obj instanceof LinkProperties)) return false;
- boolean sameAddresses;
- boolean sameDnses;
- boolean sameRoutes;
-
LinkProperties target = (LinkProperties) obj;
- Collection<InetAddress> targetAddresses = target.getAddresses();
- Collection<InetAddress> sourceAddresses = getAddresses();
- sameAddresses = (sourceAddresses.size() == targetAddresses.size()) ?
- sourceAddresses.containsAll(targetAddresses) : false;
+ return isIdenticalInterfaceName(target) &&
+ isIdenticalAddresses(target) &&
+ isIdenticalDnses(target) &&
+ isIdenticalRoutes(target) &&
+ isIdenticalHttpProxy(target);
+ }
- Collection<InetAddress> targetDnses = target.getDnses();
- sameDnses = (mDnses.size() == targetDnses.size()) ?
- mDnses.containsAll(targetDnses) : false;
-
- Collection<RouteInfo> targetRoutes = target.getRoutes();
- sameRoutes = (mRoutes.size() == targetRoutes.size()) ?
- mRoutes.containsAll(targetRoutes) : false;
-
- return
- sameAddresses && sameDnses && sameRoutes
- && TextUtils.equals(getInterfaceName(), target.getInterfaceName())
- && (getHttpProxy() == null ? target.getHttpProxy() == null :
- getHttpProxy().equals(target.getHttpProxy()));
+ /**
+ * Return two lists, a list of addresses that would be removed from
+ * mLinkAddresses and a list of addresses that would be added to
+ * mLinkAddress which would then result in target and mLinkAddresses
+ * being the same list.
+ *
+ * @param target is a new list of addresses
+ * @return the removed and added lists.
+ */
+ public CompareAddressesResult compareAddresses(LinkProperties target) {
+ /*
+ * Duplicate the LinkAddresses into removed, we will be removing
+ * 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
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 41450d2..68cdeee 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -34,6 +34,7 @@
import android.net.INetworkPolicyListener;
import android.net.INetworkPolicyManager;
import android.net.LinkProperties;
+import android.net.LinkProperties.CompareAddressesResult;
import android.net.MobileDataStateTracker;
import android.net.NetworkConfig;
import android.net.NetworkInfo;
@@ -76,6 +77,7 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
@@ -92,6 +94,7 @@
public class ConnectivityService extends IConnectivityManager.Stub {
private static final boolean DBG = true;
+ private static final boolean VDBG = true;
private static final String TAG = "ConnectivityService";
private static final boolean LOGD_RULES = false;
@@ -126,6 +129,11 @@
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
* used both as a refcount and for per-PID DNS selection
*/
@@ -332,6 +340,7 @@
mNetTrackers = new NetworkStateTracker[
ConnectivityManager.MAX_NETWORK_TYPE+1];
+ mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
mNetworkPreference = getPersistedNetworkPreference();
@@ -468,6 +477,7 @@
mNetConfigs[netType].radio);
continue;
}
+ mCurrentLinkProperties[netType] = mNetTrackers[netType].getLinkProperties();
}
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
@@ -1563,6 +1573,8 @@
* right routing table entries exist.
*/
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
* will allow it's DNS servers to be accessed.
@@ -1570,6 +1582,45 @@
handleDnsConfigurationChange(netType);
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()) {
handleApplyDefaultProxy(netType);
addDefaultRoute(mNetTrackers[netType]);
@@ -1597,15 +1648,13 @@
}
}
- if (doReset) {
+ if (doReset || resetMask != 0) {
LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
if (linkProperties != null) {
String iface = linkProperties.getInterfaceName();
if (TextUtils.isEmpty(iface) == false) {
- if (DBG) {
- log("resetConnections(" + iface + ", NetworkUtils.RESET_ALL_ADDRESSES)");
- }
- NetworkUtils.resetConnections(iface, NetworkUtils.RESET_ALL_ADDRESSES);
+ if (DBG) log("resetConnections(" + iface + ", " + resetMask + ")");
+ NetworkUtils.resetConnections(iface, resetMask);
}
}
}
diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
index fba3184..a69ce8b 100644
--- a/telephony/java/com/android/internal/telephony/DataCallState.java
+++ b/telephony/java/com/android/internal/telephony/DataCallState.java
@@ -52,7 +52,7 @@
/**
* Class returned by onSetupConnectionCompleted.
*/
- protected enum SetupResult {
+ public enum SetupResult {
SUCCESS,
ERR_BadCommand,
ERR_UnacceptableParameter,
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 5c84fdc..1bba8e3 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -17,30 +17,25 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.DataCallState.SetupResult;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import android.app.PendingIntent;
-import android.net.LinkAddress;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
-import android.net.NetworkUtils;
+import android.net.LinkProperties.CompareAddressesResult;
import android.net.ProxyProperties;
import android.os.AsyncResult;
-import android.os.Bundle;
import android.os.Message;
-import android.os.Parcel;
-import android.os.Parcelable;
import android.os.SystemProperties;
import android.text.TextUtils;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* {@hide}
@@ -497,8 +492,7 @@
} else {
if (DBG) log("onSetupConnectionCompleted received DataCallState: " + response);
cid = response.cid;
- // set link properties based on data call response
- result = setLinkProperties(response, mLinkProperties);
+ result = updateLinkProperty(response).setupResult;
}
return result;
@@ -527,48 +521,41 @@
return response.setLinkProperties(lp, okToUseSystemPropertyDns);
}
- private DataConnectionAc.LinkPropertyChangeAction updateLinkProperty(
- DataCallState newState) {
- DataConnectionAc.LinkPropertyChangeAction changed =
- DataConnectionAc.LinkPropertyChangeAction.NONE;
+ public static class UpdateLinkPropertyResult {
+ public DataCallState.SetupResult setupResult = DataCallState.SetupResult.SUCCESS;
+ public LinkProperties oldLp;
+ 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;
- LinkProperties newLp = new LinkProperties();
+ if (newState == null) return result;
+
+ DataCallState.SetupResult setupResult;
+ result.newLp = new LinkProperties();
// set link properties based on data call response
- result = setLinkProperties(newState, newLp);
- if (result != DataCallState.SetupResult.SUCCESS) {
- if (DBG) log("UpdateLinkProperty failed : " + result);
- return changed;
+ result.setupResult = setLinkProperties(newState, result.newLp);
+ if (result.setupResult != DataCallState.SetupResult.SUCCESS) {
+ if (DBG) log("updateLinkProperty failed : " + result.setupResult);
+ return result;
}
// 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) log("new LP=" + newLp);
-
- // Check consistency of link address. Currently we expect
- // 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;
- }
- }
+ if (DBG && (! result.oldLp.equals(result.newLp))) {
+ if (DBG) log("updateLinkProperty old != new");
+ if (VDBG) log("updateLinkProperty old LP=" + result.oldLp);
+ if (VDBG) log("updateLinkProperty new LP=" + result.newLp);
}
+ mLinkProperties = result.newLp;
- if (mLinkProperties == null || !mLinkProperties.equals(newLp)) {
- mLinkProperties = newLp;
- changed = DataConnectionAc.LinkPropertyChangeAction.CHANGED;
- }
-
- return changed;
+ return result;
}
/**
@@ -643,14 +630,15 @@
}
case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
DataCallState newState = (DataCallState) msg.obj;
- DataConnectionAc.LinkPropertyChangeAction action = updateLinkProperty(newState);
+ UpdateLinkPropertyResult result =
+ updateLinkProperty(newState);
if (VDBG) {
- log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE action="
- + action + " newState=" + newState);
+ log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE result="
+ + result + " newState=" + newState);
}
mAc.replyToMessage(msg,
DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,
- action.ordinal());
+ result);
break;
}
case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {
@@ -688,7 +676,7 @@
case DataConnectionAc.REQ_GET_APNCONTEXT_LIST: {
if (VDBG) log("REQ_GET_APNCONTEXT_LIST num in list=" + mApnList.size());
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNCONTEXT_LIST,
- new ArrayList(mApnList));
+ new ArrayList<ApnContext>(mApnList));
break;
}
case DataConnectionAc.REQ_SET_RECONNECT_INTENT: {
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionAc.java b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
index 309dbed..9e185e5 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionAc.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
@@ -16,12 +16,14 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import android.app.PendingIntent;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
+import android.net.LinkProperties.CompareAddressesResult;
import android.net.ProxyProperties;
import android.os.Message;
@@ -310,18 +312,18 @@
if (DBG) log("reqUpdateLinkPropertiesDataCallState");
}
- public LinkPropertyChangeAction rspUpdateLinkPropertiesDataCallState(Message response) {
- LinkPropertyChangeAction retVal = LinkPropertyChangeAction.fromInt(response.arg1);
- if (DBG) log("rspUpdateLinkPropertiesState=" + retVal);
+ public UpdateLinkPropertyResult rspUpdateLinkPropertiesDataCallState(Message response) {
+ UpdateLinkPropertyResult retVal = (UpdateLinkPropertyResult)response.obj;
+ if (DBG) log("rspUpdateLinkPropertiesState: retVal=" + retVal);
return retVal;
}
/**
* 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 =
sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
if ((response != null) &&
@@ -329,7 +331,7 @@
return rspUpdateLinkPropertiesDataCallState(response);
} else {
log("getLinkProperties error response=" + response);
- return LinkPropertyChangeAction.NONE;
+ return new UpdateLinkPropertyResult(new LinkProperties());
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index df5898b..bf964b7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -26,6 +26,9 @@
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.ConnectivityManager;
+import android.net.LinkAddress;
+import android.net.LinkProperties.CompareAddressesResult;
+import android.net.NetworkUtils;
import android.net.ProxyProperties;
import android.net.TrafficStats;
import android.net.Uri;
@@ -53,6 +56,7 @@
import com.android.internal.telephony.ApnSetting;
import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.DataConnection;
+import com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
import com.android.internal.telephony.DataConnectionAc;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.Phone;
@@ -1037,7 +1041,7 @@
/**
* @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.
*/
private List<ApnContext> findApnContextToClean(Collection<DataConnectionAc> dcacs) {
@@ -1091,32 +1095,30 @@
if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size());
// Create a hash map to store the dataCallState of each DataConnectionAc
- // TODO: Depends on how frequent the DATA_CALL_LIST got updated,
- // may cache response to reduce comparison.
- HashMap<DataCallState, DataConnectionAc> response;
- response = new HashMap<DataCallState, DataConnectionAc>();
+ HashMap<DataCallState, DataConnectionAc> dataCallStateToDcac;
+ dataCallStateToDcac = new HashMap<DataCallState, DataConnectionAc>();
for (DataCallState dataCallState : dataCallStates) {
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
- // calls listed in the Data Call List.
- List<ApnContext> apnsToClear = findApnContextToClean(response.values());
+ // A list of apns to cleanup, those that aren't in the list we know we have to cleanup
+ List<ApnContext> apnsToCleanup = findApnContextToClean(dataCallStateToDcac.values());
- // step2: Check status of each calls in Data Call List.
- // Collect list of ApnContext associated with the data call if the link
- // has to be cleared.
+ // Find which connections have changed state and send a notification or cleanup
for (DataCallState newState : dataCallStates) {
- DataConnectionAc dcac = response.get(newState);
+ DataConnectionAc dcac = dataCallStateToDcac.get(newState);
- // no associated DataConnection found. Ignore.
- if (dcac == null) continue;
+ if (dcac == null) {
+ loge("onDataStateChanged(ar): No associated DataConnection ignore");
+ continue;
+ }
+ // The list of apn's associated with this DataConnection
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>();
for (ApnContext apnContext : apns) {
if (apnContext.getState() == State.CONNECTED ||
@@ -1125,67 +1127,86 @@
connectedApns.add(apnContext);
}
}
-
- // No "Connected" ApnContext associated with this CID. Ignore.
- if (connectedApns.isEmpty()) {
- continue;
- }
-
- if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid
- + " newState=" + newState.toString());
- if (newState.active != 0) {
- boolean resetConnection;
- 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());
+ if (connectedApns.size() == 0) {
+ if (DBG) log("onDataStateChanged(ar): no connected apns");
+ } else {
+ // 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
+ + " newState=" + newState.toString());
+ if (newState.active == 0) {
+ if (DBG) {
+ log("onDataStateChanged(ar): inactive, cleanup apns=" + connectedApns);
}
- // Temporary hack, at this time a transition from CDMA -> Global
- // fails so we'll hope for the best and not reset the connection.
- // @see bug/4455071
- if (SystemProperties.getBoolean("telephony.ignore-state-changes",
- true)) {
- log("onDataStateChanged(ar): STOPSHIP don't reset, continue");
- resetConnection = false;
+ apnsToCleanup.addAll(connectedApns);
+ } else {
+ // Its active so update the DataConnections link properties
+ UpdateLinkPropertyResult result =
+ dcac.updateLinkPropertiesDataCallStateSync(newState);
+ if (result.oldLp.equals(result.newLp)) {
+ if (DBG) log("onDataStateChanged(ar): no change");
} else {
- // Things changed so reset connection, when hack is removed
- // this is the normal path.
- log("onDataStateChanged(ar): changed so resetting connection");
- resetConnection = true;
+ if (result.oldLp.isIdenticalInterfaceName(result.newLp)) {
+ if (! result.oldLp.isIdenticalDnses(result.newLp) ||
+ ! result.oldLp.isIdenticalRoutes(result.newLp) ||
+ ! 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 (!apnsToClear.isEmpty()) {
+ if (apnsToCleanup.size() != 0) {
// Add an event log when the network drops PDP
int cid = getCellLocationId();
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
TelephonyManager.getDefault().getNetworkType());
}
- for (ApnContext apnContext : apnsToClear) {
+ // Cleanup those dropped connections
+ for (ApnContext apnContext : apnsToCleanup) {
cleanUpConnection(true, apnContext);
}
+
if (DBG) log("onDataStateChanged(ar): X");
}