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:
@ -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";
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user