Replace loop-delay in setPowerStateToDesired() with async approach

Issues to be addressed:
The method setPowerStateToDesired() in CdmaServiceStateTracker class sends
a msg to CdmaDataConnectionTracker class to deactive data call, and then starts
a loop which calls SystemClock.sleep() to wait for several seconds.The purpose
of this is to wait for data-disconnection before sending RADIO_POWER off request.
However, the CdmaServiceStateTracker and CdmaDataConnectionTracker are running in
the same process so that the CdmaDataConnectionTracker is not able to process the
message to deactive data before the loop ends.

The patch includes the following changes:
1) In setPowerStateToDesired() in CdmaServiceStateTracker, replace implementation
   of loop-delay by sending a delayed msg to set RADIO_POWER off.

2) In CdmaDataConnectionTracker, when getting EVENT_DISCONNECT_DONE, call a new
   method in CdmaServiceStateTracker to process pending request to turn RADIO_POWER
   off.
This commit is contained in:
Yong Zhang
2009-08-14 10:23:53 -05:00
committed by Wink Saville
parent e6a9bcb7e8
commit fa2944d93f
3 changed files with 51 additions and 12 deletions

View File

@ -116,6 +116,7 @@ public abstract class ServiceStateTracker extends Handler {
protected static final int EVENT_NV_READY = 35;
protected static final int EVENT_ERI_FILE_LOADED = 36;
protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE = 37;
protected static final int EVENT_SET_RADIO_POWER_OFF = 38;
//***** Time Zones
protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";

View File

@ -48,6 +48,7 @@ import com.android.internal.telephony.DataConnection.FailCause;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
import java.util.ArrayList;
@ -770,6 +771,10 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
reason = (String) ar.userObj;
}
setState(State.IDLE);
CdmaServiceStateTracker ssTracker = mCdmaPhone.mSST;
ssTracker.processPendingRadioPowerOffAfterDataOff();
phone.notifyDataConnection(reason);
if (retryAfterDisconnected(reason)) {
trySetupData(reason);

View File

@ -131,6 +131,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
private boolean isEriTextLoaded = false;
private boolean isSubscriptionFromRuim = false;
private boolean mPendingRadioPowerOffAfterDataOff = false;
// Registration Denied Reason, General/Authentication Failure, used only for debugging purposes
private String mRegistrationDeniedReason;
@ -520,6 +522,16 @@ final 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.");
cm.setRadioPower(false, null);
mPendingRadioPowerOffAfterDataOff = false;
}
}
break;
default:
Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
break;
@ -548,20 +560,23 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
dcTracker.sendMessage(msg);
// Poll data state up to 50 times, with a 100ms delay
// totaling 5 sec.
// TODO: change the 5 seconds wait from blocking to non-blocking.
for (int i = 0; i < 50; i++) {
DataConnectionTracker.State currentState = dcTracker.getState();
if (currentState != DataConnectionTracker.State.CONNECTED
&& currentState != DataConnectionTracker.State.DISCONNECTING) {
if (DBG) log("Data shutdown complete.");
break;
synchronized(this) {
if (!mPendingRadioPowerOffAfterDataOff) {
DataConnectionTracker.State currentState = dcTracker.getState();
if (currentState != DataConnectionTracker.State.CONNECTED
&& currentState != DataConnectionTracker.State.DISCONNECTING) {
if (DBG) log("Data disconnected, turn off radio right away.");
cm.setRadioPower(false, null);
}
else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 5000)) {
if (DBG) log("Wait 5 sec for data to be disconnected, then turn off radio.");
mPendingRadioPowerOffAfterDataOff = true;
} else {
Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
cm.setRadioPower(false, null);
}
}
SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
}
// If it's on and available and we want it off..
cm.setRadioPower(false, null);
} // Otherwise, we're in the desired state
}
@ -1582,4 +1597,22 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
public boolean isMinInfoReady() {
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);
cm.setRadioPower(false, null);
mPendingRadioPowerOffAfterDataOff = false;
return true;
}
return false;
}
}
}