Merge cherrypicks of [19121301] into tm-release.
Change-Id: Ia76e950a27f3787d6ea1dc4a02c1c9f90a3458bf
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 751d59a..3cba6ac 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -1086,7 +1086,7 @@
/**
* Turn on or off radio power with option to specify whether it's for emergency call and specify
* a reason for setting the power state.
- * More details check {@link PhoneInternalInterface#setRadioPower(
+ * More details check {@link PhoneInternalInterface#setRadioPowerForReason(
* boolean, boolean, boolean, boolean, int)}.
*/
public void setRadioPowerForReason(boolean power, boolean forEmergencyCall,
@@ -1188,10 +1188,10 @@
if (VDBG) log("received event " + msg.what);
switch (msg.what) {
case EVENT_SET_RADIO_POWER_OFF:
- synchronized(this) {
+ synchronized (this) {
if (mPhone.isUsingNewDataStack()) {
- mPendingRadioPowerOffAfterDataOff = false;
log("Wait for all data networks torn down timed out. Power off now.");
+ cancelPendingRadioPowerOff();
hangupAndPowerOff();
return;
}
@@ -1491,17 +1491,18 @@
case EVENT_ALL_DATA_DISCONNECTED:
if (mPhone.isUsingNewDataStack()) {
log("EVENT_ALL_DATA_DISCONNECTED");
- if (mPendingRadioPowerOffAfterDataOff) {
- mPendingRadioPowerOffAfterDataOff = false;
- removeMessages(EVENT_SET_RADIO_POWER_OFF);
- if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now.");
- hangupAndPowerOff();
+ synchronized (this) {
+ if (mPendingRadioPowerOffAfterDataOff) {
+ if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now.");
+ cancelPendingRadioPowerOff();
+ hangupAndPowerOff();
+ }
}
return;
}
int dds = SubscriptionManager.getDefaultDataSubscriptionId();
ProxyController.getInstance().unregisterForAllDataDisconnected(dds, this);
- synchronized(this) {
+ synchronized (this) {
if (mPendingRadioPowerOffAfterDataOff) {
if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now.");
hangupAndPowerOff();
@@ -3132,12 +3133,12 @@
&& getRadioPowerOffDelayTimeoutForImsRegistration() > 0) {
if (DBG) log("setPowerStateToDesired: delaying power off until IMS dereg.");
startDelayRadioOffWaitingForImsDeregTimeout();
- // Return early here as we do not want to hit the cancel timeout code below.
- return;
} else {
if (DBG) log("setPowerStateToDesired: powerOffRadioSafely()");
powerOffRadioSafely();
}
+ // Return early here as we do not want to hit the cancel timeout code below.
+ return;
} else if (mDeviceShuttingDown
&& (mCi.getRadioState() != TelephonyManager.RADIO_POWER_UNAVAILABLE)) {
// !mDesiredPowerState condition above will happen first if the radio is on, so we will
@@ -3147,6 +3148,19 @@
}
// Cancel any pending timeouts because the state has been re-evaluated.
cancelDelayRadioOffWaitingForImsDeregTimeout();
+ cancelPendingRadioPowerOff();
+ }
+
+ /**
+ * Cancel the pending radio power off request that was sent to force the radio to power off
+ * if waiting for all data to disconnect times out.
+ */
+ private synchronized void cancelPendingRadioPowerOff() {
+ if (mPhone.isUsingNewDataStack() && mPendingRadioPowerOffAfterDataOff) {
+ if (DBG) log("cancelPendingRadioPowerOff: cancelling.");
+ mPendingRadioPowerOffAfterDataOff = false;
+ removeMessages(EVENT_SET_RADIO_POWER_OFF);
+ }
}
/**
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 7d9891d..ff3e8b8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -92,6 +92,7 @@
import com.android.internal.R;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
+import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.metrics.ServiceStateStats;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.uicc.IccCardApplicationStatus;
@@ -380,6 +381,65 @@
}
@Test
+ public void testSetRadioPowerWaitForAllDataDisconnected() {
+ // Start with radio on
+ sst.setRadioPower(true);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+
+ // Ensure data is connected
+ ArgumentCaptor<DataNetworkController.DataNetworkControllerCallback> callback =
+ ArgumentCaptor.forClass(DataNetworkController.DataNetworkControllerCallback.class);
+ verify(mDataNetworkController, times(1)).registerDataNetworkControllerCallback(
+ callback.capture());
+ callback.getValue().onAnyDataNetworkExistingChanged(true);
+
+ // Turn on APM and verify that SST is waiting for all data disconnected
+ sst.setRadioPower(false);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+ verify(mDataNetworkController).tearDownAllDataNetworks(
+ eq(3 /* TEAR_DOWN_REASON_AIRPLANE_MODE_ON */));
+ assertTrue(sst.hasMessages(38 /* EVENT_SET_RADIO_POWER_OFF */));
+
+ // Data disconnected, radio should power off now
+ callback.getValue().onAnyDataNetworkExistingChanged(false);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
+ }
+
+ @Test
+ public void testSetRadioPowerCancelWaitForAllDataDisconnected() {
+ // Start with radio on
+ sst.setRadioPower(true);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+
+ // Ensure data is connected
+ ArgumentCaptor<DataNetworkController.DataNetworkControllerCallback> callback =
+ ArgumentCaptor.forClass(DataNetworkController.DataNetworkControllerCallback.class);
+ verify(mDataNetworkController, times(1)).registerDataNetworkControllerCallback(
+ callback.capture());
+ callback.getValue().onAnyDataNetworkExistingChanged(true);
+
+ // Turn on APM and verify that SST is waiting for all data disconnected
+ sst.setRadioPower(false);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+ verify(mDataNetworkController).tearDownAllDataNetworks(
+ eq(3 /* TEAR_DOWN_REASON_AIRPLANE_MODE_ON */));
+ assertTrue(sst.hasMessages(38 /* EVENT_SET_RADIO_POWER_OFF */));
+
+ // Turn off APM while waiting for data to disconnect
+ sst.setRadioPower(true);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
+ // Check that radio is on and pending power off messages were cleared
+ assertFalse(sst.hasMessages(38 /* EVENT_SET_RADIO_POWER_OFF */));
+ assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+ }
+
+ @Test
@SmallTest
public void testSetRadioPowerOnForEmergencyCall() {
// Turn off radio first.