am 070eecef: Merge "Map multiple apnType to one DataConnection fixes." into honeycomb-LTE

* commit '070eecef394175d7344cdadde675e8977a1609f0':
  Map multiple apnType to one DataConnection fixes.
This commit is contained in:
Wink Saville
2011-05-23 13:42:14 -07:00
committed by Android Git Automerger
4 changed files with 112 additions and 89 deletions

View File

@@ -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;

View File

@@ -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}

View File

@@ -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);
} }
} }
} }

View File

@@ -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() {