Loading src/java/com/android/internal/telephony/dataconnection/ApnContext.java +14 −0 Original line number Original line Diff line number Diff line Loading @@ -93,6 +93,12 @@ public class ApnContext { */ */ private boolean mConcurrentVoiceAndDataAllowed; private boolean mConcurrentVoiceAndDataAllowed; /** * used to track a single connection request so disconnects can get ignored if * obsolete. */ private final AtomicInteger mConnectionGeneration = new AtomicInteger(0); public ApnContext(Context context, String apnType, String logTag, NetworkConfig config, public ApnContext(Context context, String apnType, String logTag, NetworkConfig config, DcTrackerBase tracker) { DcTrackerBase tracker) { mContext = context; mContext = context; Loading Loading @@ -392,6 +398,14 @@ public class ApnContext { return result; return result; } } public int incAndGetConnectionGeneration() { return mConnectionGeneration.incrementAndGet(); } public int getConnectionGeneration() { return mConnectionGeneration.get(); } @Override @Override public synchronized String toString() { public synchronized String toString() { // We don't print mDataConnection because its recursive. // We don't print mDataConnection because its recursive. Loading src/java/com/android/internal/telephony/dataconnection/DataConnection.java +20 −12 Original line number Original line Diff line number Diff line Loading @@ -65,6 +65,7 @@ import java.util.Locale; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger; import java.net.InetAddress; import java.net.InetAddress; import java.util.Collection; import java.util.Collection; import java.util.HashMap; /** /** * {@hide} * {@hide} Loading Loading @@ -127,15 +128,18 @@ public final class DataConnection extends StateMachine { int mRilRat; int mRilRat; boolean mRetryWhenSSChange; boolean mRetryWhenSSChange; Message mOnCompletedMsg; Message mOnCompletedMsg; final int mConnectionGeneration; ConnectionParams(ApnContext apnContext, int initialMaxRetry, int profileId, ConnectionParams(ApnContext apnContext, int initialMaxRetry, int profileId, int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg) { int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg, int connectionGeneration) { mApnContext = apnContext; mApnContext = apnContext; mInitialMaxRetry = initialMaxRetry; mInitialMaxRetry = initialMaxRetry; mProfileId = profileId; mProfileId = profileId; mRilRat = rilRadioTechnology; mRilRat = rilRadioTechnology; mRetryWhenSSChange = retryWhenSSChange; mRetryWhenSSChange = retryWhenSSChange; mOnCompletedMsg = onCompletedMsg; mOnCompletedMsg = onCompletedMsg; mConnectionGeneration = connectionGeneration; } } @Override @Override Loading Loading @@ -190,7 +194,7 @@ public final class DataConnection extends StateMachine { //***** Package visible variables //***** Package visible variables int mTag; int mTag; int mCid; int mCid; List<ApnContext> mApnContexts = null; HashMap<ApnContext, ConnectionParams> mApnContexts = null; PendingIntent mReconnectIntent = null; PendingIntent mReconnectIntent = null; RetryManager mRetryManager = new RetryManager(); RetryManager mRetryManager = new RetryManager(); Loading Loading @@ -448,7 +452,7 @@ public final class DataConnection extends StateMachine { addState(mDisconnectingErrorCreatingConnection, mDefaultState); addState(mDisconnectingErrorCreatingConnection, mDefaultState); setInitialState(mInactiveState); setInitialState(mInactiveState); mApnContexts = new ArrayList<ApnContext>(); mApnContexts = new HashMap<ApnContext, ConnectionParams>(); if (DBG) log("DataConnection constructor X"); if (DBG) log("DataConnection constructor X"); } } Loading Loading @@ -614,10 +618,13 @@ public final class DataConnection extends StateMachine { private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) { private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) { mNetworkInfo.setDetailedState(mNetworkInfo.getDetailedState(), reason, mNetworkInfo.setDetailedState(mNetworkInfo.getDetailedState(), reason, mNetworkInfo.getExtraInfo()); mNetworkInfo.getExtraInfo()); for (ApnContext apnContext : mApnContexts) { for (ConnectionParams cp : mApnContexts.values()) { ApnContext apnContext = cp.mApnContext; if (apnContext == alreadySent) continue; if (apnContext == alreadySent) continue; if (reason != null) apnContext.setReason(reason); if (reason != null) apnContext.setReason(reason); Message msg = mDct.obtainMessage(event, apnContext); Pair<ApnContext, Integer> pair = new Pair<ApnContext, Integer>(apnContext, cp.mConnectionGeneration); Message msg = mDct.obtainMessage(event, pair); AsyncResult.forMessage(msg); AsyncResult.forMessage(msg); msg.sendToTarget(); msg.sendToTarget(); } } Loading Loading @@ -1038,8 +1045,8 @@ public final class DataConnection extends StateMachine { mConnectionParams = cp; mConnectionParams = cp; mConnectionParams.mTag = mTag; mConnectionParams.mTag = mTag; if (!mApnContexts.contains(apnContext)) { if (!mApnContexts.containsKey(apnContext)) { mApnContexts.add(apnContext); mApnContexts.put(apnContext, cp); } } configureRetry(mApnSetting.canHandleType(PhoneConstants.APN_TYPE_DEFAULT)); configureRetry(mApnSetting.canHandleType(PhoneConstants.APN_TYPE_DEFAULT)); mRetryManager.setRetryCount(0); mRetryManager.setRetryCount(0); Loading Loading @@ -1544,7 +1551,8 @@ public final class DataConnection extends StateMachine { case EVENT_DISCONNECT: { case EVENT_DISCONNECT: { DisconnectParams dp = (DisconnectParams) msg.obj; DisconnectParams dp = (DisconnectParams) msg.obj; if (mApnContexts.remove(dp.mApnContext) && mApnContexts.size() == 0) { if ((mApnContexts.remove(dp.mApnContext) != null) && (mApnContexts.size() == 0)) { if (DBG) { if (DBG) { log("DcRetryingState msg.what=EVENT_DISCONNECT " + " RefCount=" log("DcRetryingState msg.what=EVENT_DISCONNECT " + " RefCount=" + mApnContexts.size() + " dp=" + dp); + mApnContexts.size() + " dp=" + dp); Loading Loading @@ -1842,10 +1850,10 @@ public final class DataConnection extends StateMachine { if (DBG) { if (DBG) { log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this); log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this); } } if (mApnContexts.contains(cp.mApnContext)) { if (mApnContexts.containsKey(cp.mApnContext)) { log("DcActiveState ERROR already added apnContext=" + cp.mApnContext); log("DcActiveState ERROR already added apnContext=" + cp.mApnContext); } else { } else { mApnContexts.add(cp.mApnContext); mApnContexts.put(cp.mApnContext, cp); if (DBG) { if (DBG) { log("DcActiveState msg.what=EVENT_CONNECT RefCount=" log("DcActiveState msg.what=EVENT_CONNECT RefCount=" + mApnContexts.size()); + mApnContexts.size()); Loading @@ -1861,7 +1869,7 @@ public final class DataConnection extends StateMachine { log("DcActiveState: EVENT_DISCONNECT dp=" + dp log("DcActiveState: EVENT_DISCONNECT dp=" + dp + " dc=" + DataConnection.this); + " dc=" + DataConnection.this); } } if (mApnContexts.contains(dp.mApnContext)) { if (mApnContexts.containsKey(dp.mApnContext)) { if (DBG) { if (DBG) { log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" + mApnContexts.size()); + mApnContexts.size()); Loading Loading @@ -2088,7 +2096,7 @@ public final class DataConnection extends StateMachine { } } // this can only happen if our exit has been called - we're already disconnected // this can only happen if our exit has been called - we're already disconnected if (mApnContexts == null) return; if (mApnContexts == null) return; for (ApnContext apnContext : mApnContexts) { for (ApnContext apnContext : mApnContexts.keySet()) { log("DcNetworkAgent: [unwanted]: disconnect apnContext=" + apnContext); log("DcNetworkAgent: [unwanted]: disconnect apnContext=" + apnContext); Message msg = mDct.obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext); Message msg = mDct.obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext); DisconnectParams dp = new DisconnectParams(apnContext, apnContext.getReason(), msg); DisconnectParams dp = new DisconnectParams(apnContext, apnContext.getReason(), msg); Loading src/java/com/android/internal/telephony/dataconnection/DcAsyncChannel.java +4 −2 Original line number Original line Diff line number Diff line Loading @@ -368,14 +368,16 @@ public class DcAsyncChannel extends AsyncChannel { * AsyncResult.result = FailCause and AsyncResult.exception = Exception(). * AsyncResult.result = FailCause and AsyncResult.exception = Exception(). */ */ public void bringUp(ApnContext apnContext, int initialMaxRetry, int profileId, public void bringUp(ApnContext apnContext, int initialMaxRetry, int profileId, int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg) { int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg, int connectionGeneration) { if (DBG) { if (DBG) { log("bringUp: apnContext=" + apnContext + " initialMaxRetry=" + initialMaxRetry log("bringUp: apnContext=" + apnContext + " initialMaxRetry=" + initialMaxRetry + " onCompletedMsg=" + onCompletedMsg); + " onCompletedMsg=" + onCompletedMsg); } } sendMessage(DataConnection.EVENT_CONNECT, sendMessage(DataConnection.EVENT_CONNECT, new ConnectionParams(apnContext, initialMaxRetry, profileId, new ConnectionParams(apnContext, initialMaxRetry, profileId, rilRadioTechnology, retryWhenSSChange, onCompletedMsg)); rilRadioTechnology, retryWhenSSChange, onCompletedMsg, connectionGeneration)); } } /** /** Loading src/java/com/android/internal/telephony/dataconnection/DcController.java +5 −5 Original line number Original line Diff line number Diff line Loading @@ -265,7 +265,7 @@ class DcController extends StateMachine { + " newState=" + newState.toString()); + " newState=" + newState.toString()); if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE) { if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE) { if (mDct.mIsCleanupRequired) { if (mDct.mIsCleanupRequired) { apnsToCleanup.addAll(dc.mApnContexts); apnsToCleanup.addAll(dc.mApnContexts.keySet()); mDct.mIsCleanupRequired = false; mDct.mIsCleanupRequired = false; } else { } else { DcFailCause failCause = DcFailCause.fromInt(newState.status); DcFailCause failCause = DcFailCause.fromInt(newState.status); Loading @@ -275,7 +275,7 @@ class DcController extends StateMachine { mDct.sendRestartRadio(); mDct.sendRestartRadio(); } else if (mDct.isPermanentFail(failCause)) { } else if (mDct.isPermanentFail(failCause)) { if (DBG) log("onDataStateChanged: inactive, add to cleanup list"); if (DBG) log("onDataStateChanged: inactive, add to cleanup list"); apnsToCleanup.addAll(dc.mApnContexts); apnsToCleanup.addAll(dc.mApnContexts.keySet()); } else { } else { if (DBG) log("onDataStateChanged: inactive, add to retry list"); if (DBG) log("onDataStateChanged: inactive, add to retry list"); dcsToRetry.add(dc); dcsToRetry.add(dc); Loading Loading @@ -318,11 +318,11 @@ class DcController extends StateMachine { " oldLp=" + result.oldLp + " oldLp=" + result.oldLp + " newLp=" + result.newLp); " newLp=" + result.newLp); } } apnsToCleanup.addAll(dc.mApnContexts); apnsToCleanup.addAll(dc.mApnContexts.keySet()); } else { } else { if (DBG) log("onDataStateChanged: simple change"); if (DBG) log("onDataStateChanged: simple change"); for (ApnContext apnContext : dc.mApnContexts) { for (ApnContext apnContext : dc.mApnContexts.keySet()) { mPhone.notifyDataConnection( mPhone.notifyDataConnection( PhoneConstants.REASON_LINK_PROPERTIES_CHANGED, PhoneConstants.REASON_LINK_PROPERTIES_CHANGED, apnContext.getApnType()); apnContext.getApnType()); Loading @@ -334,7 +334,7 @@ class DcController extends StateMachine { } } } } } else { } else { apnsToCleanup.addAll(dc.mApnContexts); apnsToCleanup.addAll(dc.mApnContexts.keySet()); if (DBG) { if (DBG) { log("onDataStateChanged: interface change, cleanup apns=" log("onDataStateChanged: interface change, cleanup apns=" + dc.mApnContexts); + dc.mApnContexts); Loading src/java/com/android/internal/telephony/dataconnection/DcTracker.java +34 −31 Original line number Original line Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; import android.text.TextUtils; import android.util.EventLog; import android.util.EventLog; import android.util.LocalLog; import android.util.LocalLog; import android.util.Pair; import android.view.WindowManager; import android.view.WindowManager; import android.telephony.Rlog; import android.telephony.Rlog; Loading Loading @@ -1311,6 +1312,7 @@ public final class DcTracker extends DcTrackerBase { apnContext.setDataConnectionAc(dcac); apnContext.setDataConnectionAc(dcac); apnContext.setApnSetting(apnSetting); apnContext.setApnSetting(apnSetting); int connectionGeneration = apnContext.incAndGetConnectionGeneration(); apnContext.setState(DctConstants.State.CONNECTING); apnContext.setState(DctConstants.State.CONNECTING); mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); Loading @@ -1318,7 +1320,7 @@ public final class DcTracker extends DcTrackerBase { msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE; msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE; msg.obj = apnContext; msg.obj = apnContext; dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, mAutoAttachOnCreation.get(), msg); mAutoAttachOnCreation.get(), msg, connectionGeneration); if (DBG) log("setupData: initing!"); if (DBG) log("setupData: initing!"); return true; return true; Loading Loading @@ -1821,13 +1823,9 @@ public final class DcTracker extends DcTrackerBase { DcFailCause cause = DcFailCause.UNKNOWN; DcFailCause cause = DcFailCause.UNKNOWN; boolean handleError = false; boolean handleError = false; ApnContext apnContext = null; ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete"); if(ar.userObj instanceof ApnContext){ if (apnContext == null) return; apnContext = (ApnContext)ar.userObj; } else { throw new RuntimeException("onDataSetupComplete: No apnContext"); } if (ar.exception == null) { if (ar.exception == null) { DcAsyncChannel dcac = apnContext.getDcAc(); DcAsyncChannel dcac = apnContext.getDcAc(); Loading Loading @@ -2010,6 +2008,27 @@ public final class DcTracker extends DcTrackerBase { } } } } /** * check for obsolete messages. Return ApnContext if valid, null if not */ private ApnContext getValidApnContext(AsyncResult ar, String logString) { if (ar != null && ar.userObj instanceof Pair) { Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj; ApnContext apnContext = pair.first; if (apnContext != null) { if (apnContext.getConnectionGeneration() == pair.second) { return apnContext; } else { log("ignoring obsolete " + logString); return null; } } } throw new RuntimeException(logString + ": No apnContext"); } /** /** * Error has occurred during the SETUP {aka bringUP} request and the DCT * Error has occurred during the SETUP {aka bringUP} request and the DCT * should either try the next waiting APN or start over from the * should either try the next waiting APN or start over from the Loading @@ -2019,13 +2038,9 @@ public final class DcTracker extends DcTrackerBase { @Override @Override protected void onDataSetupCompleteError(AsyncResult ar) { protected void onDataSetupCompleteError(AsyncResult ar) { String reason = ""; String reason = ""; ApnContext apnContext = null; ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError"); if(ar.userObj instanceof ApnContext){ if (apnContext == null) return; apnContext = (ApnContext)ar.userObj; } else { throw new RuntimeException("onDataSetupCompleteError: No apnContext"); } // See if there are more APN's to try // See if there are more APN's to try if (apnContext.getWaitingApns().isEmpty()) { if (apnContext.getWaitingApns().isEmpty()) { Loading Loading @@ -2059,15 +2074,9 @@ public final class DcTracker extends DcTrackerBase { * Called when EVENT_DISCONNECT_DONE is received. * Called when EVENT_DISCONNECT_DONE is received. */ */ @Override @Override protected void onDisconnectDone(int connId, AsyncResult ar) { protected void onDisconnectDone(AsyncResult ar) { ApnContext apnContext = null; ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone"); if (apnContext == null) return; if (ar.userObj instanceof ApnContext) { apnContext = (ApnContext) ar.userObj; } else { loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore"); return; } if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext); if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext); apnContext.setState(DctConstants.State.IDLE); apnContext.setState(DctConstants.State.IDLE); Loading Loading @@ -2138,16 +2147,10 @@ public final class DcTracker extends DcTrackerBase { * Called when EVENT_DISCONNECT_DC_RETRYING is received. * Called when EVENT_DISCONNECT_DC_RETRYING is received. */ */ @Override @Override protected void onDisconnectDcRetrying(int connId, AsyncResult ar) { protected void onDisconnectDcRetrying(AsyncResult ar) { // We could just do this in DC!!! // We could just do this in DC!!! ApnContext apnContext = null; ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying"); if (apnContext == null) return; if (ar.userObj instanceof ApnContext) { apnContext = (ApnContext) ar.userObj; } else { loge("onDisconnectDcRetrying: Invalid ar in onDisconnectDone, ignore"); return; } apnContext.setState(DctConstants.State.RETRYING); apnContext.setState(DctConstants.State.RETRYING); if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext); if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext); Loading Loading
src/java/com/android/internal/telephony/dataconnection/ApnContext.java +14 −0 Original line number Original line Diff line number Diff line Loading @@ -93,6 +93,12 @@ public class ApnContext { */ */ private boolean mConcurrentVoiceAndDataAllowed; private boolean mConcurrentVoiceAndDataAllowed; /** * used to track a single connection request so disconnects can get ignored if * obsolete. */ private final AtomicInteger mConnectionGeneration = new AtomicInteger(0); public ApnContext(Context context, String apnType, String logTag, NetworkConfig config, public ApnContext(Context context, String apnType, String logTag, NetworkConfig config, DcTrackerBase tracker) { DcTrackerBase tracker) { mContext = context; mContext = context; Loading Loading @@ -392,6 +398,14 @@ public class ApnContext { return result; return result; } } public int incAndGetConnectionGeneration() { return mConnectionGeneration.incrementAndGet(); } public int getConnectionGeneration() { return mConnectionGeneration.get(); } @Override @Override public synchronized String toString() { public synchronized String toString() { // We don't print mDataConnection because its recursive. // We don't print mDataConnection because its recursive. Loading
src/java/com/android/internal/telephony/dataconnection/DataConnection.java +20 −12 Original line number Original line Diff line number Diff line Loading @@ -65,6 +65,7 @@ import java.util.Locale; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger; import java.net.InetAddress; import java.net.InetAddress; import java.util.Collection; import java.util.Collection; import java.util.HashMap; /** /** * {@hide} * {@hide} Loading Loading @@ -127,15 +128,18 @@ public final class DataConnection extends StateMachine { int mRilRat; int mRilRat; boolean mRetryWhenSSChange; boolean mRetryWhenSSChange; Message mOnCompletedMsg; Message mOnCompletedMsg; final int mConnectionGeneration; ConnectionParams(ApnContext apnContext, int initialMaxRetry, int profileId, ConnectionParams(ApnContext apnContext, int initialMaxRetry, int profileId, int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg) { int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg, int connectionGeneration) { mApnContext = apnContext; mApnContext = apnContext; mInitialMaxRetry = initialMaxRetry; mInitialMaxRetry = initialMaxRetry; mProfileId = profileId; mProfileId = profileId; mRilRat = rilRadioTechnology; mRilRat = rilRadioTechnology; mRetryWhenSSChange = retryWhenSSChange; mRetryWhenSSChange = retryWhenSSChange; mOnCompletedMsg = onCompletedMsg; mOnCompletedMsg = onCompletedMsg; mConnectionGeneration = connectionGeneration; } } @Override @Override Loading Loading @@ -190,7 +194,7 @@ public final class DataConnection extends StateMachine { //***** Package visible variables //***** Package visible variables int mTag; int mTag; int mCid; int mCid; List<ApnContext> mApnContexts = null; HashMap<ApnContext, ConnectionParams> mApnContexts = null; PendingIntent mReconnectIntent = null; PendingIntent mReconnectIntent = null; RetryManager mRetryManager = new RetryManager(); RetryManager mRetryManager = new RetryManager(); Loading Loading @@ -448,7 +452,7 @@ public final class DataConnection extends StateMachine { addState(mDisconnectingErrorCreatingConnection, mDefaultState); addState(mDisconnectingErrorCreatingConnection, mDefaultState); setInitialState(mInactiveState); setInitialState(mInactiveState); mApnContexts = new ArrayList<ApnContext>(); mApnContexts = new HashMap<ApnContext, ConnectionParams>(); if (DBG) log("DataConnection constructor X"); if (DBG) log("DataConnection constructor X"); } } Loading Loading @@ -614,10 +618,13 @@ public final class DataConnection extends StateMachine { private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) { private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) { mNetworkInfo.setDetailedState(mNetworkInfo.getDetailedState(), reason, mNetworkInfo.setDetailedState(mNetworkInfo.getDetailedState(), reason, mNetworkInfo.getExtraInfo()); mNetworkInfo.getExtraInfo()); for (ApnContext apnContext : mApnContexts) { for (ConnectionParams cp : mApnContexts.values()) { ApnContext apnContext = cp.mApnContext; if (apnContext == alreadySent) continue; if (apnContext == alreadySent) continue; if (reason != null) apnContext.setReason(reason); if (reason != null) apnContext.setReason(reason); Message msg = mDct.obtainMessage(event, apnContext); Pair<ApnContext, Integer> pair = new Pair<ApnContext, Integer>(apnContext, cp.mConnectionGeneration); Message msg = mDct.obtainMessage(event, pair); AsyncResult.forMessage(msg); AsyncResult.forMessage(msg); msg.sendToTarget(); msg.sendToTarget(); } } Loading Loading @@ -1038,8 +1045,8 @@ public final class DataConnection extends StateMachine { mConnectionParams = cp; mConnectionParams = cp; mConnectionParams.mTag = mTag; mConnectionParams.mTag = mTag; if (!mApnContexts.contains(apnContext)) { if (!mApnContexts.containsKey(apnContext)) { mApnContexts.add(apnContext); mApnContexts.put(apnContext, cp); } } configureRetry(mApnSetting.canHandleType(PhoneConstants.APN_TYPE_DEFAULT)); configureRetry(mApnSetting.canHandleType(PhoneConstants.APN_TYPE_DEFAULT)); mRetryManager.setRetryCount(0); mRetryManager.setRetryCount(0); Loading Loading @@ -1544,7 +1551,8 @@ public final class DataConnection extends StateMachine { case EVENT_DISCONNECT: { case EVENT_DISCONNECT: { DisconnectParams dp = (DisconnectParams) msg.obj; DisconnectParams dp = (DisconnectParams) msg.obj; if (mApnContexts.remove(dp.mApnContext) && mApnContexts.size() == 0) { if ((mApnContexts.remove(dp.mApnContext) != null) && (mApnContexts.size() == 0)) { if (DBG) { if (DBG) { log("DcRetryingState msg.what=EVENT_DISCONNECT " + " RefCount=" log("DcRetryingState msg.what=EVENT_DISCONNECT " + " RefCount=" + mApnContexts.size() + " dp=" + dp); + mApnContexts.size() + " dp=" + dp); Loading Loading @@ -1842,10 +1850,10 @@ public final class DataConnection extends StateMachine { if (DBG) { if (DBG) { log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this); log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this); } } if (mApnContexts.contains(cp.mApnContext)) { if (mApnContexts.containsKey(cp.mApnContext)) { log("DcActiveState ERROR already added apnContext=" + cp.mApnContext); log("DcActiveState ERROR already added apnContext=" + cp.mApnContext); } else { } else { mApnContexts.add(cp.mApnContext); mApnContexts.put(cp.mApnContext, cp); if (DBG) { if (DBG) { log("DcActiveState msg.what=EVENT_CONNECT RefCount=" log("DcActiveState msg.what=EVENT_CONNECT RefCount=" + mApnContexts.size()); + mApnContexts.size()); Loading @@ -1861,7 +1869,7 @@ public final class DataConnection extends StateMachine { log("DcActiveState: EVENT_DISCONNECT dp=" + dp log("DcActiveState: EVENT_DISCONNECT dp=" + dp + " dc=" + DataConnection.this); + " dc=" + DataConnection.this); } } if (mApnContexts.contains(dp.mApnContext)) { if (mApnContexts.containsKey(dp.mApnContext)) { if (DBG) { if (DBG) { log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" + mApnContexts.size()); + mApnContexts.size()); Loading Loading @@ -2088,7 +2096,7 @@ public final class DataConnection extends StateMachine { } } // this can only happen if our exit has been called - we're already disconnected // this can only happen if our exit has been called - we're already disconnected if (mApnContexts == null) return; if (mApnContexts == null) return; for (ApnContext apnContext : mApnContexts) { for (ApnContext apnContext : mApnContexts.keySet()) { log("DcNetworkAgent: [unwanted]: disconnect apnContext=" + apnContext); log("DcNetworkAgent: [unwanted]: disconnect apnContext=" + apnContext); Message msg = mDct.obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext); Message msg = mDct.obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext); DisconnectParams dp = new DisconnectParams(apnContext, apnContext.getReason(), msg); DisconnectParams dp = new DisconnectParams(apnContext, apnContext.getReason(), msg); Loading
src/java/com/android/internal/telephony/dataconnection/DcAsyncChannel.java +4 −2 Original line number Original line Diff line number Diff line Loading @@ -368,14 +368,16 @@ public class DcAsyncChannel extends AsyncChannel { * AsyncResult.result = FailCause and AsyncResult.exception = Exception(). * AsyncResult.result = FailCause and AsyncResult.exception = Exception(). */ */ public void bringUp(ApnContext apnContext, int initialMaxRetry, int profileId, public void bringUp(ApnContext apnContext, int initialMaxRetry, int profileId, int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg) { int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg, int connectionGeneration) { if (DBG) { if (DBG) { log("bringUp: apnContext=" + apnContext + " initialMaxRetry=" + initialMaxRetry log("bringUp: apnContext=" + apnContext + " initialMaxRetry=" + initialMaxRetry + " onCompletedMsg=" + onCompletedMsg); + " onCompletedMsg=" + onCompletedMsg); } } sendMessage(DataConnection.EVENT_CONNECT, sendMessage(DataConnection.EVENT_CONNECT, new ConnectionParams(apnContext, initialMaxRetry, profileId, new ConnectionParams(apnContext, initialMaxRetry, profileId, rilRadioTechnology, retryWhenSSChange, onCompletedMsg)); rilRadioTechnology, retryWhenSSChange, onCompletedMsg, connectionGeneration)); } } /** /** Loading
src/java/com/android/internal/telephony/dataconnection/DcController.java +5 −5 Original line number Original line Diff line number Diff line Loading @@ -265,7 +265,7 @@ class DcController extends StateMachine { + " newState=" + newState.toString()); + " newState=" + newState.toString()); if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE) { if (newState.active == DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE) { if (mDct.mIsCleanupRequired) { if (mDct.mIsCleanupRequired) { apnsToCleanup.addAll(dc.mApnContexts); apnsToCleanup.addAll(dc.mApnContexts.keySet()); mDct.mIsCleanupRequired = false; mDct.mIsCleanupRequired = false; } else { } else { DcFailCause failCause = DcFailCause.fromInt(newState.status); DcFailCause failCause = DcFailCause.fromInt(newState.status); Loading @@ -275,7 +275,7 @@ class DcController extends StateMachine { mDct.sendRestartRadio(); mDct.sendRestartRadio(); } else if (mDct.isPermanentFail(failCause)) { } else if (mDct.isPermanentFail(failCause)) { if (DBG) log("onDataStateChanged: inactive, add to cleanup list"); if (DBG) log("onDataStateChanged: inactive, add to cleanup list"); apnsToCleanup.addAll(dc.mApnContexts); apnsToCleanup.addAll(dc.mApnContexts.keySet()); } else { } else { if (DBG) log("onDataStateChanged: inactive, add to retry list"); if (DBG) log("onDataStateChanged: inactive, add to retry list"); dcsToRetry.add(dc); dcsToRetry.add(dc); Loading Loading @@ -318,11 +318,11 @@ class DcController extends StateMachine { " oldLp=" + result.oldLp + " oldLp=" + result.oldLp + " newLp=" + result.newLp); " newLp=" + result.newLp); } } apnsToCleanup.addAll(dc.mApnContexts); apnsToCleanup.addAll(dc.mApnContexts.keySet()); } else { } else { if (DBG) log("onDataStateChanged: simple change"); if (DBG) log("onDataStateChanged: simple change"); for (ApnContext apnContext : dc.mApnContexts) { for (ApnContext apnContext : dc.mApnContexts.keySet()) { mPhone.notifyDataConnection( mPhone.notifyDataConnection( PhoneConstants.REASON_LINK_PROPERTIES_CHANGED, PhoneConstants.REASON_LINK_PROPERTIES_CHANGED, apnContext.getApnType()); apnContext.getApnType()); Loading @@ -334,7 +334,7 @@ class DcController extends StateMachine { } } } } } else { } else { apnsToCleanup.addAll(dc.mApnContexts); apnsToCleanup.addAll(dc.mApnContexts.keySet()); if (DBG) { if (DBG) { log("onDataStateChanged: interface change, cleanup apns=" log("onDataStateChanged: interface change, cleanup apns=" + dc.mApnContexts); + dc.mApnContexts); Loading
src/java/com/android/internal/telephony/dataconnection/DcTracker.java +34 −31 Original line number Original line Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; import android.text.TextUtils; import android.util.EventLog; import android.util.EventLog; import android.util.LocalLog; import android.util.LocalLog; import android.util.Pair; import android.view.WindowManager; import android.view.WindowManager; import android.telephony.Rlog; import android.telephony.Rlog; Loading Loading @@ -1311,6 +1312,7 @@ public final class DcTracker extends DcTrackerBase { apnContext.setDataConnectionAc(dcac); apnContext.setDataConnectionAc(dcac); apnContext.setApnSetting(apnSetting); apnContext.setApnSetting(apnSetting); int connectionGeneration = apnContext.incAndGetConnectionGeneration(); apnContext.setState(DctConstants.State.CONNECTING); apnContext.setState(DctConstants.State.CONNECTING); mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); Loading @@ -1318,7 +1320,7 @@ public final class DcTracker extends DcTrackerBase { msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE; msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE; msg.obj = apnContext; msg.obj = apnContext; dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, mAutoAttachOnCreation.get(), msg); mAutoAttachOnCreation.get(), msg, connectionGeneration); if (DBG) log("setupData: initing!"); if (DBG) log("setupData: initing!"); return true; return true; Loading Loading @@ -1821,13 +1823,9 @@ public final class DcTracker extends DcTrackerBase { DcFailCause cause = DcFailCause.UNKNOWN; DcFailCause cause = DcFailCause.UNKNOWN; boolean handleError = false; boolean handleError = false; ApnContext apnContext = null; ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete"); if(ar.userObj instanceof ApnContext){ if (apnContext == null) return; apnContext = (ApnContext)ar.userObj; } else { throw new RuntimeException("onDataSetupComplete: No apnContext"); } if (ar.exception == null) { if (ar.exception == null) { DcAsyncChannel dcac = apnContext.getDcAc(); DcAsyncChannel dcac = apnContext.getDcAc(); Loading Loading @@ -2010,6 +2008,27 @@ public final class DcTracker extends DcTrackerBase { } } } } /** * check for obsolete messages. Return ApnContext if valid, null if not */ private ApnContext getValidApnContext(AsyncResult ar, String logString) { if (ar != null && ar.userObj instanceof Pair) { Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj; ApnContext apnContext = pair.first; if (apnContext != null) { if (apnContext.getConnectionGeneration() == pair.second) { return apnContext; } else { log("ignoring obsolete " + logString); return null; } } } throw new RuntimeException(logString + ": No apnContext"); } /** /** * Error has occurred during the SETUP {aka bringUP} request and the DCT * Error has occurred during the SETUP {aka bringUP} request and the DCT * should either try the next waiting APN or start over from the * should either try the next waiting APN or start over from the Loading @@ -2019,13 +2038,9 @@ public final class DcTracker extends DcTrackerBase { @Override @Override protected void onDataSetupCompleteError(AsyncResult ar) { protected void onDataSetupCompleteError(AsyncResult ar) { String reason = ""; String reason = ""; ApnContext apnContext = null; ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError"); if(ar.userObj instanceof ApnContext){ if (apnContext == null) return; apnContext = (ApnContext)ar.userObj; } else { throw new RuntimeException("onDataSetupCompleteError: No apnContext"); } // See if there are more APN's to try // See if there are more APN's to try if (apnContext.getWaitingApns().isEmpty()) { if (apnContext.getWaitingApns().isEmpty()) { Loading Loading @@ -2059,15 +2074,9 @@ public final class DcTracker extends DcTrackerBase { * Called when EVENT_DISCONNECT_DONE is received. * Called when EVENT_DISCONNECT_DONE is received. */ */ @Override @Override protected void onDisconnectDone(int connId, AsyncResult ar) { protected void onDisconnectDone(AsyncResult ar) { ApnContext apnContext = null; ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone"); if (apnContext == null) return; if (ar.userObj instanceof ApnContext) { apnContext = (ApnContext) ar.userObj; } else { loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore"); return; } if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext); if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext); apnContext.setState(DctConstants.State.IDLE); apnContext.setState(DctConstants.State.IDLE); Loading Loading @@ -2138,16 +2147,10 @@ public final class DcTracker extends DcTrackerBase { * Called when EVENT_DISCONNECT_DC_RETRYING is received. * Called when EVENT_DISCONNECT_DC_RETRYING is received. */ */ @Override @Override protected void onDisconnectDcRetrying(int connId, AsyncResult ar) { protected void onDisconnectDcRetrying(AsyncResult ar) { // We could just do this in DC!!! // We could just do this in DC!!! ApnContext apnContext = null; ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying"); if (apnContext == null) return; if (ar.userObj instanceof ApnContext) { apnContext = (ApnContext) ar.userObj; } else { loge("onDisconnectDcRetrying: Invalid ar in onDisconnectDone, ignore"); return; } apnContext.setState(DctConstants.State.RETRYING); apnContext.setState(DctConstants.State.RETRYING); if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext); if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext); Loading