summaryrefslogtreecommitdiffstats
path: root/telephony
diff options
context:
space:
mode:
authorWink Saville <wink@google.com>2011-04-01 10:11:09 -0700
committerWink Saville <wink@google.com>2011-04-01 10:11:18 -0700
commit95bc2b7564b201d10f2a5e319f69972e18c58261 (patch)
tree62a3e6ce7061cc5c5994d77a73a6095d66c27e04 /telephony
parent77de14d64f1b2a36a117869d412a3a74e6823cd7 (diff)
downloadframeworks_base-95bc2b7564b201d10f2a5e319f69972e18c58261.zip
frameworks_base-95bc2b7564b201d10f2a5e319f69972e18c58261.tar.gz
frameworks_base-95bc2b7564b201d10f2a5e319f69972e18c58261.tar.bz2
Airplane mode on always timed out when camping on LTE
While on LTE, GsmDataConnectionTracker is implicitly associated with CdmaServiceTracker. CdmaServiceTracker asynchronously waits for the disconnection of data before turning off the Radio but GsmDataConnection does not notify the disconnection due to different logic in GsmServiceTracker. This fix is to have common airplane mode toggle logic on both GSM and CDMA flavors. Change-Id: I67ff82a59a2243856ae3e7c5e37b5726bcbf3c94
Diffstat (limited to 'telephony')
-rw-r--r--telephony/java/com/android/internal/telephony/ServiceStateTracker.java76
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java5
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java62
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java22
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java20
5 files changed, 104 insertions, 81 deletions
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 1b5bad9..5501361 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -68,6 +68,9 @@ public abstract class ServiceStateTracker extends Handler {
protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
+ /* Radio power off pending flag and tag counter */
+ private boolean mPendingRadioPowerOffAfterDataOff = false;
+ private int mPendingRadioPowerOffAfterDataOffTag = 0;
protected static final boolean DBG = true;
@@ -77,8 +80,6 @@ public abstract class ServiceStateTracker extends Handler {
/** Waiting period before recheck gprs and voice registration. */
public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
- public static final int DATA_STATE_POLL_SLEEP_MS = 100;
-
/** GSM events */
protected static final int EVENT_RADIO_STATE_CHANGED = 1;
protected static final int EVENT_NETWORK_STATE_CHANGED = 2;
@@ -262,7 +263,29 @@ public abstract class ServiceStateTracker extends Handler {
}
}
- public abstract void handleMessage(Message msg);
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_SET_RADIO_POWER_OFF:
+ synchronized(this) {
+ if (mPendingRadioPowerOffAfterDataOff &&
+ (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
+ if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
+ hangupAndPowerOff();
+ mPendingRadioPowerOffAfterDataOffTag += 1;
+ mPendingRadioPowerOffAfterDataOff = false;
+ } else {
+ log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
+ "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
+ }
+ }
+ break;
+
+ default:
+ log("Unhandled message with number: " + msg.what);
+ break;
+ }
+ }
protected abstract Phone getPhone();
protected abstract void handlePollStateResult(int what, AsyncResult ar);
@@ -370,7 +393,52 @@ public abstract class ServiceStateTracker extends Handler {
*
* Hang up the existing voice calls to decrease call drop rate.
*/
- public abstract void powerOffRadioSafely();
+ public void powerOffRadioSafely(DataConnectionTracker dcTracker) {
+ synchronized (this) {
+ if (!mPendingRadioPowerOffAfterDataOff) {
+ if (dcTracker.isAnyActiveDataConnections()) {
+ dcTracker.cleanUpAllConnections(null);
+ Message msg = Message.obtain(this);
+ msg.what = EVENT_SET_RADIO_POWER_OFF;
+ msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
+ if (sendMessageDelayed(msg, 30000)) {
+ if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
+ mPendingRadioPowerOffAfterDataOff = true;
+ } else {
+ log("Cannot send delayed Msg, turn off radio right away.");
+ hangupAndPowerOff();
+ }
+ } else {
+ dcTracker.cleanUpAllConnections(null);
+ if (DBG) log("Data disconnected, turn off radio right away.");
+ hangupAndPowerOff();
+ }
+ }
+ }
+ }
+
+ /**
+ * process the pending request to turn radio off after data is disconnected
+ *
+ * return true if there is pending request to process; false otherwise.
+ */
+ public boolean processPendingRadioPowerOffAfterDataOff() {
+ synchronized(this) {
+ if (mPendingRadioPowerOffAfterDataOff) {
+ if (DBG) log("Process pending request to turn radio off.");
+ mPendingRadioPowerOffAfterDataOffTag += 1;
+ hangupAndPowerOff();
+ mPendingRadioPowerOffAfterDataOff = false;
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Hang up all voice call and turn off radio. Implemented by derived class.
+ */
+ protected abstract void hangupAndPowerOff();
/** Cancel a pending (if any) pollState() operation */
protected void cancelPollState() {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 3d10c9c..05361cd 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -907,6 +907,11 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
@Override
+ public boolean isAnyActiveDataConnections() {
+ return (mState != State.IDLE);
+ }
+
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[CdmaDataConnectionTracker] " + s);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 4c6cd17..07f9e38 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -139,8 +139,6 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
private boolean isEriTextLoaded = false;
private boolean isSubscriptionFromRuim = false;
- private boolean mPendingRadioPowerOffAfterDataOff = false;
-
/* Used only for debugging purposes. */
private String mRegistrationDeniedReason;
@@ -485,18 +483,8 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
}
break;
- case EVENT_SET_RADIO_POWER_OFF:
- synchronized(this) {
- if (mPendingRadioPowerOffAfterDataOff) {
- if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
- hangupAndPowerOff();
- mPendingRadioPowerOffAfterDataOff = false;
- }
- }
- break;
-
default:
- Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
+ super.handleMessage(msg);
break;
}
}
@@ -513,35 +501,10 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
DataConnectionTracker dcTracker = phone.mDataConnection;
// If it's on and available and we want it off gracefully
- powerOffRadioSafely();
+ powerOffRadioSafely(dcTracker);
} // Otherwise, we're in the desired state
}
- // TODO: Consider moving this method to DataConnectionTracker
- @Override
- public void powerOffRadioSafely() {
- DataConnectionTracker dcTracker = phone.mDataConnection;
-
- synchronized (this) {
- if (!mPendingRadioPowerOffAfterDataOff) {
- if (dcTracker.isAnyActiveDataConnections()) {
- dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
- if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
- if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
- mPendingRadioPowerOffAfterDataOff = true;
- } else {
- Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
- hangupAndPowerOff();
- }
- } else {
- dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
- if (DBG) log("Data disconnected, turn off radio right away.");
- hangupAndPowerOff();
- }
- }
- }
- }
-
@Override
protected void updateSpnDisplay() {
// TODO RUIM SPN is not implemented, EF_SPN has to be read and Display Condition
@@ -1658,24 +1621,6 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
}
/**
- * process the pending request to turn radio off after data is disconnected
- *
- * return true if there is pending request to process; false otherwise.
- */
- public boolean processPendingRadioPowerOffAfterDataOff() {
- synchronized(this) {
- if (mPendingRadioPowerOffAfterDataOff) {
- if (DBG) log("Process pending request to turn radio off.");
- removeMessages(EVENT_SET_RADIO_POWER_OFF);
- hangupAndPowerOff();
- mPendingRadioPowerOffAfterDataOff = false;
- return true;
- }
- return false;
- }
- }
-
- /**
* Returns OTASP_UNKNOWN, OTASP_NEEDED or OTASP_NOT_NEEDED
*/
int getOtasp() {
@@ -1701,7 +1646,8 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
Log.d(LOG_TAG, "[CdmaServiceStateTracker] " + s);
}
- private void hangupAndPowerOff() {
+ @Override
+ protected void hangupAndPowerOff() {
// hang up all active voice calls
phone.mCT.ringingCall.hangupIfAlive();
phone.mCT.backgroundCall.hangupIfAlive();
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 4d94b27..7dad459 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -1073,7 +1073,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
protected void restartRadio() {
log("************TURN OFF RADIO**************");
cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
- mPhone.getServiceStateTracker().powerOffRadioSafely();
+ mPhone.getServiceStateTracker().powerOffRadioSafely(this);
/* Note: no need to call setRadioPower(true). Assuming the desired
* radio power state is still ON (as tracked by ServiceStateTracker),
* ServiceStateTracker will call setRadioPower when it receives the
@@ -1491,14 +1491,25 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
+
+ apnContext.setState(State.IDLE);
+ apnContext.setApnSetting(null);
+
+ // if all data connection are gone, check whether Airplane mode request was
+ // pending.
+ if (!isConnected()) {
+ if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
+ // Radio will be turned off. No need to retry data setup
+ return;
+ }
+ }
+
// Check if APN disabled.
if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
mApnContexts.remove(apnContext.getApnType());
return;
}
- apnContext.setState(State.IDLE);
- apnContext.setApnSetting(null);
if (TextUtils.equals(apnContext.getApnType(), Phone.APN_TYPE_DEFAULT)
&& retryAfterDisconnected(apnContext.getReason())) {
SystemProperties.set("gsm.defaultpdpcontext.active", "false");
@@ -1894,6 +1905,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
@Override
+ public boolean isAnyActiveDataConnections() {
+ return isConnected();
+ }
+
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[GsmDataConnectionTracker] " + s);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 3f521a0..ef3eed8 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -164,8 +164,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
static final int PS_NOTIFICATION = 888; // Id to update and cancel PS restricted
static final int CS_NOTIFICATION = 999; // Id to update and cancel CS restricted
- static final int MAX_NUM_DATA_STATE_READS = 15;
-
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -459,7 +457,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
break;
default:
- Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
+ super.handleMessage(msg);
break;
}
}
@@ -471,23 +469,13 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
cm.setRadioPower(true, null);
} else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
// If it's on and available and we want it off gracefully
- powerOffRadioSafely();
+ DataConnectionTracker dcTracker = phone.mDataConnection;
+ powerOffRadioSafely(dcTracker);
} // Otherwise, we're in the desired state
}
@Override
- public void powerOffRadioSafely() {
- // Cleanup all connections
- DataConnectionTracker dcTracker = phone.mDataConnection;
- Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_ALL_CONNECTIONS);
- dcTracker.sendMessage(msg);
-
- // poll data state up to 15 times, with a 100ms delay
- // totaling 1.5 sec. Normal data disable action will finish in 100ms.
- for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) {
- SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
- }
-
+ protected void hangupAndPowerOff() {
// hang up all active voice calls
if (phone.isInCall()) {
phone.mCT.ringingCall.hangupIfAlive();