Merge "Map multiple apnType to one DataConnection fixes." into honeycomb-LTE
This commit is contained in:
@@ -205,6 +205,7 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
protected long lastFailTime;
|
protected long lastFailTime;
|
||||||
protected FailCause lastFailCause;
|
protected FailCause lastFailCause;
|
||||||
protected static final String NULL_IP = "0.0.0.0";
|
protected static final String NULL_IP = "0.0.0.0";
|
||||||
|
private int mRefCount;
|
||||||
Object userData;
|
Object userData;
|
||||||
|
|
||||||
//***** Abstract methods
|
//***** Abstract methods
|
||||||
@@ -413,49 +414,6 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
return mRetryMgr.configure(configStr);
|
return mRetryMgr.configure(configStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AtomicInteger mRefCount = new AtomicInteger(0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set refCount.
|
|
||||||
*
|
|
||||||
* @param val is new refCount
|
|
||||||
*/
|
|
||||||
public void setRefCount(int val) {
|
|
||||||
mRefCount.set(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get refCount
|
|
||||||
*
|
|
||||||
* @return refCount
|
|
||||||
*/
|
|
||||||
public int getRefCount() {
|
|
||||||
return mRefCount.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return decrement and return refCount
|
|
||||||
*
|
|
||||||
* TODO: Consider using the refCount for defining the
|
|
||||||
* life time of a connection. When this goes zero the
|
|
||||||
* DataConnection could tear itself down.
|
|
||||||
*/
|
|
||||||
public int decAndGetRefCount() {
|
|
||||||
int v = mRefCount.decrementAndGet();
|
|
||||||
if (v < 0) {
|
|
||||||
log("BUG: decAndGetRefCount caused refCount to be < 0");
|
|
||||||
mRefCount.set(0);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return increment and return refCount
|
|
||||||
*/
|
|
||||||
public int incAndGetRefCount() {
|
|
||||||
return mRefCount.incrementAndGet();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* **************************************************************************
|
* **************************************************************************
|
||||||
* End members owned by DataConnectionTracker
|
* End members owned by DataConnectionTracker
|
||||||
@@ -471,6 +429,7 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
createTime = -1;
|
createTime = -1;
|
||||||
lastFailTime = -1;
|
lastFailTime = -1;
|
||||||
lastFailCause = FailCause.NONE;
|
lastFailCause = FailCause.NONE;
|
||||||
|
mRefCount = 0;
|
||||||
|
|
||||||
mLinkProperties = new LinkProperties();
|
mLinkProperties = new LinkProperties();
|
||||||
mApn = null;
|
mApn = null;
|
||||||
@@ -674,6 +633,11 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET);
|
mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET);
|
||||||
transitionTo(mInactiveState);
|
transitionTo(mInactiveState);
|
||||||
break;
|
break;
|
||||||
|
case DataConnectionAc.REQ_GET_REFCOUNT: {
|
||||||
|
log("REQ_GET_REFCOUNT refCount=" + mRefCount);
|
||||||
|
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_REFCOUNT, mRefCount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EVENT_CONNECT:
|
case EVENT_CONNECT:
|
||||||
if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected");
|
if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected");
|
||||||
@@ -774,9 +738,13 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_CONNECT:
|
case EVENT_CONNECT:
|
||||||
if (DBG) log("DcInactiveState msg.what=EVENT_CONNECT");
|
|
||||||
ConnectionParams cp = (ConnectionParams) msg.obj;
|
ConnectionParams cp = (ConnectionParams) msg.obj;
|
||||||
cp.tag = mTag;
|
cp.tag = mTag;
|
||||||
|
if (DBG) {
|
||||||
|
log("DcInactiveState msg.what=EVENT_CONNECT." + "RefCount = "
|
||||||
|
+ mRefCount);
|
||||||
|
}
|
||||||
|
mRefCount = 1;
|
||||||
onConnect(cp);
|
onConnect(cp);
|
||||||
transitionTo(mActivatingState);
|
transitionTo(mActivatingState);
|
||||||
retVal = HANDLED;
|
retVal = HANDLED;
|
||||||
@@ -804,7 +772,15 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
|
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case EVENT_DISCONNECT:
|
case EVENT_DISCONNECT:
|
||||||
if (DBG) log("DcActivatingState deferring msg.what=EVENT_DISCONNECT");
|
if (DBG) log("DcActivatingState deferring msg.what=EVENT_DISCONNECT"
|
||||||
|
+ mRefCount);
|
||||||
|
deferMessage(msg);
|
||||||
|
retVal = HANDLED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_CONNECT:
|
||||||
|
if (DBG) log("DcActivatingState deferring msg.what=EVENT_CONNECT refCount = "
|
||||||
|
+ mRefCount);
|
||||||
deferMessage(msg);
|
deferMessage(msg);
|
||||||
retVal = HANDLED;
|
retVal = HANDLED;
|
||||||
break;
|
break;
|
||||||
@@ -928,12 +904,28 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
boolean retVal;
|
boolean retVal;
|
||||||
|
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
|
case EVENT_CONNECT:
|
||||||
|
mRefCount++;
|
||||||
|
if (DBG) log("DcActiveState msg.what=EVENT_CONNECT RefCount=" + mRefCount);
|
||||||
|
if (msg.obj != null) {
|
||||||
|
notifyConnectCompleted((ConnectionParams) msg.obj, FailCause.NONE);
|
||||||
|
}
|
||||||
|
retVal = HANDLED;
|
||||||
|
break;
|
||||||
case EVENT_DISCONNECT:
|
case EVENT_DISCONNECT:
|
||||||
if (DBG) log("DcActiveState msg.what=EVENT_DISCONNECT");
|
mRefCount--;
|
||||||
DisconnectParams dp = (DisconnectParams) msg.obj;
|
if (DBG) log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" + mRefCount);
|
||||||
dp.tag = mTag;
|
if (mRefCount == 0)
|
||||||
tearDownData(dp);
|
{
|
||||||
transitionTo(mDisconnectingState);
|
DisconnectParams dp = (DisconnectParams) msg.obj;
|
||||||
|
dp.tag = mTag;
|
||||||
|
tearDownData(dp);
|
||||||
|
transitionTo(mDisconnectingState);
|
||||||
|
} else {
|
||||||
|
if (msg.obj != null) {
|
||||||
|
notifyDisconnectCompleted((DisconnectParams) msg.obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
retVal = HANDLED;
|
retVal = HANDLED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -956,6 +948,13 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
boolean retVal;
|
boolean retVal;
|
||||||
|
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
|
case EVENT_CONNECT:
|
||||||
|
if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = "
|
||||||
|
+ mRefCount);
|
||||||
|
deferMessage(msg);
|
||||||
|
retVal = HANDLED;
|
||||||
|
break;
|
||||||
|
|
||||||
case EVENT_DEACTIVATE_DONE:
|
case EVENT_DEACTIVATE_DONE:
|
||||||
if (DBG) log("DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE");
|
if (DBG) log("DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE");
|
||||||
AsyncResult ar = (AsyncResult) msg.obj;
|
AsyncResult ar = (AsyncResult) msg.obj;
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ public class DataConnectionAc extends AsyncChannel {
|
|||||||
public static final int REQ_RESET = BASE + 14;
|
public static final int REQ_RESET = BASE + 14;
|
||||||
public static final int RSP_RESET = BASE + 15;
|
public static final int RSP_RESET = BASE + 15;
|
||||||
|
|
||||||
|
public static final int REQ_GET_REFCOUNT = BASE + 16;
|
||||||
|
public static final int RSP_GET_REFCOUNT = BASE + 17;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum used to notify action taken or necessary to be
|
* enum used to notify action taken or necessary to be
|
||||||
* taken after the link property is changed.
|
* taken after the link property is changed.
|
||||||
@@ -151,6 +154,40 @@ public class DataConnectionAc extends AsyncChannel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the Reference Count.
|
||||||
|
* Response {@link #rspRefCount}
|
||||||
|
*/
|
||||||
|
public void reqRefCount() {
|
||||||
|
sendMessage(REQ_GET_REFCOUNT);
|
||||||
|
if (DBG) log("reqRefCount");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate a RSP_GET_REFCOUNT message and return the refCount.
|
||||||
|
*
|
||||||
|
* @param response Message
|
||||||
|
* @return ref count or -1 if an error
|
||||||
|
*/
|
||||||
|
public int rspRefCount(Message response) {
|
||||||
|
int retVal = response.arg1;
|
||||||
|
if (DBG) log("rspRefCount=" + retVal);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return connection id or -1 if an error
|
||||||
|
*/
|
||||||
|
public int getRefCountSync() {
|
||||||
|
Message response = sendMessageSynchronously(REQ_GET_REFCOUNT);
|
||||||
|
if ((response != null) && (response.what == RSP_GET_REFCOUNT)) {
|
||||||
|
return rspRefCount(response);
|
||||||
|
} else {
|
||||||
|
log("rspRefCount error response=" + response);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request the connections ApnSetting.
|
* Request the connections ApnSetting.
|
||||||
* Response {@link #rspApnSetting}
|
* Response {@link #rspApnSetting}
|
||||||
|
|||||||
@@ -987,7 +987,7 @@ public abstract class DataConnectionTracker extends Handler {
|
|||||||
resetAllRetryCounts();
|
resetAllRetryCounts();
|
||||||
onTrySetupData(Phone.REASON_DATA_ENABLED);
|
onTrySetupData(Phone.REASON_DATA_ENABLED);
|
||||||
} else {
|
} else {
|
||||||
onCleanUpConnection(true, APN_DEFAULT_ID, Phone.REASON_DATA_DISABLED);
|
onCleanUpAllConnections(Phone.REASON_DATA_DISABLED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -612,28 +612,26 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
*
|
*
|
||||||
* @param apnContext
|
* @param apnContext
|
||||||
* @param tearDown
|
* @param tearDown
|
||||||
* @return refCount
|
* @return none
|
||||||
*/
|
*/
|
||||||
private int releaseApnContext(ApnContext apnContext, boolean tearDown) {
|
private void releaseApnContext(ApnContext apnContext, boolean tearDown) {
|
||||||
if (apnContext == null) {
|
if (apnContext == null) {
|
||||||
if (DBG) loge("releaseApnContext: apnContext null should not happen, ignore");
|
if (DBG) loge("releaseApnContext: apnContext null should not happen, ignore");
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
DataConnection dc = apnContext.getDataConnection();
|
DataConnection dc = apnContext.getDataConnection();
|
||||||
if (dc == null) {
|
if (dc == null) {
|
||||||
if (DBG) loge("releaseApnContext: apnContext dc == null should not happen, ignore");
|
if (DBG) loge("releaseApnContext: apnContext dc == null should not happen, ignore");
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
int refCount = dc.decAndGetRefCount();
|
if (tearDown) {
|
||||||
if (DBG) log("releaseApnContext: dec refCount=" + refCount + " tearDown=" + tearDown);
|
|
||||||
if (tearDown && (refCount == 0)) {
|
|
||||||
if (DBG) log("releaseApnContext: tearing down");
|
if (DBG) log("releaseApnContext: tearing down");
|
||||||
Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
|
Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
|
||||||
apnContext.getDataConnection().tearDown(apnContext.getReason(), msg);
|
apnContext.getDataConnection().tearDown(apnContext.getReason(), msg);
|
||||||
}
|
}
|
||||||
apnContext.setDataConnection(null);
|
apnContext.setDataConnection(null);
|
||||||
apnContext.setDataConnectionAc(null);
|
apnContext.setDataConnectionAc(null);
|
||||||
return refCount;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupDataOnReadyApns(String reason) {
|
private void setupDataOnReadyApns(String reason) {
|
||||||
@@ -809,12 +807,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
apnContext.setState(State.DISCONNECTING);
|
apnContext.setState(State.DISCONNECTING);
|
||||||
releaseApnContext(apnContext, tearDown);
|
releaseApnContext(apnContext, tearDown);
|
||||||
} else {
|
} else {
|
||||||
// STOPSHIP: Reference counting logic in GDCT still have issue.
|
|
||||||
// Need to be cleaned up in later patch
|
|
||||||
dcac.resetSync();
|
dcac.resetSync();
|
||||||
if (apnContext.getDataConnection() != null) {
|
|
||||||
apnContext.getDataConnection().setRefCount(0);
|
|
||||||
}
|
|
||||||
apnContext.setState(State.IDLE);
|
apnContext.setState(State.IDLE);
|
||||||
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
|
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
|
||||||
apnContext.setDataConnection(null);
|
apnContext.setDataConnection(null);
|
||||||
@@ -946,7 +939,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
dc = (GsmDataConnection)apnContext.getDataConnection();
|
dc = (GsmDataConnection)apnContext.getDataConnection();
|
||||||
|
|
||||||
if (dc == null) {
|
if (dc == null) {
|
||||||
dc = findReadyDataConnection(apn);
|
|
||||||
|
dc = (GsmDataConnection) checkForConnectionForApnContext(apnContext);
|
||||||
|
|
||||||
|
if (dc == null) {
|
||||||
|
dc = findReadyDataConnection(apn);
|
||||||
|
}
|
||||||
|
|
||||||
if (dc == null) {
|
if (dc == null) {
|
||||||
if (DBG) log("setupData: No ready GsmDataConnection found!");
|
if (DBG) log("setupData: No ready GsmDataConnection found!");
|
||||||
@@ -964,16 +962,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId());
|
||||||
dc.setProfileId( profileId );
|
dc.setProfileId( profileId );
|
||||||
dc.setActiveApnType(apnContext.getApnType());
|
dc.setActiveApnType(apnContext.getApnType());
|
||||||
int refCount = dc.incAndGetRefCount();
|
int refCount = dcac.getRefCountSync();
|
||||||
if (DBG) log("setupData: init dc and apnContext refCount=" + refCount);
|
if (DBG) log("setupData: init dc and apnContext refCount=" + refCount);
|
||||||
|
|
||||||
// configure retry count if no other Apn is using the same connection.
|
// configure retry count if no other Apn is using the same connection.
|
||||||
if (refCount == 1) {
|
if (refCount == 0) {
|
||||||
configureRetry(dc, apnContext.getApnType());
|
configureRetry(dc, apnContext.getApnType());
|
||||||
}
|
}
|
||||||
DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId());
|
|
||||||
apnContext.setDataConnectionAc(mDataConnectionAsyncChannels.get(dc.getDataConnectionId()));
|
apnContext.setDataConnectionAc(mDataConnectionAsyncChannels.get(dc.getDataConnectionId()));
|
||||||
apnContext.setApnSetting(apn);
|
apnContext.setApnSetting(apn);
|
||||||
apnContext.setDataConnection(dc);
|
apnContext.setDataConnection(dc);
|
||||||
@@ -1493,23 +1491,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
} else {
|
} else {
|
||||||
apnContext.setReason(Phone.REASON_DATA_ENABLED);
|
apnContext.setReason(Phone.REASON_DATA_ENABLED);
|
||||||
}
|
}
|
||||||
DataConnection conn = checkForConnectionForApnContext(apnContext);
|
if (apnContext.getState() == State.FAILED) {
|
||||||
if (conn == null) {
|
apnContext.setState(State.IDLE);
|
||||||
if (apnContext.getState() == State.FAILED) {
|
|
||||||
apnContext.setState(State.IDLE);
|
|
||||||
}
|
|
||||||
trySetup = true;
|
|
||||||
} else {
|
|
||||||
int refCount = conn.incAndGetRefCount();
|
|
||||||
apnContext.setDataConnection(conn);
|
|
||||||
apnContext.setDataConnectionAc(
|
|
||||||
mDataConnectionAsyncChannels.get(conn.getDataConnectionId()));
|
|
||||||
if (DBG) {
|
|
||||||
log("applyNewState: Found existing connection for " +
|
|
||||||
apnContext.getApnType() + " inc refCount=" + refCount +
|
|
||||||
" conn=" + conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
trySetup = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apnContext.setEnabled(enabled);
|
apnContext.setEnabled(enabled);
|
||||||
@@ -1644,7 +1629,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
|
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
log(String.format("onDataSetupComplete: success apn=%s",
|
log(String.format("onDataSetupComplete: success apn=%s",
|
||||||
apnContext.getWaitingApns().get(0).apn) + " refCount=" + dc.getRefCount());
|
apnContext.getWaitingApns().get(0).apn));
|
||||||
}
|
}
|
||||||
ApnSetting apn = apnContext.getApnSetting();
|
ApnSetting apn = apnContext.getApnSetting();
|
||||||
if (apn.proxy != null && apn.proxy.length() != 0) {
|
if (apn.proxy != null && apn.proxy.length() != 0) {
|
||||||
@@ -1712,10 +1697,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
apnContext.setState(State.FAILED);
|
apnContext.setState(State.FAILED);
|
||||||
mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
|
mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
|
||||||
|
|
||||||
int refCount = releaseApnContext(apnContext, false);
|
releaseApnContext(apnContext, false);
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
log("onDataSetupComplete: permanent error apn=%s" + apnString +
|
log("onDataSetupComplete: permanent error apn=%s" + apnString );
|
||||||
" refCount=" + refCount);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
|
if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
|
||||||
@@ -1809,7 +1793,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
|
protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
|
||||||
if (DBG) log("onCleanUpConnection");
|
if (DBG) log("onCleanUpConnection");
|
||||||
ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
|
ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
|
||||||
cleanUpConnection(tearDown, apnContext);
|
if (apnContext != null) {
|
||||||
|
apnContext.setReason(reason);
|
||||||
|
cleanUpConnection(tearDown, apnContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isConnected() {
|
protected boolean isConnected() {
|
||||||
|
|||||||
Reference in New Issue
Block a user