Merge "Airplane mode on always timed out when camping on LTE" into honeycomb-LTE

This commit is contained in:
Wink Saville
2011-04-01 10:28:22 -07:00
committed by Android (Google) Code Review
5 changed files with 104 additions and 81 deletions

View File

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

View File

@@ -906,6 +906,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);

View File

@@ -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
@@ -1657,24 +1620,6 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
return mIsMinInfoReady;
}
/**
* 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
*/
@@ -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();

View File

@@ -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");
@@ -1893,6 +1904,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);

View File

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