diff options
author | Wink Saville <wink@google.com> | 2011-06-27 19:57:20 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2011-06-27 19:57:20 -0700 |
commit | cf2980ffef2780ab41eb196f398df482b105312e (patch) | |
tree | f4da5e1628a7a92ecbb87762c16f8bb5b5568569 /telephony | |
parent | 229ff64bde1f8ffeb23a305178a7f6a57bffe1e5 (diff) | |
parent | 29d1dde972acaaf3685b60de3da00c1809c510f9 (diff) | |
download | frameworks_base-cf2980ffef2780ab41eb196f398df482b105312e.zip frameworks_base-cf2980ffef2780ab41eb196f398df482b105312e.tar.gz frameworks_base-cf2980ffef2780ab41eb196f398df482b105312e.tar.bz2 |
am 29d1dde9: Merge "Data connection retry pattern could be broken by PDP sharing" into honeycomb-LTE
* commit '29d1dde972acaaf3685b60de3da00c1809c510f9':
Data connection retry pattern could be broken by PDP sharing
Diffstat (limited to 'telephony')
4 files changed, 305 insertions, 96 deletions
diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java index 5ec00e8..a52f1ca 100644 --- a/telephony/java/com/android/internal/telephony/ApnContext.java +++ b/telephony/java/com/android/internal/telephony/ApnContext.java @@ -16,8 +16,6 @@ package com.android.internal.telephony; -import android.app.PendingIntent; - import android.util.Log; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; @@ -49,8 +47,6 @@ public class ApnContext { String mReason; - PendingIntent mReconnectIntent; - /** * user/app requested connection on this APN */ @@ -90,9 +86,9 @@ public class ApnContext { public synchronized void setDataConnectionAc(DataConnectionAc dcac) { if (dcac != null) { - dcac.addApnContext(this); + dcac.addApnContextSync(this); } else { - if (mDataConnectionAc != null) mDataConnectionAc.removeApnContext(this); + if (mDataConnectionAc != null) mDataConnectionAc.removeApnContextSync(this); } mDataConnectionAc = dcac; } @@ -169,16 +165,6 @@ public class ApnContext { return mReason; } - public synchronized void setReconnectIntent(PendingIntent intent) { - if (DBG) - log("set ReconnectIntent for type " + mApnType); - mReconnectIntent = intent; - } - - public synchronized PendingIntent getReconnectIntent() { - return mReconnectIntent; - } - public boolean isReady() { return mDataEnabled.get() && mDependencyMet.get(); } diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java index cb8b0e5..5c84fdc 100644 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ b/telephony/java/com/android/internal/telephony/DataConnection.java @@ -22,6 +22,7 @@ import com.android.internal.util.Protocol; import com.android.internal.util.State; import com.android.internal.util.StateMachine; +import android.app.PendingIntent; import android.net.LinkAddress; import android.net.LinkCapabilities; import android.net.LinkProperties; @@ -35,8 +36,10 @@ import android.os.Parcelable; import android.os.SystemProperties; import android.text.TextUtils; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** @@ -68,6 +71,8 @@ public abstract class DataConnection extends StateMachine { protected static int mCount; protected AsyncChannel mAc; + private List<ApnContext> mApnList = null; + PendingIntent mReconnectIntent = null; /** * Used internally for saving connecting parameters. @@ -250,6 +255,8 @@ public abstract class DataConnection extends StateMachine { addState(mDisconnectingState, mDefaultState); addState(mDisconnectingErrorCreatingConnection, mDefaultState); setInitialState(mInactiveState); + + mApnList = new ArrayList<ApnContext>(); if (DBG) log("DataConnection constructor X"); } @@ -662,7 +669,41 @@ public abstract class DataConnection extends StateMachine { mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_REFCOUNT, mRefCount); break; } - + case DataConnectionAc.REQ_ADD_APNCONTEXT: { + ApnContext apnContext = (ApnContext) msg.obj; + if (VDBG) log("REQ_ADD_APNCONTEXT apn=" + apnContext.getApnType()); + if (!mApnList.contains(apnContext)) { + mApnList.add(apnContext); + } + mAc.replyToMessage(msg, DataConnectionAc.RSP_ADD_APNCONTEXT); + break; + } + case DataConnectionAc.REQ_REMOVE_APNCONTEXT: { + ApnContext apnContext = (ApnContext) msg.obj; + if (VDBG) log("REQ_REMOVE_APNCONTEXT apn=" + apnContext.getApnType()); + mApnList.remove(apnContext); + mAc.replyToMessage(msg, DataConnectionAc.RSP_REMOVE_APNCONTEXT); + break; + } + case DataConnectionAc.REQ_GET_APNCONTEXT_LIST: { + if (VDBG) log("REQ_GET_APNCONTEXT_LIST num in list=" + mApnList.size()); + mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNCONTEXT_LIST, + new ArrayList(mApnList)); + break; + } + case DataConnectionAc.REQ_SET_RECONNECT_INTENT: { + PendingIntent intent = (PendingIntent) msg.obj; + if (VDBG) log("REQ_SET_RECONNECT_INTENT"); + mReconnectIntent = intent; + mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_RECONNECT_INTENT); + break; + } + case DataConnectionAc.REQ_GET_RECONNECT_INTENT: { + if (VDBG) log("REQ_GET_RECONNECT_INTENT"); + mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_RECONNECT_INTENT, + mReconnectIntent); + break; + } case EVENT_CONNECT: if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected"); ConnectionParams cp = (ConnectionParams) msg.obj; diff --git a/telephony/java/com/android/internal/telephony/DataConnectionAc.java b/telephony/java/com/android/internal/telephony/DataConnectionAc.java index e23f1cc..309dbed 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionAc.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionAc.java @@ -19,6 +19,7 @@ package com.android.internal.telephony; import com.android.internal.util.AsyncChannel; import com.android.internal.util.Protocol; +import android.app.PendingIntent; import android.net.LinkCapabilities; import android.net.LinkProperties; import android.net.ProxyProperties; @@ -26,8 +27,6 @@ import android.os.Message; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.List; /** * AsyncChannel to a DataConnection @@ -35,7 +34,6 @@ import java.util.List; public class DataConnectionAc extends AsyncChannel { private static final boolean DBG = false; private String mLogTag; - private List<ApnContext> mApnList = null; public DataConnection dataConnection; @@ -68,6 +66,21 @@ public class DataConnectionAc extends AsyncChannel { public static final int REQ_GET_REFCOUNT = BASE + 16; public static final int RSP_GET_REFCOUNT = BASE + 17; + public static final int REQ_ADD_APNCONTEXT = BASE + 18; + public static final int RSP_ADD_APNCONTEXT = BASE + 19; + + public static final int REQ_REMOVE_APNCONTEXT = BASE + 20; + public static final int RSP_REMOVE_APNCONTEXT = BASE + 21; + + public static final int REQ_GET_APNCONTEXT_LIST = BASE + 22; + public static final int RSP_GET_APNCONTEXT_LIST = BASE + 23; + + public static final int REQ_SET_RECONNECT_INTENT = BASE + 24; + public static final int RSP_SET_RECONNECT_INTENT = BASE + 25; + + public static final int REQ_GET_RECONNECT_INTENT = BASE + 26; + public static final int RSP_GET_RECONNECT_INTENT = BASE + 27; + /** * enum used to notify action taken or necessary to be * taken after the link property is changed. @@ -91,7 +104,6 @@ public class DataConnectionAc extends AsyncChannel { public DataConnectionAc(DataConnection dc, String logTag) { dataConnection = dc; mLogTag = logTag; - mApnList = Collections.synchronizedList(new ArrayList<ApnContext>()); } /** @@ -379,32 +391,147 @@ public class DataConnectionAc extends AsyncChannel { } /** - * Add ApnContext association. + * Request to add ApnContext association. + * Response RSP_ADD_APNCONTEXT when complete. + */ + public void reqAddApnContext(ApnContext apnContext) { + Message response = sendMessageSynchronously(REQ_ADD_APNCONTEXT, apnContext); + if (DBG) log("reqAddApnContext"); + } + + /** + * Add ApnContext association synchronoulsy. * * @param ApnContext to associate */ - public void addApnContext(ApnContext apnContext) { - if (!mApnList.contains(apnContext)) { - mApnList.add(apnContext); + public void addApnContextSync(ApnContext apnContext) { + Message response = sendMessageSynchronously(REQ_ADD_APNCONTEXT, apnContext); + if ((response != null) && (response.what == RSP_ADD_APNCONTEXT)) { + if (DBG) log("addApnContext ok"); + } else { + log("addApnContext error response=" + response); } } /** + * Request to remove ApnContext association. + * Response RSP_REMOVE_APNCONTEXT when complete. + */ + public void reqRemomveApnContext(ApnContext apnContext) { + Message response = sendMessageSynchronously(REQ_REMOVE_APNCONTEXT, apnContext); + if (DBG) log("reqRemomveApnContext"); + } + + /** * Remove ApnContext associateion. * * @param ApnContext to dissociate */ - public void removeApnContext(ApnContext apnContext) { - mApnList.remove(apnContext); + public void removeApnContextSync(ApnContext apnContext) { + Message response = sendMessageSynchronously(REQ_REMOVE_APNCONTEXT, apnContext); + if ((response != null) && (response.what == RSP_REMOVE_APNCONTEXT)) { + if (DBG) log("removeApnContext ok"); + } else { + log("removeApnContext error response=" + response); + } + } + + /** + * Request to retrive ApnContext List associated with DC. + * Response RSP_GET_APNCONTEXT_LIST when complete. + */ + public void reqGetApnList(ApnContext apnContext) { + Message response = sendMessageSynchronously(REQ_GET_APNCONTEXT_LIST); + if (DBG) log("reqGetApnList"); + } + + /** + * Retrieve Collection of ApnContext from the response message. + * + * @param Message sent from DC in response to REQ_GET_APNCONTEXT_LIST. + * @return Collection of ApnContext + */ + public Collection<ApnContext> rspApnList(Message response) { + Collection<ApnContext> retVal = (Collection<ApnContext>)response.obj; + if (retVal == null) retVal = new ArrayList<ApnContext>(); + return retVal; } /** - * Retrieve collection of ApnContext currently associated with the DataConnectionAc. + * Retrieve collection of ApnContext currently associated with + * the DataConnectionA synchronously. * * @return Collection of ApnContext */ - public Collection<ApnContext> getApnList() { - return mApnList; + public Collection<ApnContext> getApnListSync() { + Message response = sendMessageSynchronously(REQ_GET_APNCONTEXT_LIST); + if ((response != null) && (response.what == RSP_GET_APNCONTEXT_LIST)) { + if (DBG) log("getApnList ok"); + return rspApnList(response); + } else { + log("getApnList error response=" + response); + // return dummy list with no entry + return new ArrayList<ApnContext>(); + } + } + + /** + * Request to set Pending ReconnectIntent to DC. + * Response RSP_SET_RECONNECT_INTENT when complete. + */ + public void reqSetReconnectIntent(PendingIntent intent) { + Message response = sendMessageSynchronously(REQ_SET_RECONNECT_INTENT, intent); + if (DBG) log("reqSetReconnectIntent"); + } + + /** + * Set pending reconnect intent to DC synchronously. + * + * @param PendingIntent to set. + */ + public void setReconnectIntentSync(PendingIntent intent) { + Message response = sendMessageSynchronously(REQ_SET_RECONNECT_INTENT, intent); + if ((response != null) && (response.what == RSP_SET_RECONNECT_INTENT)) { + if (DBG) log("setReconnectIntent ok"); + } else { + log("setReconnectIntent error response=" + response); + } + } + + /** + * Request to get Pending ReconnectIntent to DC. + * Response RSP_GET_RECONNECT_INTENT when complete. + */ + public void reqGetReconnectIntent() { + Message response = sendMessageSynchronously(REQ_GET_RECONNECT_INTENT); + if (DBG) log("reqGetReconnectIntent"); + } + + /** + * Retrieve reconnect intent from response message from DC. + * + * @param Message which contains the reconnect intent. + * @return PendingIntent from the response. + */ + public PendingIntent rspReconnectIntent(Message response) { + PendingIntent retVal = (PendingIntent) response.obj; + return retVal; + } + + /** + * Retrieve reconnect intent currently set in DC synchronously. + * + * @return PendingIntent reconnect intent current ly set in DC + */ + public PendingIntent getReconnectIntentSync() { + Message response = sendMessageSynchronously(REQ_GET_RECONNECT_INTENT); + if ((response != null) && (response.what == RSP_GET_RECONNECT_INTENT)) { + if (DBG) log("getReconnectIntent ok"); + return rspReconnectIntent(response); + } else { + log("getReconnectIntent error response=" + response); + return null; + } } private void log(String s) { diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 1ac012f..5fc0bf9 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -125,14 +125,20 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (DBG) log("GPRS reconnect alarm. Previous state was " + mState); String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON); - String type = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE); - ApnContext apnContext = mApnContexts.get(type); - if (apnContext != null) { - apnContext.setReason(reason); - if (apnContext.getState() == State.FAILED) { - apnContext.setState(State.IDLE); + int connectionId = intent.getIntExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, -1); + + DataConnectionAc dcac= mDataConnectionAsyncChannels.get(connectionId); + + if (dcac != null) { + for (ApnContext apnContext : dcac.getApnListSync()) { + apnContext.setReason(reason); + if (apnContext.getState() == State.FAILED) { + apnContext.setState(State.IDLE); + } + sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, apnContext)); } - sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, apnContext)); + // Alram had expired. Clear pending intent recorded on the DataConnection. + dcac.setReconnectIntentSync(null); } } @@ -591,17 +597,25 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } private void setupDataOnReadyApns(String reason) { + // Stop reconnect alarms on all data connections pending + // retry. Reset ApnContext state to IDLE. + for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) { + if (dcac.getReconnectIntentSync() != null) { + cancelReconnectAlarm(dcac); + if (dcac.dataConnection != null) { + dcac.dataConnection.resetRetryCount(); + } + + Collection<ApnContext> apnList = dcac.getApnListSync(); + for (ApnContext apnContext : apnList) { + apnContext.setState(State.IDLE); + } + } + } + // Only check for default APN state for (ApnContext apnContext : mApnContexts.values()) { if (apnContext.isReady()) { - if (apnContext.getState() == State.FAILED) { - cleanApnContextBeforeRestart(apnContext); - if (apnContext.getDataConnection() != null) { - apnContext.getDataConnection().resetRetryCount(); - } - } - // Do not start ApnContext in SCANNING state - // FAILED state must be reset to IDLE by now if (apnContext.getState() == State.IDLE) { apnContext.setReason(reason); trySetupData(apnContext); @@ -751,53 +765,70 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (DBG) { log("cleanUpConnection: tearDown=" + tearDown + " reason=" + apnContext.getReason()); } - if (tearDown && cleanApnContextBeforeRestart(apnContext)) { - // if the request is tearDown and ApnContext does not hold an active connection, - // we're ok to return here. - return; - } - DataConnectionAc dcac = apnContext.getDataConnectionAc(); - if (tearDown && (dcac != null)) { - if (DBG) log("cleanUpConnection: tearing down"); - Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext); - apnContext.getDataConnection().tearDown(apnContext.getReason(), msg); - apnContext.setState(State.DISCONNECTING); + if (tearDown) { + boolean isConnected = (apnContext.getState() != State.IDLE + && apnContext.getState() != State.FAILED); + if (!isConnected) { + // The request is tearDown and but ApnContext is not connected. + // If apnContext is not enabled anymore, break the linkage to the DCAC/DC. + apnContext.setState(State.IDLE); + if (!apnContext.isReady()) { + apnContext.setDataConnection(null); + apnContext.setDataConnectionAc(null); + } + } else { + // Connection is still there. Try to clean up. + if (dcac != null) { + if (apnContext.getState() != State.DISCONNECTING) { + if (DBG) log("cleanUpConnection: tearing down"); + Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext); + apnContext.getDataConnection().tearDown(apnContext.getReason(), msg); + apnContext.setState(State.DISCONNECTING); + } else { + // apn is connected but no reference to dcac. + // Should not be happen, but reset the state in case. + apnContext.setState(State.IDLE); + mPhone.notifyDataConnection(apnContext.getReason(), + apnContext.getApnType()); + } + } + } } else { + // force clean up the data connection. if (dcac != null) dcac.resetSync(); apnContext.setState(State.IDLE); mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); apnContext.setDataConnection(null); apnContext.setDataConnectionAc(null); } + + // make sure reconnection alarm is cleaned up if there is no ApnContext + // associated to the connection. + if (dcac != null) { + Collection<ApnContext> apnList = dcac.getApnListSync(); + if (apnList.isEmpty()) { + cancelReconnectAlarm(dcac); + } + } } /** - * @param APNContext to clean - * @return true if ApnContext is not connected anymore. - * false if ApnContext still holds a connection. + * Cancels the alarm associated with DCAC. + * + * @param DataConnectionAc on which the alarm should be stopped. */ - private boolean cleanApnContextBeforeRestart(ApnContext apnContext) { - if (apnContext == null) return true; + private void cancelReconnectAlarm(DataConnectionAc dcac) { + if (dcac == null) return; - // Clear the reconnect alarm, if set. - if (apnContext.getReconnectIntent() != null) { - AlarmManager am = - (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - am.cancel(apnContext.getReconnectIntent()); - apnContext.setReconnectIntent(null); - } + PendingIntent intent = dcac.getReconnectIntentSync(); - if (apnContext.getState() == State.IDLE || apnContext.getState() == State.DISCONNECTING) { - if (DBG) log("cleanUpConnection: state= " + apnContext.getState()); - return true; - } - - if (apnContext.getState() == State.FAILED) { - apnContext.setState(State.IDLE); - return true; + if (intent != null) { + AlarmManager am = + (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); + am.cancel(intent); + dcac.setReconnectIntentSync(null); } - return false; } /** @@ -936,17 +967,26 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { configureRetry(dc, apnContext.getApnType()); } apnContext.setDataConnectionAc(dcac); - apnContext.setApnSetting(apn); apnContext.setDataConnection(dc); } + apnContext.setApnSetting(apn); + apnContext.setState(State.INITING); + mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); + // If reconnect alarm is active on this DataConnection, wait for the alarm being + // fired so that we don't disruppt data retry pattern engaged. + if (apnContext.getDataConnectionAc().getReconnectIntentSync() != null) { + if (DBG) log("setupData: data reconnection pending"); + apnContext.setState(State.FAILED); + mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); + return true; + } + Message msg = obtainMessage(); msg.what = EVENT_DATA_SETUP_COMPLETE; msg.obj = apnContext; dc.bringUp(msg, apn); - apnContext.setState(State.INITING); - mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); if (DBG) log("setupData: initing!"); return true; } @@ -1063,13 +1103,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { // no associated DataConnection found. Ignore. if (dcac == null) continue; - Collection<ApnContext> apns = dcac.getApnList(); + Collection<ApnContext> apns = dcac.getApnListSync(); // filter out ApnContext with "Connected" state. ArrayList<ApnContext> connectedApns = new ArrayList<ApnContext>(); for (ApnContext apnContext : apns) { - if ((apnContext != null) && - (apnContext.getState() == State.CONNECTED)) { + if (apnContext.getState() == State.CONNECTED) { connectedApns.add(apnContext); } } @@ -1449,21 +1488,28 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { + (delay / 1000) + "s"); } + DataConnectionAc dcac = apnContext.getDataConnectionAc(); + + if ((dcac == null) || (dcac.dataConnection == null)) { + // should not happen, but just in case. + loge("null dcac or dc."); + return; + } + AlarmManager am = (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - // TODO : Register the receiver only once maybe in baseclass. - IntentFilter filter = new IntentFilter(); - filter.addAction(INTENT_RECONNECT_ALARM + '.'+apnContext.getApnType()); - mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); - - Intent intent = new Intent(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType()); + Intent intent = new Intent(INTENT_RECONNECT_ALARM + '.' + + dcac.dataConnection.getDataConnectionId()); intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason()); - intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnContext.getApnType()); - apnContext.setReconnectIntent(PendingIntent.getBroadcast ( - mPhone.getContext(), 0, intent, 0)); + intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, + dcac.dataConnection.getDataConnectionId()); + + PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0, + intent, 0); + dcac.setReconnectIntentSync(alarmIntent); am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + delay, apnContext.getReconnectIntent()); + SystemClock.elapsedRealtime() + delay, alarmIntent); } @@ -1768,9 +1814,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } apnContext.setState(State.IDLE); - apnContext.setApnSetting(null); - apnContext.setDataConnection(null); - apnContext.setDataConnectionAc(null); mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); @@ -1779,6 +1822,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (!isConnected()) { if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) { // Radio will be turned off. No need to retry data setup + apnContext.setApnSetting(null); + apnContext.setDataConnection(null); + apnContext.setDataConnectionAc(null); return; } } @@ -1790,6 +1836,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { // we're not tying up the RIL command channel. // This also helps in any external dependency to turn off the context. startAlarmForReconnect(APN_DELAY_MILLIS, apnContext); + } else { + apnContext.setApnSetting(null); + apnContext.setDataConnection(null); + apnContext.setDataConnectionAc(null); } } @@ -1915,6 +1965,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { " status=" + status); } + // install reconnect intent filter for this data connection. + IntentFilter filter = new IntentFilter(); + filter.addAction(INTENT_RECONNECT_ALARM + '.' + id); + mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); + if (DBG) log("createDataConnection() X id=" + id); return conn; } |