Merge "Reset connection while data state changed." into honeycomb-LTE
This commit is contained in:
@@ -68,7 +68,8 @@ public class LinkProperties implements Parcelable {
|
||||
mLinkAddresses = source.getLinkAddresses();
|
||||
mDnses = source.getDnses();
|
||||
mRoutes = source.getRoutes();
|
||||
mHttpProxy = new ProxyProperties(source.getHttpProxy());
|
||||
mHttpProxy = (source.getHttpProxy() == null) ?
|
||||
null : new ProxyProperties(source.getHttpProxy());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 =
|
||||
new Creator<RouteInfo>() {
|
||||
public RouteInfo createFromParcel(Parcel in) {
|
||||
|
||||
@@ -85,12 +85,10 @@ public class ApnContext {
|
||||
|
||||
|
||||
public synchronized DataConnectionAc getDataConnectionAc() {
|
||||
log("getDataConnectionAc dcac=" + mDataConnectionAc);
|
||||
return mDataConnectionAc;
|
||||
}
|
||||
|
||||
public synchronized void setDataConnectionAc(DataConnectionAc dcac) {
|
||||
log("setDataConnectionAc dcac=" + dcac);
|
||||
mDataConnectionAc = dcac;
|
||||
}
|
||||
|
||||
|
||||
@@ -511,14 +511,14 @@ public abstract class DataConnection extends StateMachine {
|
||||
log("onSetupConnectionCompleted received DataCallState: " + response);
|
||||
cid = response.cid;
|
||||
// set link properties based on data call response
|
||||
result = response.setLinkProperties(mLinkProperties,
|
||||
isOkToUseSystemPropertyDns(response));
|
||||
result = setLinkProperties(response, mLinkProperties);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isOkToUseSystemPropertyDns(DataCallState response) {
|
||||
private DataCallState.SetupResult setLinkProperties(DataCallState response,
|
||||
LinkProperties lp) {
|
||||
// Check if system property dns usable
|
||||
boolean okToUseSystemPropertyDns = false;
|
||||
String propertyPrefix = "net." + response.ifname + ".";
|
||||
@@ -526,7 +526,9 @@ public abstract class DataConnection extends StateMachine {
|
||||
dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
|
||||
dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
|
||||
okToUseSystemPropertyDns = isDnsOk(dnsServers);
|
||||
return okToUseSystemPropertyDns;
|
||||
|
||||
// set link properties based on data call response
|
||||
return response.setLinkProperties(lp, okToUseSystemPropertyDns);
|
||||
}
|
||||
|
||||
private boolean updateLinkProperty(DataCallState newState) {
|
||||
@@ -535,29 +537,25 @@ public abstract class DataConnection extends StateMachine {
|
||||
if (newState == null) return changed;
|
||||
|
||||
DataCallState.SetupResult result;
|
||||
LinkProperties linkProperties = new LinkProperties();
|
||||
LinkProperties newLp = new LinkProperties();
|
||||
|
||||
// set link properties based on data call response
|
||||
result = newState.setLinkProperties(linkProperties,
|
||||
isOkToUseSystemPropertyDns(newState));
|
||||
|
||||
result = setLinkProperties(newState, newLp);
|
||||
if (result != DataCallState.SetupResult.SUCCESS) {
|
||||
log("updateLinkProperty failed : " + result);
|
||||
if (DBG) log("UpdateLinkProperty failed : " + result);
|
||||
return changed;
|
||||
}
|
||||
// copy HTTP proxy as it is not part DataCallState.
|
||||
newLp.setHttpProxy(mLinkProperties.getHttpProxy());
|
||||
|
||||
if (mLinkProperties != null) {
|
||||
// Before comparison, copy HTTP proxy from the original
|
||||
// as it is not part DataCallState.
|
||||
linkProperties.setHttpProxy(mLinkProperties.getHttpProxy());
|
||||
if (!mLinkProperties.equals(linkProperties)) {
|
||||
mLinkProperties = linkProperties;
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
mLinkProperties = linkProperties;
|
||||
if (DBG) log("old LP=" + mLinkProperties);
|
||||
if (DBG) log("new LP=" + newLp);
|
||||
|
||||
if (mLinkProperties == null || !mLinkProperties.equals(newLp)) {
|
||||
mLinkProperties = newLp;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -635,8 +633,9 @@ public abstract class DataConnection extends StateMachine {
|
||||
DataCallState newState = (DataCallState) msg.obj;
|
||||
int updated = updateLinkProperty(newState) ? 1 : 0;
|
||||
if (DBG) {
|
||||
log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE updated=" + updated +
|
||||
" newState=" + newState);
|
||||
log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE updated="
|
||||
+ (updated == 1)
|
||||
+ " newState=" + newState);
|
||||
}
|
||||
mAc.replyToMessage(msg,
|
||||
DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,
|
||||
|
||||
@@ -970,32 +970,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
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.
|
||||
*/
|
||||
@@ -1023,15 +997,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param explicitPoll if true, indicates that *we* polled for this
|
||||
* update while state == CONNECTED rather than having it delivered
|
||||
* via an unsolicited response (which could have happened at any
|
||||
* previous state
|
||||
* @param ar is the result of RIL_REQUEST_DATA_CALL_LIST
|
||||
* or RIL_UNSOL_DATA_CALL_LIST_CHANGED
|
||||
*/
|
||||
private void onDataStateChanged (AsyncResult ar) {
|
||||
ArrayList<DataCallState> dataCallStates;
|
||||
|
||||
if (DBG) log("onDataStateChanged(ar) E");
|
||||
if (DBG) log("onDataStateChanged(ar): E");
|
||||
dataCallStates = (ArrayList<DataCallState>)(ar.result);
|
||||
|
||||
if (ar.exception != null) {
|
||||
@@ -1042,78 +1014,79 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
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()) {
|
||||
onDataStateChanged(dataCallStates, apnContext);
|
||||
}
|
||||
if (DBG) log("onDataStateChanged(ar) X");
|
||||
}
|
||||
|
||||
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.
|
||||
if (DBG){
|
||||
log("onDataStateChanged(ar): " + apnContext.toString());
|
||||
if (apnContext.getDataConnection() != null) {
|
||||
log("onDataStateChanged(ar): " + apnContext.getDataConnection().toString());
|
||||
}
|
||||
}
|
||||
DataConnectionAc dcac = apnContext.getDataConnectionAc();
|
||||
if (dcac == null) {
|
||||
if (DBG) log("onDataStateChanged(dataCallState, apnContext): dcac==null BAD NEWS");
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
int cid = dcac.getCidSync();
|
||||
if (!dataCallStatesHasCID(dataCallStates, cid)) {
|
||||
// It looks like the PDP context has deactivated.
|
||||
// Tear everything down and try to reconnect.
|
||||
int connectionId = dcac.getCidSync();
|
||||
|
||||
if (DBG) {
|
||||
log("onDataStateChanged(dataCallStates,apnContext) " +
|
||||
"PDP connection has dropped. Reconnecting");
|
||||
}
|
||||
// Add an event log when the network drops PDP
|
||||
int cellLocationId = getCellLocationId();
|
||||
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cellLocationId,
|
||||
TelephonyManager.getDefault().getNetworkType());
|
||||
|
||||
cleanUpConnection(true, apnContext);
|
||||
} else if (!dataCallStatesHasActiveCID(dataCallStates,
|
||||
apnContext.getDataConnectionAc().getCidSync())) {
|
||||
|
||||
if (DBG) {
|
||||
log("onDataStateChanged(dataCallStates,apnContext) " +
|
||||
"PDP connection has dropped (active=false case). Reconnecting");
|
||||
}
|
||||
|
||||
// Log the network drop on the event log.
|
||||
int cellLocationId = getCellLocationId();
|
||||
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cellLocationId,
|
||||
TelephonyManager.getDefault().getNetworkType());
|
||||
|
||||
cleanUpConnection(true, apnContext);
|
||||
} else {
|
||||
// Here, data call list has active cid for given ApnContext.
|
||||
// Check if link property has been updated.
|
||||
DataCallState state = findDataCallStateByCID(dataCallStates,
|
||||
apnContext.getDataConnectionAc().getCidSync());
|
||||
|
||||
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 (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 de-activated one.
|
||||
if (response.containsKey(connectionId)) {
|
||||
DataCallState newState = response.get(connectionId);
|
||||
if (DBG) log("onDataStateChanged(ar): Found ConnId=" + connectionId
|
||||
+ " newState=" + newState.toString());
|
||||
if (newState.active != 0) {
|
||||
boolean changed
|
||||
= dcac.updateLinkPropertiesDataCallStateSync(newState);
|
||||
if (changed) {
|
||||
if (DBG) log("onDataStateChanged(ar): Found and changed, notify");
|
||||
mPhone.notifyDataConnection(Phone.REASON_LINK_PROPERTIES_CHANGED,
|
||||
apnContext.getApnType());
|
||||
// Temporary hack, if false we'll reset connections and at this
|
||||
// time a transition from CDMA -> Global fails. The DEACTIVATE
|
||||
// fails with a GENERIC_FAILURE and the VZWINTERNET connection is
|
||||
// never setup. @see bug/
|
||||
if (SystemProperties.getBoolean("telephony.ignore-state-changes",
|
||||
true)) {
|
||||
log("onDataStateChanged(ar): STOPSHIP don't reset, continue");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (DBG) log("onDataStateChanged(ar): Found but no change, skip");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -2143,7 +2116,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
@Override
|
||||
protected void log(String s) {
|
||||
Log.d(LOG_TAG, "[GsmDCT] " + s);
|
||||
Log.d(LOG_TAG, "[GsmDCT] "+ s);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user