Merge "Improves service state changed notification"
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index e69a593..842563d 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -211,6 +211,7 @@
protected static final int EVENT_PHONE_TYPE_SWITCHED = 50;
protected static final int EVENT_RADIO_POWER_FROM_CARRIER = 51;
protected static final int EVENT_SIM_NOT_INSERTED = 52;
+ protected static final int EVENT_IMS_SERVICE_STATE_CHANGED = 53;
protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
@@ -1346,6 +1347,15 @@
updateSpnDisplay();
break;
+ case EVENT_IMS_SERVICE_STATE_CHANGED:
+ if (DBG) log("EVENT_IMS_SERVICE_STATE_CHANGED");
+ // IMS state will only affect the merged service state if the service state of
+ // GsmCdma phone is not STATE_IN_SERVICE.
+ if (mSS.getState() != ServiceState.STATE_IN_SERVICE) {
+ mPhone.notifyServiceStateChanged(mPhone.getServiceState());
+ }
+ break;
+
//CDMA
case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
@@ -2536,6 +2546,11 @@
}
}
+ /** Called when the service state of ImsPhone is changed. */
+ public void onImsServiceStateChanged() {
+ sendMessage(obtainMessage(EVENT_IMS_SERVICE_STATE_CHANGED));
+ }
+
public void setImsRegistrationState(boolean registered) {
log("ImsRegistrationState - registered : " + registered);
@@ -2798,6 +2813,8 @@
mRejectCode = mNewRejectCode;
}
+ ServiceState oldMergedSS = mPhone.getServiceState();
+
// swap mSS and mNewSS to put new state in mSS
ServiceState tss = mSS;
mSS = mNewSS;
@@ -2909,7 +2926,10 @@
setRoamingType(mSS);
log("Broadcasting ServiceState : " + mSS);
// notify using PhoneStateListener and the legacy intent ACTION_SERVICE_STATE_CHANGED
- mPhone.notifyServiceStateChanged(mSS);
+ // notify service state changed only if the merged service state is changed.
+ if (!oldMergedSS.equals(mPhone.getServiceState())) {
+ mPhone.notifyServiceStateChanged(mPhone.getServiceState());
+ }
// insert into ServiceStateProvider. This will trigger apps to wake through JobScheduler
mPhone.getContext().getContentResolver()
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 03843a7..d27cae7 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -258,9 +258,21 @@
return mSS;
}
- /* package */ void setServiceState(int state) {
- mSS.setVoiceRegState(state);
+ @VisibleForTesting
+ public void setServiceState(int state) {
+ boolean isVoiceRegStateChanged = false;
+
+ synchronized (this) {
+ isVoiceRegStateChanged = mSS.getVoiceRegState() != state;
+ mSS.setVoiceRegState(state);
+ }
updateDataServiceState();
+
+ if (isVoiceRegStateChanged) {
+ if (mDefaultPhone.getServiceStateTracker() != null) {
+ mDefaultPhone.getServiceStateTracker().onImsServiceStateChanged();
+ }
+ }
}
@Override
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 15897d4..5c2b427 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -332,6 +332,31 @@
}
@Test
+ public void testOnImsServiceStateChanged() {
+ // The service state of GsmCdmaPhone is STATE_OUT_OF_SERVICE, and IMS is unregistered.
+ ServiceState ss = new ServiceState();
+ ss.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
+ sst.mSS = ss;
+
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_IMS_SERVICE_STATE_CHANGED));
+ waitForMs(200);
+
+ // The listener will be notified that the service state was changed.
+ verify(mPhone).notifyServiceStateChanged(any(ServiceState.class));
+
+ // The service state of GsmCdmaPhone is STATE_IN_SERVICE, and IMS is registered.
+ ss = new ServiceState();
+ ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+ sst.mSS = ss;
+
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_IMS_SERVICE_STATE_CHANGED));
+ waitForMs(200);
+
+ // Nothing happened because the IMS service state was not affected the merged service state.
+ verify(mPhone, times(1)).notifyServiceStateChanged(any(ServiceState.class));
+ }
+
+ @Test
@MediumTest
public void testSignalStrength() {
SignalStrength ss = new SignalStrength(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
index 3b357d7..f2e69cc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -30,6 +30,8 @@
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -47,6 +49,7 @@
import android.os.SystemProperties;
import android.support.test.filters.FlakyTest;
import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.ImsCallProfile;
@@ -485,6 +488,24 @@
}
@Test
+ public void testShouldSendNotificationWhenServiceStateIsChanged() {
+ mImsPhoneUT.setServiceState(ServiceState.STATE_IN_SERVICE);
+ reset(mSST);
+
+ mImsPhoneUT.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
+ verify(mSST).onImsServiceStateChanged();
+ }
+
+ @Test
+ public void testShouldNotSendNotificationWhenServiceStateIsNotChanged() {
+ mImsPhoneUT.setServiceState(ServiceState.STATE_IN_SERVICE);
+ reset(mSST);
+
+ mImsPhoneUT.setServiceState(ServiceState.STATE_IN_SERVICE);
+ verify(mSST, never()).onImsServiceStateChanged();
+ }
+
+ @Test
@SmallTest
public void testCellBarring() throws Exception {
Message msg = mTestHandler.obtainMessage();