diff options
Diffstat (limited to 'telephony/java')
5 files changed, 99 insertions, 42 deletions
diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java index b95dd11..4967ab8 100644 --- a/telephony/java/com/android/internal/telephony/Call.java +++ b/telephony/java/com/android/internal/telephony/Call.java @@ -18,6 +18,8 @@ package com.android.internal.telephony; import java.util.List; +import android.util.Log; + /** * {@hide} */ @@ -54,6 +56,8 @@ public abstract class Call { // merged, etc. protected boolean isGeneric = false; + protected final String LOG_TAG = "Call"; + /* Instance Methods */ /** Do not modify the List result!!! This list is not yours to keep @@ -235,4 +239,17 @@ public abstract class Call { public void setGeneric(boolean generic) { isGeneric = generic; } + + /** + * Hangup call if it is alive + */ + public void hangupIfAlive() { + if (getState().isAlive()) { + try { + hangup(); + } catch (CallStateException ex) { + Log.w(LOG_TAG, " hangupIfActive: caught " + ex); + } + } + } } diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java index 6892998..7383649 100644 --- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java @@ -271,6 +271,13 @@ public abstract class ServiceStateTracker extends Handler { protected abstract void updateSpnDisplay(); protected abstract void setPowerStateToDesired(); + /** + * Clean up existing voice and data connection then turn off radio power. + * + * Hang up the existing voice calls to decrease call drop rate. + */ + protected abstract void powerOffRadioSafely(); + /** Cancel a pending (if any) pollState() operation */ protected void cancelPollState() { // This will effectively cancel the rest of the poll requests. diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index af3cbd5..42feaa9 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -514,7 +514,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { synchronized(this) { if (mPendingRadioPowerOffAfterDataOff) { if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now."); - cm.setRadioPower(false, null); + hangupAndPowerOff(); mPendingRadioPowerOffAfterDataOff = false; } } @@ -541,32 +541,42 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { dcTracker.getStateInString(), dcTracker.getAnyDataEnabled() ? 1 : 0); } - Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION); - msg.arg1 = 1; // tearDown is true - msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF; - dcTracker.sendMessage(msg); - synchronized(this) { - if (!mPendingRadioPowerOffAfterDataOff) { - DataConnectionTracker.State currentState = dcTracker.getState(); - if (currentState != DataConnectionTracker.State.CONNECTED - && currentState != DataConnectionTracker.State.DISCONNECTING - && currentState != DataConnectionTracker.State.INITING) { - if (DBG) log("Data disconnected, turn off radio right away."); - cm.setRadioPower(false, null); - } - else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) { - if (DBG) { - log("Wait up to 30 sec for data to disconnect, then turn off radio."); - } - mPendingRadioPowerOffAfterDataOff = true; - } else { - Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away."); - cm.setRadioPower(false, null); + // If it's on and available and we want it off gracefully + powerOffRadioSafely(); + } // Otherwise, we're in the desired state + } + + @Override + protected void powerOffRadioSafely(){ + // clean data connection + DataConnectionTracker dcTracker = phone.mDataConnection; + + Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION); + msg.arg1 = 1; // tearDown is true + msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF; + dcTracker.sendMessage(msg); + + synchronized(this) { + if (!mPendingRadioPowerOffAfterDataOff) { + DataConnectionTracker.State currentState = dcTracker.getState(); + if (currentState != DataConnectionTracker.State.CONNECTED + && currentState != DataConnectionTracker.State.DISCONNECTING + && currentState != DataConnectionTracker.State.INITING) { + if (DBG) log("Data disconnected, turn off radio right away."); + hangupAndPowerOff(); + } + else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) { + if (DBG) { + log("Wait up to 30 sec 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(); } } - } // Otherwise, we're in the desired state + } } @Override @@ -1644,11 +1654,19 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { if (mPendingRadioPowerOffAfterDataOff) { if (DBG) log("Process pending request to turn radio off."); removeMessages(EVENT_SET_RADIO_POWER_OFF); - cm.setRadioPower(false, null); + hangupAndPowerOff(); mPendingRadioPowerOffAfterDataOff = false; return true; } return false; } } + + private void hangupAndPowerOff() { + // hang up all active voice calls + phone.mCT.ringingCall.hangupIfAlive(); + phone.mCT.backgroundCall.hangupIfAlive(); + phone.mCT.foregroundCall.hangupIfAlive(); + cm.setRadioPower(false, null); + } } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 3f52eff..6695ccb 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -808,7 +808,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { protected void restartRadio() { Log.d(LOG_TAG, "************TURN OFF RADIO**************"); cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF); - phone.mCM.setRadioPower(false, null); + mGsmPhone.mSST.powerOffRadioSafely(); /* 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 diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index c2c89c01..48e5c97 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -518,26 +518,41 @@ final class GsmServiceStateTracker extends ServiceStateTracker { EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_DATA_STATE_RADIO_OFF, dcTracker.getStateInString(), dcTracker.getAnyDataEnabled() ? 1 : 0); } - Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION); - msg.arg1 = 1; // tearDown is true - msg.obj = GSMPhone.REASON_RADIO_TURNED_OFF; - 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++) { - if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED - && dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) { - Log.d(LOG_TAG, "Data shutdown complete."); - break; - } - SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS); - } - // If it's on and available and we want it off.. - cm.setRadioPower(false, null); + // If it's on and available and we want it off gracefully + powerOffRadioSafely(); } // Otherwise, we're in the desired state } + @Override + protected void powerOffRadioSafely() { + // clean data connection + DataConnectionTracker dcTracker = phone.mDataConnection; + Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION); + msg.arg1 = 1; // tearDown is true + msg.obj = GSMPhone.REASON_RADIO_TURNED_OFF; + 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++) { + if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED + && dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) { + Log.d(LOG_TAG, "Data shutdown complete."); + break; + } + SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS); + } + + // hang up all active voice calls + if (phone.isInCall()) { + phone.mCT.ringingCall.hangupIfAlive(); + phone.mCT.backgroundCall.hangupIfAlive(); + phone.mCT.foregroundCall.hangupIfAlive(); + } + + cm.setRadioPower(false, null); + } + protected void updateSpnDisplay() { int rule = phone.mSIMRecords.getDisplayRule(ss.getOperatorNumeric()); String spn = phone.mSIMRecords.getServiceProviderName(); |