summaryrefslogtreecommitdiffstats
path: root/telephony
diff options
context:
space:
mode:
authorWink Saville <wink@google.com>2011-06-27 19:57:20 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2011-06-27 19:57:20 -0700
commitcf2980ffef2780ab41eb196f398df482b105312e (patch)
treef4da5e1628a7a92ecbb87762c16f8bb5b5568569 /telephony
parent229ff64bde1f8ffeb23a305178a7f6a57bffe1e5 (diff)
parent29d1dde972acaaf3685b60de3da00c1809c510f9 (diff)
downloadframeworks_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')
-rw-r--r--telephony/java/com/android/internal/telephony/ApnContext.java18
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java43
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionAc.java153
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java187
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;
}