diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java index 46b39a5db6c72..39806e92ef681 100644 --- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java @@ -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"; diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index 8e87587769734..8bae483215f48 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -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); diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index b42cffd2b18a4..b4de09b683f3e 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -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; + } + } }