Merge "Reset connection while data state changed." into honeycomb-LTE

This commit is contained in:
Wink Saville
2011-05-19 11:25:45 -07:00
committed by Android (Google) Code Review
5 changed files with 117 additions and 119 deletions

View File

@@ -68,7 +68,8 @@ public class LinkProperties implements Parcelable {
mLinkAddresses = source.getLinkAddresses(); mLinkAddresses = source.getLinkAddresses();
mDnses = source.getDnses(); mDnses = source.getDnses();
mRoutes = source.getRoutes(); mRoutes = source.getRoutes();
mHttpProxy = new ProxyProperties(source.getHttpProxy()); mHttpProxy = (source.getHttpProxy() == null) ?
null : new ProxyProperties(source.getHttpProxy());
} }
} }

View File

@@ -140,6 +140,33 @@ public class RouteInfo implements Parcelable {
} }
} }
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof RouteInfo)) return false;
RouteInfo target = (RouteInfo) obj;
boolean sameDestination = ( mDestination == null) ?
target.getDestination() == null
: mDestination.equals(target.getDestination());
boolean sameAddress = (mGateway == null) ?
target.getGateway() == null
: mGateway.equals(target.getGateway());
return sameDestination && sameAddress
&& mIsDefault == target.mIsDefault;
}
@Override
public int hashCode() {
return (mDestination == null ? 0 : mDestination.hashCode())
+ (mGateway == null ? 0 :mGateway.hashCode())
+ (mIsDefault ? 3 : 7);
}
public static final Creator<RouteInfo> CREATOR = public static final Creator<RouteInfo> CREATOR =
new Creator<RouteInfo>() { new Creator<RouteInfo>() {
public RouteInfo createFromParcel(Parcel in) { public RouteInfo createFromParcel(Parcel in) {

View File

@@ -85,12 +85,10 @@ public class ApnContext {
public synchronized DataConnectionAc getDataConnectionAc() { public synchronized DataConnectionAc getDataConnectionAc() {
log("getDataConnectionAc dcac=" + mDataConnectionAc);
return mDataConnectionAc; return mDataConnectionAc;
} }
public synchronized void setDataConnectionAc(DataConnectionAc dcac) { public synchronized void setDataConnectionAc(DataConnectionAc dcac) {
log("setDataConnectionAc dcac=" + dcac);
mDataConnectionAc = dcac; mDataConnectionAc = dcac;
} }

View File

@@ -511,14 +511,14 @@ public abstract class DataConnection extends StateMachine {
log("onSetupConnectionCompleted received DataCallState: " + response); log("onSetupConnectionCompleted received DataCallState: " + response);
cid = response.cid; cid = response.cid;
// set link properties based on data call response // set link properties based on data call response
result = response.setLinkProperties(mLinkProperties, result = setLinkProperties(response, mLinkProperties);
isOkToUseSystemPropertyDns(response));
} }
return result; return result;
} }
private boolean isOkToUseSystemPropertyDns(DataCallState response) { private DataCallState.SetupResult setLinkProperties(DataCallState response,
LinkProperties lp) {
// Check if system property dns usable // Check if system property dns usable
boolean okToUseSystemPropertyDns = false; boolean okToUseSystemPropertyDns = false;
String propertyPrefix = "net." + response.ifname + "."; String propertyPrefix = "net." + response.ifname + ".";
@@ -526,7 +526,9 @@ public abstract class DataConnection extends StateMachine {
dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1"); dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2"); dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
okToUseSystemPropertyDns = isDnsOk(dnsServers); okToUseSystemPropertyDns = isDnsOk(dnsServers);
return okToUseSystemPropertyDns;
// set link properties based on data call response
return response.setLinkProperties(lp, okToUseSystemPropertyDns);
} }
private boolean updateLinkProperty(DataCallState newState) { private boolean updateLinkProperty(DataCallState newState) {
@@ -535,29 +537,25 @@ public abstract class DataConnection extends StateMachine {
if (newState == null) return changed; if (newState == null) return changed;
DataCallState.SetupResult result; DataCallState.SetupResult result;
LinkProperties linkProperties = new LinkProperties(); LinkProperties newLp = new LinkProperties();
// set link properties based on data call response // set link properties based on data call response
result = newState.setLinkProperties(linkProperties, result = setLinkProperties(newState, newLp);
isOkToUseSystemPropertyDns(newState));
if (result != DataCallState.SetupResult.SUCCESS) { if (result != DataCallState.SetupResult.SUCCESS) {
log("updateLinkProperty failed : " + result); if (DBG) log("UpdateLinkProperty failed : " + result);
return changed; return changed;
} }
// copy HTTP proxy as it is not part DataCallState.
newLp.setHttpProxy(mLinkProperties.getHttpProxy());
if (mLinkProperties != null) { if (DBG) log("old LP=" + mLinkProperties);
// Before comparison, copy HTTP proxy from the original if (DBG) log("new LP=" + newLp);
// as it is not part DataCallState.
linkProperties.setHttpProxy(mLinkProperties.getHttpProxy()); if (mLinkProperties == null || !mLinkProperties.equals(newLp)) {
if (!mLinkProperties.equals(linkProperties)) { mLinkProperties = newLp;
mLinkProperties = linkProperties;
changed = true;
}
} else {
mLinkProperties = linkProperties;
changed = true; changed = true;
} }
return changed; return changed;
} }
@@ -635,8 +633,9 @@ public abstract class DataConnection extends StateMachine {
DataCallState newState = (DataCallState) msg.obj; DataCallState newState = (DataCallState) msg.obj;
int updated = updateLinkProperty(newState) ? 1 : 0; int updated = updateLinkProperty(newState) ? 1 : 0;
if (DBG) { if (DBG) {
log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE updated=" + updated + log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE updated="
" newState=" + newState); + (updated == 1)
+ " newState=" + newState);
} }
mAc.replyToMessage(msg, mAc.replyToMessage(msg,
DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,

View File

@@ -970,32 +970,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return true; return true;
} }
private boolean dataCallStatesHasCID (ArrayList<DataCallState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if (states.get(i).cid == cid) return true;
}
return false;
}
private boolean dataCallStatesHasActiveCID (ArrayList<DataCallState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if ((states.get(i).cid == cid) && (states.get(i).active != 0)) {
return true;
}
}
return false;
}
private DataCallState findDataCallStateByCID (ArrayList<DataCallState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if (states.get(i).cid == cid) {
return states.get(i);
}
}
return null;
}
/** /**
* Handles changes to the APN database. * Handles changes to the APN database.
*/ */
@@ -1023,15 +997,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
} }
/** /**
* @param explicitPoll if true, indicates that *we* polled for this * @param ar is the result of RIL_REQUEST_DATA_CALL_LIST
* update while state == CONNECTED rather than having it delivered * or RIL_UNSOL_DATA_CALL_LIST_CHANGED
* via an unsolicited response (which could have happened at any
* previous state
*/ */
private void onDataStateChanged (AsyncResult ar) { private void onDataStateChanged (AsyncResult ar) {
ArrayList<DataCallState> dataCallStates; ArrayList<DataCallState> dataCallStates;
if (DBG) log("onDataStateChanged(ar) E"); if (DBG) log("onDataStateChanged(ar): E");
dataCallStates = (ArrayList<DataCallState>)(ar.result); dataCallStates = (ArrayList<DataCallState>)(ar.result);
if (ar.exception != null) { if (ar.exception != null) {
@@ -1042,78 +1014,79 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return; return;
} }
// Create a hash map to store the dataCallState of each call id
// TODO: Depends on how frequent the DATA_CALL_LIST got updated,
// may cache response to reduce comparison.
HashMap<Integer, DataCallState> response;
response = new HashMap<Integer, DataCallState>();
if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size());
for (DataCallState dc : dataCallStates) {
response.put(dc.cid, dc);
if (DBG) log("onDataStateChanged(ar): " + dc.cid + ": " + dc.toString());
}
// For each connected apn, check if there is a matched active
// data call state, which has the same link properties.
if (DBG) log(" ApnContext size=" + mApnContexts.values().size());
for (ApnContext apnContext : mApnContexts.values()) { for (ApnContext apnContext : mApnContexts.values()) {
onDataStateChanged(dataCallStates, apnContext); if (DBG){
} log("onDataStateChanged(ar): " + apnContext.toString());
if (DBG) log("onDataStateChanged(ar) X"); if (apnContext.getDataConnection() != null) {
} log("onDataStateChanged(ar): " + apnContext.getDataConnection().toString());
}
private void onDataStateChanged (ArrayList<DataCallState> dataCallStates, }
ApnContext apnContext) {
if (DBG) log("onDataStateChanged(dataCallState, apnContext): apnContext=" + apnContext);
if (apnContext == null) {
// Should not happen
if (DBG) log("onDataStateChanged(dataCallState, apnContext): ignore apnContext=null");
return;
}
if (apnContext.getState() == State.CONNECTED) {
// The way things are supposed to work, the PDP list
// should not contain the CID after it disconnects.
// However, the way things really work, sometimes the PDP
// context is still listed with active = false, which
// makes it hard to distinguish an activating context from
// an activated-and-then deactivated one.
DataConnectionAc dcac = apnContext.getDataConnectionAc(); DataConnectionAc dcac = apnContext.getDataConnectionAc();
if (dcac == null) { if (dcac == null) {
if (DBG) log("onDataStateChanged(dataCallState, apnContext): dcac==null BAD NEWS"); continue;
return;
} }
int cid = dcac.getCidSync(); int connectionId = dcac.getCidSync();
if (!dataCallStatesHasCID(dataCallStates, cid)) {
// It looks like the PDP context has deactivated.
// Tear everything down and try to reconnect.
if (DBG) { if (apnContext.getState() == State.CONNECTED) {
log("onDataStateChanged(dataCallStates,apnContext) " + // The way things are supposed to work, the PDP list
"PDP connection has dropped. Reconnecting"); // should not contain the CID after it disconnects.
} // However, the way things really work, sometimes the PDP
// Add an event log when the network drops PDP // context is still listed with active = false, which
int cellLocationId = getCellLocationId(); // makes it hard to distinguish an activating context from
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cellLocationId, // an activated-and-then de-activated one.
TelephonyManager.getDefault().getNetworkType()); if (response.containsKey(connectionId)) {
DataCallState newState = response.get(connectionId);
cleanUpConnection(true, apnContext); if (DBG) log("onDataStateChanged(ar): Found ConnId=" + connectionId
} else if (!dataCallStatesHasActiveCID(dataCallStates, + " newState=" + newState.toString());
apnContext.getDataConnectionAc().getCidSync())) { if (newState.active != 0) {
boolean changed
if (DBG) { = dcac.updateLinkPropertiesDataCallStateSync(newState);
log("onDataStateChanged(dataCallStates,apnContext) " + if (changed) {
"PDP connection has dropped (active=false case). Reconnecting"); if (DBG) log("onDataStateChanged(ar): Found and changed, notify");
} mPhone.notifyDataConnection(Phone.REASON_LINK_PROPERTIES_CHANGED,
apnContext.getApnType());
// Log the network drop on the event log. // Temporary hack, if false we'll reset connections and at this
int cellLocationId = getCellLocationId(); // time a transition from CDMA -> Global fails. The DEACTIVATE
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cellLocationId, // fails with a GENERIC_FAILURE and the VZWINTERNET connection is
TelephonyManager.getDefault().getNetworkType()); // never setup. @see bug/
if (SystemProperties.getBoolean("telephony.ignore-state-changes",
cleanUpConnection(true, apnContext); true)) {
} else { log("onDataStateChanged(ar): STOPSHIP don't reset, continue");
// Here, data call list has active cid for given ApnContext. continue;
// Check if link property has been updated. }
DataCallState state = findDataCallStateByCID(dataCallStates, } else {
apnContext.getDataConnectionAc().getCidSync()); if (DBG) log("onDataStateChanged(ar): Found but no change, skip");
continue;
if ((dcac != null) && (state != null)){ }
if (dcac.updateLinkPropertiesDataCallStateSync(state)) {
// notify data change for this apn
mPhone.notifyDataConnection(Phone.REASON_LINK_PROPERTIES_CHANGED,
apnContext.getApnType());
} }
} }
if (DBG) log("onDataStateChanged(ar): reset connection.");
// Add an event log when the network drops PDP
int cid = getCellLocationId();
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
TelephonyManager.getDefault().getNetworkType());
cleanUpConnection(true, apnContext);
} }
} }
if (DBG) log("onDataStateChanged(ar): X");
} }
private void notifyDefaultData(ApnContext apnContext) { private void notifyDefaultData(ApnContext apnContext) {
@@ -2143,7 +2116,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
@Override @Override
protected void log(String s) { protected void log(String s) {
Log.d(LOG_TAG, "[GsmDCT] " + s); Log.d(LOG_TAG, "[GsmDCT] "+ s);
} }
@Override @Override