Merge "Place dial request for Emergency call soon after Radio is on."
diff --git a/src/com/android/services/telephony/RadioOnHelper.java b/src/com/android/services/telephony/RadioOnHelper.java
index 981dc96..116c61d 100644
--- a/src/com/android/services/telephony/RadioOnHelper.java
+++ b/src/com/android/services/telephony/RadioOnHelper.java
@@ -110,6 +110,11 @@
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, 0);
+ for (Phone phone : PhoneFactory.getPhones()) {
+ Log.d(this, "powerOnRadio, enabling Radio");
+ phone.setRadioPower(true);
+ }
+
// Post the broadcast intend for change in airplane mode
// TODO: We really should not be in charge of sending this broadcast.
// If changing the setting is sufficient to trigger all of the rest of the logic,
diff --git a/src/com/android/services/telephony/RadioOnStateListener.java b/src/com/android/services/telephony/RadioOnStateListener.java
index 52bd9cf..43269b4 100644
--- a/src/com/android/services/telephony/RadioOnStateListener.java
+++ b/src/com/android/services/telephony/RadioOnStateListener.java
@@ -56,6 +56,9 @@
@VisibleForTesting
public static final int MSG_SERVICE_STATE_CHANGED = 2;
private static final int MSG_RETRY_TIMEOUT = 3;
+ @VisibleForTesting
+ public static final int MSG_RADIO_ON = 4;
+ public static final int MSG_RADIO_OFF_OR_NOT_AVAILABLE = 5;
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
@@ -75,6 +78,12 @@
case MSG_SERVICE_STATE_CHANGED:
onServiceStateChanged((ServiceState) ((AsyncResult) msg.obj).result);
break;
+ case MSG_RADIO_ON:
+ onRadioOn();
+ break;
+ case MSG_RADIO_OFF_OR_NOT_AVAILABLE:
+ registerForRadioOn();
+ break;
case MSG_RETRY_TIMEOUT:
onRetryTimeout();
break;
@@ -135,6 +144,9 @@
mCallback = callback;
registerForServiceStateChanged();
+ // Register for RADIO_OFF to handle cases where emergency call is dialed before
+ // we receive UNSOL_RESPONSE_RADIO_STATE_CHANGED with RADIO_OFF.
+ registerForRadioOff();
// Next step: when the SERVICE_STATE_CHANGED event comes in, we'll retry the call; see
// onServiceStateChanged(). But also, just in case, start a timer to make sure we'll retry
// the call even if the SERVICE_STATE_CHANGED event never comes in for some reason.
@@ -169,6 +181,17 @@
}
}
+ private void onRadioOn() {
+ ServiceState state = mPhone.getServiceState();
+ Log.d(this, "onRadioOn, state = %s, Phone = %s", state,
+ mPhone.getPhoneId());
+ if (isOkToCall(state.getState())) {
+ onComplete(true);
+ cleanup();
+ } else {
+ Log.d(this, "onRadioOn: not ready to call yet, keep waiting.");
+ }
+ }
/**
* Callback to see if it is okay to call yet, given the current conditions.
*/
@@ -239,6 +262,8 @@
onComplete(false);
unregisterForServiceStateChanged();
+ unregisterForRadioOff();
+ unregisterForRadioOn();
cancelRetryTimer();
// Used for unregisterForServiceStateChanged() so we null it out here instead.
@@ -271,6 +296,31 @@
mHandler.removeMessages(MSG_SERVICE_STATE_CHANGED); // Clean up any pending messages too
}
+ private void registerForRadioOff() {
+ mPhone.mCi.registerForOffOrNotAvailable(mHandler, MSG_RADIO_OFF_OR_NOT_AVAILABLE, null);
+ }
+
+ private void unregisterForRadioOff() {
+ // This method is safe to call even if we haven't set mPhone yet.
+ if (mPhone != null) {
+ mPhone.mCi.unregisterForOffOrNotAvailable(mHandler); // Safe even if unnecessary
+ }
+ mHandler.removeMessages(MSG_RADIO_OFF_OR_NOT_AVAILABLE); // Clean up any pending messages
+ }
+
+ private void registerForRadioOn() {
+ unregisterForRadioOff();
+ mPhone.mCi.registerForOn(mHandler, MSG_RADIO_ON, null);
+ }
+
+ private void unregisterForRadioOn() {
+ // This method is safe to call even if we haven't set mPhone yet.
+ if (mPhone != null) {
+ mPhone.mCi.unregisterForOn(mHandler); // Safe even if unnecessary
+ }
+ mHandler.removeMessages(MSG_RADIO_ON); // Clean up any pending messages too
+ }
+
private void onComplete(boolean isRadioReady) {
if (mCallback != null) {
Callback tempCallback = mCallback;
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 40b941e..b921466 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -662,7 +662,7 @@
// been powered on and isn't in the UNAVAILABLE state, even if it is
// reporting the OUT_OF_SERVICE state.
return (phone.getState() == PhoneConstants.State.OFFHOOK)
- || phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
+ || phone.getServiceStateTracker().isRadioOn();
} else {
// Wait until we are in service and ready to make calls. This can happen
// when we power down the radio on bluetooth to save power on watches or if
diff --git a/tests/src/com/android/services/telephony/RadioOnStateListenerTest.java b/tests/src/com/android/services/telephony/RadioOnStateListenerTest.java
index 8b46bf0..afdfab5 100644
--- a/tests/src/com/android/services/telephony/RadioOnStateListenerTest.java
+++ b/tests/src/com/android/services/telephony/RadioOnStateListenerTest.java
@@ -34,6 +34,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.TelephonyTestBase;
+import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
@@ -55,6 +56,7 @@
@Mock Phone mMockPhone;
@Mock RadioOnStateListener.Callback mCallback;
+ @Mock CommandsInterface mMockCi;
RadioOnStateListener mListener;
@Override
@@ -80,6 +82,7 @@
@Test
@SmallTest
public void testRegisterForCallback() {
+ mMockPhone.mCi = mMockCi;
mListener.waitForRadioOn(mMockPhone, mCallback);
waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
@@ -87,6 +90,9 @@
verify(mMockPhone).unregisterForServiceStateChanged(any(Handler.class));
verify(mMockPhone).registerForServiceStateChanged(any(Handler.class),
eq(RadioOnStateListener.MSG_SERVICE_STATE_CHANGED), isNull());
+
+ verify(mMockCi).registerForOffOrNotAvailable(any(Handler.class),
+ eq(RadioOnStateListener.MSG_RADIO_OFF_OR_NOT_AVAILABLE), isNull());
}
/**
@@ -101,6 +107,7 @@
state.setState(ServiceState.STATE_IN_SERVICE);
when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
when(mCallback.isOkToCall(eq(mMockPhone), anyInt())).thenReturn(true);
+ mMockPhone.mCi = mMockCi;
mListener.waitForRadioOn(mMockPhone, mCallback);
waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
@@ -124,6 +131,7 @@
when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
when(mCallback.isOkToCall(eq(mMockPhone), anyInt())).thenReturn(false);
when(mMockPhone.getServiceState()).thenReturn(state);
+ mMockPhone.mCi = mMockCi;
mListener.waitForRadioOn(mMockPhone, mCallback);
waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
@@ -152,6 +160,7 @@
mListener.setMaxNumRetries(2);
// Wait for the timer to expire and check state manually in onRetryTimeout
+ mMockPhone.mCi = mMockCi;
mListener.waitForRadioOn(mMockPhone, mCallback);
waitForHandlerActionDelayed(mListener.getHandler(), TIMEOUT_MS, TIMEOUT_MS /*delay*/);