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();
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user