Junit Deliverables for Google Qns

-Junit deliverables with Code coverage improvement

Bug: 231693710
Test: atest QualifiedNetworksServiceTests
Change-Id: I251858cd50fbe6a2d8eb7b49990518448950cdb4
diff --git a/src/com/android/qns/DataConnectionStatusTracker.java b/src/com/android/qns/DataConnectionStatusTracker.java
index f5df058..18e123b 100644
--- a/src/com/android/qns/DataConnectionStatusTracker.java
+++ b/src/com/android/qns/DataConnectionStatusTracker.java
@@ -18,10 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Looper;
@@ -47,10 +44,6 @@
     private final int mApnType;
     @VisibleForTesting protected final Handler mHandler;
     private DataConnectionChangedInfo mLastUpdatedDcChangedInfo;
-    /*For internal test [s] This should be removed later.*/
-    private boolean mTestMode = false;
-    private int mTestHoFailMode = 0;
-    /*For internal test [e] This should be removed later.*/
     private final QnsTelephonyListener mQnsTelephonyListener;
     public static final int STATE_INACTIVE = 0;
     public static final int STATE_CONNECTING = 1;
@@ -112,74 +105,12 @@
         mQnsTelephonyListener = QnsTelephonyListener.getInstance(context, slotIndex);
         mQnsTelephonyListener.registerPreciseDataConnectionStateChanged(
                 mApnType, mHandler, EVENT_DATA_CONNECTION_STATE_CHANGED, null, true);
-        /*For internal test [s] This should be removed later.*/
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction("android.intent.action.QNS_DC_CHANGED");
-        mContext.registerReceiver(mIntentReceiver, intentFilter);
-        /*For internal test [e]*/
     }
 
     protected void log(String s) {
         Log.d(LOG_TAG, s);
     }
 
-    /*For internal test [s] This should be removed later.*/
-    public void notifyTransportTypeChanged(int transportType) {
-        if (!mTestMode) {
-            return;
-        }
-        log(
-                "notifyTransportTypeChanged target:"
-                        + AccessNetworkConstants.transportTypeToString(transportType)
-                        + " current:"
-                        + AccessNetworkConstants.transportTypeToString(mTransportType));
-        int prevTransportType = mTransportType;
-        if (mState == STATE_CONNECTED && transportType != mTransportType) {
-            PreciseDataConnectionState dc1 =
-                    new PreciseDataConnectionState.Builder()
-                            .setTransportType(transportType)
-                            .setState(TelephonyManager.DATA_CONNECTING)
-                            .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                            .build();
-            AsyncResult ar1 = new AsyncResult(null, dc1, null);
-            Message msg = mHandler.obtainMessage(EVENT_DATA_CONNECTION_STATE_CHANGED, ar1);
-            mHandler.sendMessageDelayed(msg, 300);
-            if (mTestHoFailMode == 0) {
-                PreciseDataConnectionState dc2 =
-                        new PreciseDataConnectionState.Builder()
-                                .setTransportType(transportType)
-                                .setState(TelephonyManager.DATA_CONNECTED)
-                                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                                .build();
-                AsyncResult ar2 = new AsyncResult(null, dc2, null);
-                Message msg2 = mHandler.obtainMessage(EVENT_DATA_CONNECTION_STATE_CHANGED, ar2);
-                mHandler.sendMessageDelayed(msg2, 3300);
-
-                PreciseDataConnectionState dc3 =
-                        new PreciseDataConnectionState.Builder()
-                                .setTransportType(prevTransportType)
-                                .setState(TelephonyManager.DATA_DISCONNECTED)
-                                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                                .build();
-                AsyncResult ar3 = new AsyncResult(null, dc3, null);
-                Message msg3 = mHandler.obtainMessage(EVENT_DATA_CONNECTION_STATE_CHANGED, ar3);
-                mHandler.sendMessageDelayed(msg3, 3800);
-            } else {
-                PreciseDataConnectionState dc4 =
-                        new PreciseDataConnectionState.Builder()
-                                .setTransportType(transportType)
-                                .setFailCause(33)
-                                .setState(TelephonyManager.DATA_DISCONNECTED)
-                                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                                .build();
-                AsyncResult ar4 = new AsyncResult(null, dc4, null);
-                Message msg2 = mHandler.obtainMessage(EVENT_DATA_CONNECTION_STATE_CHANGED, ar4);
-                mHandler.sendMessageDelayed(msg2, 13300);
-            }
-        }
-    }
-    /*For internal test [e] */
-
     public boolean isInactiveState() {
         return mState == STATE_INACTIVE;
     }
@@ -348,7 +279,6 @@
     public void close() {
         mQnsTelephonyListener.unregisterPreciseDataConnectionStateChanged(mApnType, mHandler);
         mDataConnectionStatusRegistrants.removeAll();
-        mContext.unregisterReceiver(mIntentReceiver);
     }
 
     public static String stateToString(int state) {
@@ -442,64 +372,4 @@
             }
         }
     }
-
-    /*For internal test This should be removed later.*/
-    private final BroadcastReceiver mIntentReceiver =
-            new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    String action = intent.getAction();
-                    int event = -1;
-                    log("onReceive: " + action);
-                    switch (action) {
-                        case "android.intent.action.QNS_DC_CHANGED":
-                            int apntype = intent.getIntExtra("apntype", ApnSetting.TYPE_IMS);
-                            if (apntype != mApnType) {
-                                return;
-                            }
-                            mTestHoFailMode = intent.getIntExtra("hofailmode", 0);
-                            int dctransporttype =
-                                    intent.getIntExtra(
-                                            "transport",
-                                            AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-                            mTransportType = dctransporttype;
-                            int dcevent =
-                                    intent.getIntExtra("event", EVENT_DATA_CONNECTION_DISCONNECTED);
-                            switch (dcevent) {
-                                case EVENT_DATA_CONNECTION_DISCONNECTED:
-                                    mState = STATE_INACTIVE;
-                                    break;
-                                case EVENT_DATA_CONNECTION_CONNECTED:
-                                    mState = STATE_CONNECTED;
-                                    break;
-                                case EVENT_DATA_CONNECTION_HANDOVER_STARTED:
-                                    mState = STATE_HANDOVER;
-                                    break;
-                                case EVENT_DATA_CONNECTION_HANDOVER_SUCCESS:
-                                    mState = STATE_CONNECTED;
-                                    break;
-                                case EVENT_DATA_CONNECTION_HANDOVER_FAILED:
-                                    mState = STATE_CONNECTED;
-                                    break;
-                                default:
-                                    break;
-                            }
-                            mTestMode = true;
-                            log(
-                                    "TEST: QNS_DC_CHANGED apntype:"
-                                            + apntype
-                                            + "  state:"
-                                            + mState
-                                            + "  transport:"
-                                            + dctransporttype
-                                            + "  dcevent"
-                                            + dcevent
-                                            + "  testHoFailMode:"
-                                            + mTestHoFailMode);
-                            notifyDataConnectionStatusChangedEvent(dcevent);
-                            break;
-                    }
-                }
-            };
-    /*For internal test [e]*/
 }
diff --git a/src/com/android/qns/QnsEventDispatcher.java b/src/com/android/qns/QnsEventDispatcher.java
index 9c15a37..050cea7 100644
--- a/src/com/android/qns/QnsEventDispatcher.java
+++ b/src/com/android/qns/QnsEventDispatcher.java
@@ -129,7 +129,7 @@
     private Uri mWfcModeUri;
     private Uri mWfcRoamingEnabledUri;
     private Uri mWfcRoamingModeUri;
-    private UserSettingObserver mUserSettingObserver;
+    @VisibleForTesting UserSettingObserver mUserSettingObserver;
     private HandlerThread mUserSettingHandlerThread;
     boolean mLastWfcEnabledByPlatform = false;
     boolean mLastCrossSimCallingEnabled = false;
@@ -681,7 +681,8 @@
         }
     }
 
-    private class UserSettingObserver extends ContentObserver {
+    @VisibleForTesting
+    class UserSettingObserver extends ContentObserver {
         UserSettingObserver(Handler h) {
             super(h);
         }
@@ -693,8 +694,7 @@
         }
     }
 
-    @VisibleForTesting
-    synchronized void onUserSettingChanged(Uri uri) {
+    private synchronized void onUserSettingChanged(Uri uri) {
         if (mCrossSimCallingUri.equals(uri)) {
             notifyCurrentSetting(uri, false);
         } else if (mWfcEnabledUri.equals(uri)) {
diff --git a/src/com/android/qns/QnsProvisioningListener.java b/src/com/android/qns/QnsProvisioningListener.java
index a5e5c4c..dc4ea2a 100644
--- a/src/com/android/qns/QnsProvisioningListener.java
+++ b/src/com/android/qns/QnsProvisioningListener.java
@@ -30,6 +30,8 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -51,7 +53,8 @@
     private final int mSlotIndex;
     private final QnsProvisioningInfo mProvisioningInfo;
     private final QnsEventDispatcher mQnsEventDispatcher;
-    private final QnsProvisioningHandler mQnsProvisioningHandler;
+    @VisibleForTesting QnsProvisioningHandler mQnsProvisioningHandler;
+
     private final QnsProvisioningCallback mQnsProvisioningCallback;
     private final RegistrantList mRegistrantList;
     protected IwlanNetworkStatusTracker mIwlanNetworkStatusTracker;
@@ -71,7 +74,6 @@
         HandlerThread handlerThread = new HandlerThread(LOG_TAG);
         handlerThread.start();
         mQnsProvisioningHandler = new QnsProvisioningHandler(handlerThread.getLooper());
-
         mQnsEventDispatcher = QnsEventDispatcher.getInstance(context, slotIndex);
         List<Integer> events = new ArrayList<>();
         events.add(QnsEventDispatcher.QNS_EVENT_CARRIER_CONFIG_CHANGED);
@@ -426,7 +428,8 @@
         }
     }
 
-    private class QnsProvisioningHandler extends Handler {
+    @VisibleForTesting
+    class QnsProvisioningHandler extends Handler {
         private int mRetryRegisterProvisioningCallbackCount;
 
         public QnsProvisioningHandler(Looper looper) {
diff --git a/src/com/android/qns/QnsTelephonyListener.java b/src/com/android/qns/QnsTelephonyListener.java
index fe5e44c..5d3b4c1 100644
--- a/src/com/android/qns/QnsTelephonyListener.java
+++ b/src/com/android/qns/QnsTelephonyListener.java
@@ -43,6 +43,8 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Objects;
@@ -76,11 +78,12 @@
     protected HashMap<Integer, PreciseDataConnectionState> mLastPreciseDataConnectionState =
             new HashMap<>();
     private int mSubId;
-    private TelephonyListener mTelephonyListener;
+    @VisibleForTesting TelephonyListener mTelephonyListener;
     private int mCoverage;
     @Annotation.CallState private int mCallState;
 
-    private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangeListener =
+    @VisibleForTesting
+    final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangeListener =
             new SubscriptionManager.OnSubscriptionsChangedListener() {
                 @Override
                 public void onSubscriptionsChanged() {
diff --git a/src/com/android/qns/QualifiedNetworksServiceImpl.java b/src/com/android/qns/QualifiedNetworksServiceImpl.java
index 7a81516..4e19e74 100644
--- a/src/com/android/qns/QualifiedNetworksServiceImpl.java
+++ b/src/com/android/qns/QualifiedNetworksServiceImpl.java
@@ -30,6 +30,8 @@
 import android.telephony.data.ThrottleStatus;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -127,8 +129,8 @@
     public class NetworkAvailabilityProviderImpl extends NetworkAvailabilityProvider {
         private final String mLogTag;
         private final int mSlotIndex;
-        private final Handler mHandler;
-        private final Handler mConfigHandler;
+        @VisibleForTesting Handler mHandler;
+        @VisibleForTesting Handler mConfigHandler;
         private final HandlerThread mHandlerThread;
         private final HandlerThread mConfigHandlerThread;
         private boolean isQnsConfigChangeRegistered = false;
diff --git a/tests/src/com/android/qns/AlternativeEventListenerTest.java b/tests/src/com/android/qns/AlternativeEventListenerTest.java
index c14fa3a..744a2e7 100644
--- a/tests/src/com/android/qns/AlternativeEventListenerTest.java
+++ b/tests/src/com/android/qns/AlternativeEventListenerTest.java
@@ -233,8 +233,10 @@
 
     @Test
     public void testForCallTypeChangedScenarios() {
+        mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, null, 1, null);
         mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, mHandler, 1, null);
         mListener.registerCallTypeChangedListener(ApnSetting.TYPE_EMERGENCY, mHandler, 1, null);
+        mListener.registerCallTypeChangedListener(ApnSetting.TYPE_MMS, mHandler, 1, null);
 
         // Test1:
         mAltEventProvider.notifyCallInfo(
@@ -288,8 +290,10 @@
 
     @Test
     public void testUnregisterCallTypeChangedListener() {
+        mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, null, 1, null);
         mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, mHandler, 1, null);
         mListener.registerCallTypeChangedListener(ApnSetting.TYPE_EMERGENCY, mHandler, 1, null);
+        mListener.registerCallTypeChangedListener(ApnSetting.TYPE_MMS, mHandler, 1, null);
 
         mAltEventProvider.notifyCallInfo(
                 1, QnsConstants.CALL_TYPE_VOICE, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
diff --git a/tests/src/com/android/qns/DataConnectionStatusTrackerTest.java b/tests/src/com/android/qns/DataConnectionStatusTrackerTest.java
index d458ca3..0f1d0e5 100644
--- a/tests/src/com/android/qns/DataConnectionStatusTrackerTest.java
+++ b/tests/src/com/android/qns/DataConnectionStatusTrackerTest.java
@@ -80,8 +80,6 @@
     protected DataConnectionStatusTracker mDataConnectionStatusTracker;
     private static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 1;
     DataConnectionChangedInfo dcStatus;
-    int transportType;
-    private final String LOG_TAG = DataConnectionStatusTrackerTest.class.getSimpleName();
 
     private boolean mReady = false;
     private Object mLock = new Object();
@@ -351,6 +349,45 @@
     }
 
     @Test
+    public void testHandoverOnNonSrcTransportType() {
+        mReady = false;
+        validateNotConnectedStatusChecks();
+        validateDataConnectionLastTransportType(TRANSPORT_TYPE_INVALID);
+
+        loadPrecisionDataConnectionState(
+                TRANSPORT_TYPE_WWAN,
+                TelephonyManager.DATA_CONNECTING,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        validateConnectingStatusChecks();
+        validateDataConnectionLastTransportType(TRANSPORT_TYPE_INVALID);
+        waitUntilReady();
+        validateDataConnectionChangedInfo(
+                STATE_CONNECTING, TRANSPORT_TYPE_WWAN, EVENT_DATA_CONNECTION_STARTED);
+
+        mReady = false;
+        loadPrecisionDataConnectionState(
+                TRANSPORT_TYPE_WWAN,
+                TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        validateConnectedStatusChecks();
+        validateDataConnectionLastTransportType(TRANSPORT_TYPE_WWAN);
+        waitUntilReady();
+        validateDataConnectionChangedInfo(
+                STATE_CONNECTED, TRANSPORT_TYPE_WWAN, EVENT_DATA_CONNECTION_CONNECTED);
+
+        mReady = false;
+        loadPrecisionDataConnectionState(
+                TRANSPORT_TYPE_WLAN,
+                TelephonyManager.DATA_HANDOVER_IN_PROGRESS,
+                TelephonyManager.NETWORK_TYPE_IWLAN);
+
+        Assert.assertFalse(mDataConnectionStatusTracker.isHandoverState());
+        validateDataConnectionLastTransportType(TRANSPORT_TYPE_WWAN);
+    }
+
+    @Test
     public void testOnCellularHandoverSuspended() {
         mReady = false;
         validateNotConnectedStatusChecks();
@@ -500,6 +537,40 @@
     }
 
     @Test
+    public void testOnIwlanWithApnSetting() {
+        mReady = false;
+        validateNotConnectedStatusChecks();
+        validateDataConnectionLastTransportType(TRANSPORT_TYPE_INVALID);
+
+        loadPrecisionDataConnectionStateWithApnSetting(
+                TRANSPORT_TYPE_WLAN,
+                ApnSetting.TYPE_IMS,
+                TelephonyManager.DATA_CONNECTING,
+                TelephonyManager.NETWORK_TYPE_IWLAN);
+
+        validateConnectingStatusChecks();
+        validateDataConnectionLastTransportType(TRANSPORT_TYPE_INVALID);
+        waitUntilReady();
+        validateDataConnectionChangedInfo(
+                STATE_CONNECTING, TRANSPORT_TYPE_WLAN, EVENT_DATA_CONNECTION_STARTED);
+
+        mReady = false;
+        loadPrecisionDataConnectionStateWithApnSetting(
+                TRANSPORT_TYPE_WLAN,
+                ApnSetting.TYPE_IMS,
+                TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_IWLAN);
+
+        validateConnectedStatusChecks();
+        validateDataConnectionLastTransportType(TRANSPORT_TYPE_WLAN);
+        waitUntilReady();
+        validateDataConnectionChangedInfo(
+                STATE_CONNECTED, TRANSPORT_TYPE_WLAN, EVENT_DATA_CONNECTION_CONNECTED);
+
+        validateApnSetting(TRANSPORT_TYPE_WLAN);
+    }
+
+    @Test
     public void testOnIwlanHandover() {
         mReady = false;
         validateNotConnectedStatusChecks();
@@ -646,6 +717,14 @@
         validateConnectedStatusChecks();
         validateDataConnectionLastTransportType(TRANSPORT_TYPE_WLAN);
         validateHandoverFailCause(MISSING_UNKNOWN_APN);
+        validateApnSettingForNull(TRANSPORT_TYPE_WLAN);
+    }
+
+    @Test
+    public void testInvalidDataConnectionStatusTrackerHandler() {
+        mDataConnectionStatusTracker.mHandler.handleMessage(
+                Message.obtain(mDataConnectionStatusTracker.mHandler, -1, null));
+        validateDataConnectionLastTransportType(TRANSPORT_TYPE_INVALID);
     }
 
     private void loadPrecisionDataConnectionState(
@@ -677,6 +756,31 @@
         mDataConnectionStatusTracker.mHandler.handleMessage(msg);
     }
 
+    private void loadPrecisionDataConnectionStateWithApnSetting(
+            int accessNetwork, int apnType, int telephonyState, int currentRat) {
+        ApnSetting apnSetting =
+                new ApnSetting.Builder()
+                        .setApnTypeBitmask(ApnSetting.TYPE_IMS)
+                        .setApnName("ims")
+                        .setEntryName("IMS")
+                        .setApnTypeBitmask(apnType)
+                        .setNetworkTypeBitmask(
+                                (int) TelephonyManager.NETWORK_STANDARDS_FAMILY_BITMASK_3GPP)
+                        .setCarrierEnabled(true)
+                        .build();
+
+        PreciseDataConnectionState dataState =
+                new PreciseDataConnectionState.Builder()
+                        .setTransportType(accessNetwork)
+                        .setApnSetting(apnSetting)
+                        .setState(telephonyState)
+                        .setNetworkType(currentRat)
+                        .build();
+        AsyncResult ar = new AsyncResult(null, dataState, null);
+        Message msg = mDataConnectionStatusTracker.mHandler.obtainMessage(11001, ar);
+        mDataConnectionStatusTracker.mHandler.handleMessage(msg);
+    }
+
     private void validateNotConnectedStatusChecks() {
         Assert.assertFalse(mDataConnectionStatusTracker.isActiveState());
         Assert.assertTrue(mDataConnectionStatusTracker.isInactiveState());
@@ -718,6 +822,16 @@
         Assert.assertEquals(event, dcStatus.getEvent());
     }
 
+    private void validateApnSettingForNull(int transportType) {
+        ApnSetting apnSetting = mDataConnectionStatusTracker.getLastApnSetting(transportType);
+        Assert.assertNull(apnSetting);
+    }
+
+    private void validateApnSetting(int transportType) {
+        ApnSetting apnSetting = mDataConnectionStatusTracker.getLastApnSetting(transportType);
+        Assert.assertTrue(apnSetting.canHandleType(ApnSetting.TYPE_IMS));
+    }
+
     @After
     public void tearDown() {
         mDataConnectionStatusTracker.unRegisterDataConnectionStatusChanged(mHandler);
diff --git a/tests/src/com/android/qns/ImsStatusListenerTest.java b/tests/src/com/android/qns/ImsStatusListenerTest.java
index d4acf16..a8e198b 100644
--- a/tests/src/com/android/qns/ImsStatusListenerTest.java
+++ b/tests/src/com/android/qns/ImsStatusListenerTest.java
@@ -143,6 +143,7 @@
 
     @Test
     public void testNotifyImsRegistrationChangedEventOnRegistered() {
+        assertFalse(mImsStatusListener.isImsRegistered(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
         ImsRegistrationAttributes attr =
                 new ImsRegistrationAttributes.Builder(ImsRegistrationImplBase.REGISTRATION_TECH_LTE)
                         .build();
@@ -158,6 +159,10 @@
         assertNotNull(bean);
         assertEquals(QnsConstants.IMS_REGISTRATION_CHANGED_REGISTERED, msg.what);
         assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, bean.getTransportType());
+        assertTrue(mImsStatusListener.isImsRegistered(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
+        assertFalse(mImsStatusListener.isImsRegistered(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
+        assertFalse(
+                mImsStatusListener.isImsRegistered(AccessNetworkConstants.TRANSPORT_TYPE_INVALID));
     }
 
     @Test
@@ -201,5 +206,6 @@
         verify(mockImsMmTelManager)
                 .unregisterImsRegistrationCallback(
                         any(RegistrationManager.RegistrationCallback.class));
+        assertFalse(mImsStatusListener.isImsRegistered(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
     }
 }
diff --git a/tests/src/com/android/qns/QnsEventDispatcherTest.java b/tests/src/com/android/qns/QnsEventDispatcherTest.java
index 3f54fbd..87d18dc 100644
--- a/tests/src/com/android/qns/QnsEventDispatcherTest.java
+++ b/tests/src/com/android/qns/QnsEventDispatcherTest.java
@@ -18,8 +18,12 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
 import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
@@ -371,8 +375,6 @@
 
     @Test
     public void testNotifyImmeditatelyWfcSettingsWithDisabledStatus() {
-        lenient().when(QnsUtils.isWfcEnabledByPlatform(mMockContext, 0)).thenReturn(true);
-
         when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_PLATFORM_DISABLED)))
                 .thenReturn(mMockMessage);
         when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_DISABLED)))
@@ -393,6 +395,59 @@
     }
 
     @Test
+    public void testNotifyImmeditatelyWfcSettingsWithEnabledStatus() {
+        setEnabledStatusForWfcSettingsCrossSimSettings();
+
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_PLATFORM_ENABLED)))
+                .thenReturn(mMockMessage);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_ENABLED)))
+                .thenReturn(mMockMessage1);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_ENABLED)))
+                .thenReturn(mMockMessage2);
+
+        List<Integer> events = new ArrayList<Integer>();
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_PLATFORM_ENABLED);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_ENABLED);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_ENABLED);
+        mQnsEventDispatcher.registerEvent(events, mMockHandler);
+
+        // WFC settings Enabled Case
+        verify(mMockMessage, times(1)).sendToTarget();
+        verify(mMockMessage1, times(1)).sendToTarget();
+        verify(mMockMessage2, times(1)).sendToTarget();
+    }
+
+    @Test
+    public void testNotifyImmeditatelyDifferentWfcModes() {
+        setEnabledStatusForWfcSettingsCrossSimSettings();
+        lenient()
+                .when(QnsUtils.getWfcMode(isA(Context.class), anyInt(), anyBoolean()))
+                .thenReturn(1)
+                .thenReturn(2);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_ONLY)))
+                .thenReturn(mMockMessage);
+        when(mMockHandler.obtainMessage(
+                        eq(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_CELLULAR_PREFERRED)))
+                .thenReturn(mMockMessage1);
+        when(mMockHandler.obtainMessage(
+                        eq(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_PREFERRED)))
+                .thenReturn(mMockMessage2);
+
+        List<Integer> events = new ArrayList<Integer>();
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_ONLY);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_CELLULAR_PREFERRED);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_PREFERRED);
+        mQnsEventDispatcher.registerEvent(events, mMockHandler);
+
+        // WFC Modes Enabled Case
+        verify(mMockMessage, times(1)).sendToTarget();
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_MODE_URI);
+        verify(mMockMessage1, times(1)).sendToTarget();
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_MODE_URI);
+        verify(mMockMessage2, times(1)).sendToTarget();
+    }
+
+    @Test
     public void testNotifyCurrentSettingWithDisabledStatus() {
         when(mMockHandler.obtainMessage(
                         eq(QnsEventDispatcher.QNS_EVENT_CROSS_SIM_CALLING_DISABLED)))
@@ -433,6 +488,59 @@
     }
 
     @Test
+    public void testNotifyCurrentSettingWithEnabledStatus() {
+        setEnabledStatusForWfcSettingsCrossSimSettings();
+
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_CROSS_SIM_CALLING_ENABLED)))
+                .thenReturn(mMockMessage);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_ENABLED)))
+                .thenReturn(mMockMessage1);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_ONLY)))
+                .thenReturn(mMockMessage4);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_ENABLED)))
+                .thenReturn(mMockMessage2);
+        when(mMockHandler.obtainMessage(
+                        eq(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_ONLY)))
+                .thenReturn(mMockMessage5);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_CARRIER_CONFIG_CHANGED)))
+                .thenReturn(mMockMessage3);
+
+        List<Integer> events = new ArrayList<Integer>();
+        events.add(QnsEventDispatcher.QNS_EVENT_CROSS_SIM_CALLING_ENABLED);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_ENABLED);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_ONLY);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_ENABLED);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_ONLY);
+        events.add(QnsEventDispatcher.QNS_EVENT_CARRIER_CONFIG_CHANGED);
+        mQnsEventDispatcher.registerEvent(events, mMockHandler);
+
+        // Send ACTION_CARRIER_CONFIG_CHANGED intent with valid Carrier id
+        final Intent validCarrierIdintent =
+                new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        validCarrierIdintent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, DEFAULT_SLOT_INDEX);
+        validCarrierIdintent.putExtra(TelephonyManager.EXTRA_CARRIER_ID, DEFAULT_CARRIER_INDEX);
+        mQnsEventDispatcher.mIntentReceiver.onReceive(mMockContext, validCarrierIdintent);
+        verify(mMockMessage, times(2)).sendToTarget();
+        verify(mMockMessage1, times(2)).sendToTarget();
+        verify(mMockMessage4, times(2)).sendToTarget();
+        verify(mMockMessage2, times(2)).sendToTarget();
+        verify(mMockMessage5, times(2)).sendToTarget();
+        verify(mMockMessage3, times(1)).sendToTarget();
+    }
+
+    private void setEnabledStatusForWfcSettingsCrossSimSettings() {
+        lenient()
+                .when(QnsUtils.isCrossSimCallingEnabled(isA(Context.class), anyInt()))
+                .thenReturn(true);
+        lenient()
+                .when(QnsUtils.isWfcEnabledByPlatform(isA(Context.class), anyInt()))
+                .thenReturn(true);
+        lenient()
+                .when(QnsUtils.isWfcEnabled(isA(Context.class), anyInt(), anyBoolean()))
+                .thenReturn(true);
+    }
+
+    @Test
     public void testUnregisterEventAndUserSettingObserver() {
         when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_CARRIER_CONFIG_CHANGED)))
                 .thenReturn(mMockMessage);
@@ -453,7 +561,7 @@
     }
 
     @Test
-    public void testOnUserSettingChanged() {
+    public void testOnUserSettingChangedEventDisableStatus() {
         when(mMockHandler.obtainMessage(
                         eq(QnsEventDispatcher.QNS_EVENT_CROSS_SIM_CALLING_DISABLED)))
                 .thenReturn(mMockMessage);
@@ -487,21 +595,74 @@
 
         verify(mMockMessage, times(2)).sendToTarget();
         verify(mMockMessage1, times(2)).sendToTarget();
-        verify(mMockMessage4, times(1)).sendToTarget();
+        verify(mMockMessage4, atLeastOnce()).sendToTarget();
         verify(mMockMessage2, times(2)).sendToTarget();
-        verify(mMockMessage5, times(1)).sendToTarget();
+        verify(mMockMessage5, atLeastOnce()).sendToTarget();
         verify(mMockMessage3, times(1)).sendToTarget();
 
-        mQnsEventDispatcher.onUserSettingChanged(CROSS_SIM_URI);
-        mQnsEventDispatcher.onUserSettingChanged(WFC_ENABLED_URI);
-        mQnsEventDispatcher.onUserSettingChanged(WFC_MODE_URI);
-        mQnsEventDispatcher.onUserSettingChanged(WFC_ROAMING_ENABLED_URI);
-        mQnsEventDispatcher.onUserSettingChanged(WFC_ROAMIN_MODE_URI);
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, CROSS_SIM_URI);
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_ENABLED_URI);
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_MODE_URI);
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_ROAMING_ENABLED_URI);
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_ROAMIN_MODE_URI);
 
         verify(mMockMessage, times(2)).sendToTarget();
         verify(mMockMessage1, times(2)).sendToTarget();
-        verify(mMockMessage4, times(1)).sendToTarget();
+        verify(mMockMessage4, atLeastOnce()).sendToTarget();
         verify(mMockMessage2, times(2)).sendToTarget();
-        verify(mMockMessage5, times(1)).sendToTarget();
+        verify(mMockMessage5, atLeastOnce()).sendToTarget();
+    }
+
+    @Test
+    public void testOnUserSettingChangedEventEnabledStatus() {
+        setEnabledStatusForWfcSettingsCrossSimSettings();
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_CROSS_SIM_CALLING_ENABLED)))
+                .thenReturn(mMockMessage);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_ENABLED)))
+                .thenReturn(mMockMessage1);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_ONLY)))
+                .thenReturn(mMockMessage4);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_ENABLED)))
+                .thenReturn(mMockMessage2);
+        when(mMockHandler.obtainMessage(
+                        eq(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_ONLY)))
+                .thenReturn(mMockMessage5);
+        when(mMockHandler.obtainMessage(eq(QnsEventDispatcher.QNS_EVENT_CARRIER_CONFIG_CHANGED)))
+                .thenReturn(mMockMessage3);
+
+        List<Integer> events = new ArrayList<Integer>();
+        events.add(QnsEventDispatcher.QNS_EVENT_CROSS_SIM_CALLING_ENABLED);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_ENABLED);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_ONLY);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_ENABLED);
+        events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_ONLY);
+        events.add(QnsEventDispatcher.QNS_EVENT_CARRIER_CONFIG_CHANGED);
+        mQnsEventDispatcher.registerEvent(events, mMockHandler);
+
+        // Send ACTION_CARRIER_CONFIG_CHANGED intent with valid Carrier id
+        final Intent validCarrierIdintent =
+                new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        validCarrierIdintent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, DEFAULT_SLOT_INDEX);
+        validCarrierIdintent.putExtra(TelephonyManager.EXTRA_CARRIER_ID, DEFAULT_CARRIER_INDEX);
+        mQnsEventDispatcher.mIntentReceiver.onReceive(mMockContext, validCarrierIdintent);
+
+        verify(mMockMessage, times(2)).sendToTarget();
+        verify(mMockMessage1, times(2)).sendToTarget();
+        verify(mMockMessage4, times(2)).sendToTarget();
+        verify(mMockMessage2, times(2)).sendToTarget();
+        verify(mMockMessage5, times(2)).sendToTarget();
+        verify(mMockMessage3, times(1)).sendToTarget();
+
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, CROSS_SIM_URI);
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_ENABLED_URI);
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_MODE_URI);
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_ROAMING_ENABLED_URI);
+        mQnsEventDispatcher.mUserSettingObserver.onChange(true, WFC_ROAMIN_MODE_URI);
+
+        verify(mMockMessage, times(2)).sendToTarget();
+        verify(mMockMessage1, times(2)).sendToTarget();
+        verify(mMockMessage4, times(2)).sendToTarget();
+        verify(mMockMessage2, times(2)).sendToTarget();
+        verify(mMockMessage5, times(2)).sendToTarget();
     }
 }
diff --git a/tests/src/com/android/qns/QnsProvisioningListenerTest.java b/tests/src/com/android/qns/QnsProvisioningListenerTest.java
index 342cfac..17c1b48 100644
--- a/tests/src/com/android/qns/QnsProvisioningListenerTest.java
+++ b/tests/src/com/android/qns/QnsProvisioningListenerTest.java
@@ -21,7 +21,9 @@
 import static org.junit.Assert.*;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -98,7 +100,8 @@
     private void captureProvisioningHandler() throws ImsException {
         ArgumentCaptor<ProvisioningManager.Callback> arg =
                 ArgumentCaptor.forClass(ProvisioningManager.Callback.class);
-        verify(mMockProvisioningManager)
+
+        verify(mMockProvisioningManager, atLeast(1))
                 .registerProvisioningChangedCallback(isA(Executor.class), arg.capture());
         mQnsProvisioningCallback = arg.getValue();
     }
@@ -240,6 +243,11 @@
 
         // test clear()
         info.clear();
+        mQnsProvisioningListener.mQnsProvisioningHandler.handleMessage(
+                Message.obtain(
+                        mQnsProvisioningListener.mQnsProvisioningHandler,
+                        QnsEventDispatcher.QNS_EVENT_SIM_ABSENT,
+                        null));
         assertNull(info.getIntegerItem(ProvisioningManager.KEY_VOICE_OVER_WIFI_MODE_OVERRIDE));
         assertNull(info.getIntegerItem(ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS));
         assertNull(info.getStringItem(ProvisioningManager.KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID));
@@ -294,4 +302,54 @@
                 info3.equalsIntegerItem(
                         info1, ProvisioningManager.KEY_VOICE_OVER_WIFI_MODE_OVERRIDE));
     }
+
+    @Test
+    public void testUnregisterProvisioningCallback() throws ImsException {
+        mQnsProvisioningListener.mQnsProvisioningHandler.handleMessage(
+                Message.obtain(
+                        mQnsProvisioningListener.mQnsProvisioningHandler,
+                        QnsEventDispatcher.QNS_EVENT_SIM_LOADED,
+                        null));
+
+        ArgumentCaptor<ProvisioningManager.Callback> arg =
+                ArgumentCaptor.forClass(ProvisioningManager.Callback.class);
+        verify(mMockProvisioningManager).unregisterProvisioningChangedCallback(arg.capture());
+
+        captureProvisioningHandler();
+    }
+
+    @Test
+    public void testOnQnsConfigEventChangedEventHandler() throws ImsException {
+        mQnsProvisioningListener.mQnsProvisioningHandler.handleMessage(
+                Message.obtain(
+                        mQnsProvisioningListener.mQnsProvisioningHandler,
+                        QnsEventDispatcher.QNS_EVENT_CARRIER_CONFIG_CHANGED,
+                        null));
+
+        ArgumentCaptor<ProvisioningManager.Callback> arg =
+                ArgumentCaptor.forClass(ProvisioningManager.Callback.class);
+        verify(mMockProvisioningManager, times(1))
+                .registerProvisioningChangedCallback(isA(Executor.class), arg.capture());
+        mQnsProvisioningCallback = arg.getValue();
+    }
+
+    @Test
+    public void testOnIwlanNetworkStatusChangedEventHandler() throws ImsException {
+        mQnsProvisioningListener.mQnsProvisioningHandler.handleMessage(
+                Message.obtain(mQnsProvisioningListener.mQnsProvisioningHandler, 11002, null));
+
+        IwlanNetworkStatusTracker.IwlanAvailabilityInfo info =
+                mMockIwlanNetworkStatusTracker.new IwlanAvailabilityInfo(true, false);
+
+        mQnsProvisioningListener.mQnsProvisioningHandler.handleMessage(
+                Message.obtain(
+                        mQnsProvisioningListener.mQnsProvisioningHandler,
+                        11002,
+                        new AsyncResult(null, info, null)));
+        ArgumentCaptor<ProvisioningManager.Callback> arg =
+                ArgumentCaptor.forClass(ProvisioningManager.Callback.class);
+        verify(mMockProvisioningManager, times(1))
+                .registerProvisioningChangedCallback(isA(Executor.class), arg.capture());
+        mQnsProvisioningCallback = arg.getValue();
+    }
 }
diff --git a/tests/src/com/android/qns/QnsTelephonyListenerTest.java b/tests/src/com/android/qns/QnsTelephonyListenerTest.java
index 662bbb8..494c804 100644
--- a/tests/src/com/android/qns/QnsTelephonyListenerTest.java
+++ b/tests/src/com/android/qns/QnsTelephonyListenerTest.java
@@ -16,10 +16,16 @@
 
 package com.android.qns;
 
+import static android.telephony.NrVopsSupportInfo.NR_STATUS_VOPS_3GPP_SUPPORTED;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.qns.QualityMonitor.EVENT_SUBSCRIPTION_ID_CHANGED;
+
 import static org.junit.Assert.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import android.content.Context;
 import android.net.LinkProperties;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -30,6 +36,7 @@
 import android.telephony.BarringInfo;
 import android.telephony.LteVopsSupportInfo;
 import android.telephony.NetworkRegistrationInfo;
+import android.telephony.NrVopsSupportInfo;
 import android.telephony.PreciseDataConnectionState;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
@@ -46,6 +53,7 @@
 import org.junit.runners.JUnit4;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
 
 import java.util.concurrent.Executor;
 
@@ -55,6 +63,7 @@
     private static final int CONDITIONAL_BARRING_FACTOR = 100;
     private static final int CONDITIONAL_BARRING_TIME = 20;
     QnsTelephonyListener mQtListener;
+    MockitoSession mStaticMockSession;
 
     Handler h;
     HandlerThread mHandlerThread =
@@ -71,7 +80,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         super.setUp();
-
+        mStaticMockSession = mockitoSession().mockStatic(QnsUtils.class).startMocking();
         doAnswer(invocation -> null)
                 .when(mockSubscriptionManager)
                 .addOnSubscriptionsChangedListener(
@@ -85,7 +94,10 @@
 
     @After
     public void tearDown() {
-        mQtListener.close();
+        mStaticMockSession.finishMocking();
+
+        if (mQtListener != null) mQtListener.close();
+
         if (mHandlerThread != null) {
             mHandlerThread.quit();
         }
@@ -146,7 +158,7 @@
         assertFalse(qtInfo.isCoverage());
         assertFalse(qtInfo.isCellularAvailable());
 
-        testOnCellularServiceStateChanged();
+        testOnCellularServiceStateChangedWithLteVopsOnHome();
 
         qtInfo = mQtListener.getLastQnsTelephonyInfo();
         assertEquals(ServiceState.STATE_IN_SERVICE, qtInfo.getDataRegState());
@@ -192,8 +204,8 @@
                         .setFailCause(27)
                         .build();
 
-        mQtListener.onPreciseDataConnectionStateChanged(connectionStateXcap);
-        mQtListener.onPreciseDataConnectionStateChanged(connectionStateIms);
+        mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(connectionStateXcap);
+        mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(connectionStateIms);
 
         output = mQtListener.getLastPreciseDataConnectionState(ApnSetting.TYPE_IMS);
         assertNotEquals(connectionStateXcap, output);
@@ -236,18 +248,19 @@
                         .setLinkProperties(new LinkProperties())
                         .setFailCause(0)
                         .build();
-        mQtListener.onPreciseDataConnectionStateChanged(connectedStateIms);
-        mQtListener.onPreciseDataConnectionStateChanged(handoverStateIms);
+        mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(connectedStateIms);
+        mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(handoverStateIms);
 
         mQtListener.close();
 
         mQtListener = QnsTelephonyListener.getInstance(sMockContext, 0);
 
-        mQtListener.onPreciseDataConnectionStateChanged(handoverStateIms);
+        mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(handoverStateIms);
         output = mQtListener.getLastPreciseDataConnectionState(ApnSetting.TYPE_IMS);
         assertNull(output);
 
-        mQtListener.onPreciseDataConnectionStateChanged(connectedStateIms);
+        mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(connectedStateIms);
+
         output = mQtListener.getLastPreciseDataConnectionState(ApnSetting.TYPE_IMS);
         assertNull(output);
     }
@@ -373,6 +386,7 @@
 
     @Test
     public void testStartTelephonyListener() {
+        mQtListener.mSubscriptionsChangeListener.onSubscriptionsChanged();
         mQtListener.startTelephonyListener(1);
         verify(mockTelephonyManager, atLeastOnce())
                 .registerTelephonyCallback(
@@ -386,33 +400,46 @@
     }
 
     @Test
-    public void testOnCellularServiceStateChanged() {
-        ServiceState ss = new ServiceState();
+    public void testRegisterSubscriptionsIDChangedListener() {
+        lenient()
+                .when(QnsUtils.getSubId(isA(Context.class), anyInt()))
+                .thenReturn(-1)
+                .thenReturn(1);
+        mQtListener.registerSubscriptionIdListener(h, EVENT_SUBSCRIPTION_ID_CHANGED, null);
+        mQtListener.mSubscriptionsChangeListener.onSubscriptionsChanged();
+        Message msg = mTestLooper.nextMessage();
+        assertNull(msg);
+
+        mQtListener.mSubscriptionsChangeListener.onSubscriptionsChanged();
+        msg = mTestLooper.nextMessage();
+        assertNotNull(msg);
+        assertEquals(EVENT_SUBSCRIPTION_ID_CHANGED, msg.what);
+
+        mQtListener.mSubscriptionsChangeListener.onSubscriptionsChanged();
+        msg = mTestLooper.nextMessage();
+        assertNull(msg);
+    }
+
+    @Test
+    public void testUnregisterSubscriptionsIDChanged() {
+        lenient().when(QnsUtils.getSubId(sMockContext, 0)).thenReturn(0);
+        mQtListener.registerSubscriptionIdListener(h, EVENT_SUBSCRIPTION_ID_CHANGED, null);
+        mQtListener.unregisterSubscriptionIdChanged(h);
+        mQtListener.mSubscriptionsChangeListener.onSubscriptionsChanged();
+        Message msg = mTestLooper.nextMessage();
+        assertNull(msg);
+    }
+
+    @Test
+    public void testOnCellularServiceStateChangedWithLteVopsOnHome() {
         VopsSupportInfo vopsSupportInfo =
                 new LteVopsSupportInfo(
                         LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
                         LteVopsSupportInfo.LTE_STATUS_SUPPORTED);
-        NetworkRegistrationInfo nri =
-                new NetworkRegistrationInfo(
-                        NetworkRegistrationInfo.DOMAIN_PS,
-                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                        NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
-                        TelephonyManager.NETWORK_TYPE_LTE,
-                        0,
-                        false,
-                        null,
-                        null,
-                        "00101",
-                        10,
-                        false,
-                        true,
-                        true,
-                        vopsSupportInfo);
-        ss.setRilVoiceRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
-        ss.addNetworkRegistrationInfo(nri);
-        ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
-
-        mQtListener.onServiceStateChanged(ss);
+        setOnCellularServiceStateChangedWithLteVopsOn(
+                vopsSupportInfo,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
 
         assertEquals(
                 ServiceState.STATE_IN_SERVICE,
@@ -433,9 +460,139 @@
         assertFalse(mQtListener.mLastQnsTelephonyInfoIms.getVoiceBarring());
         assertTrue(mQtListener.mLastQnsTelephonyInfoIms.getVopsEmergencySupport());
         assertTrue(mQtListener.mLastQnsTelephonyInfoIms.getVopsSupport());
+    }
+
+    @Test
+    public void testOnCellularServiceStateChangedWithLteVopsOnRoam() {
+        VopsSupportInfo vopsSupportInfo =
+                new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED);
+        setOnCellularServiceStateChangedWithLteVopsOn(
+                vopsSupportInfo,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+
+        assertEquals(
+                ServiceState.STATE_IN_SERVICE,
+                mQtListener.mLastQnsTelephonyInfoIms.getDataRegState());
+        assertEquals(
+                ServiceState.RIL_RADIO_TECHNOLOGY_LTE,
+                mQtListener.mLastQnsTelephonyInfoIms.getDataTech());
+        assertEquals(
+                ServiceState.RIL_RADIO_TECHNOLOGY_LTE,
+                mQtListener.mLastQnsTelephonyInfoIms.getVoiceTech());
+        assertEquals("00101", mQtListener.mLastQnsTelephonyInfoIms.getRegisteredPlmn());
+        assertTrue(mQtListener.mLastQnsTelephonyInfoIms.isCoverage());
+        assertTrue(mQtListener.mLastQnsTelephonyInfoIms.isCellularAvailable());
+        assertFalse(mQtListener.mLastQnsTelephonyInfoIms.getEmergencyBarring());
+        assertFalse(mQtListener.mLastQnsTelephonyInfoIms.getVoiceBarring());
+        assertTrue(mQtListener.mLastQnsTelephonyInfoIms.getVopsEmergencySupport());
+        assertTrue(mQtListener.mLastQnsTelephonyInfoIms.getVopsSupport());
+    }
+
+    @Test
+    public void testOnCellularServiceStateChangedWithNrVopsOn() {
+        VopsSupportInfo vopsSupportInfo =
+                new NrVopsSupportInfo(
+                        NR_STATUS_VOPS_3GPP_SUPPORTED,
+                        NR_STATUS_VOPS_3GPP_SUPPORTED,
+                        NR_STATUS_VOPS_3GPP_SUPPORTED);
+        validateOnCellularServiceStateChangedWithNrVopsOn(vopsSupportInfo);
+    }
+
+    @Test
+    public void testOnCellularServiceStateChangedWithLteVopsOff() {
+        testOnCellularServiceStateChangedWithLteVopsOnHome();
+
+        // Update Vops Information
+        ServiceState ss = new ServiceState();
+        VopsSupportInfo vopsSupportInfo =
+                new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED);
+        NetworkRegistrationInfo nri =
+                new NetworkRegistrationInfo(
+                        NetworkRegistrationInfo.DOMAIN_PS,
+                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                        NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
+                        TelephonyManager.NETWORK_TYPE_LTE,
+                        0,
+                        false,
+                        null,
+                        null,
+                        "00101",
+                        10,
+                        false,
+                        true,
+                        true,
+                        vopsSupportInfo);
+        ss.setRilVoiceRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+        ss.addNetworkRegistrationInfo(nri);
+        ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+        assertTrue(mQtListener.mLastQnsTelephonyInfoIms.getVopsEmergencySupport());
+        assertTrue(mQtListener.mLastQnsTelephonyInfoIms.getVopsSupport());
+        mQtListener.mTelephonyListener.onServiceStateChanged(ss);
+
+        // Validate Vops Updated information
+        assertFalse(mQtListener.mLastQnsTelephonyInfoIms.getVopsEmergencySupport());
+        assertFalse(mQtListener.mLastQnsTelephonyInfoIms.getVopsSupport());
+    }
+
+    private void setOnCellularServiceStateChangedWithLteVopsOn(
+            VopsSupportInfo vopsSupportInfo, int domain, int coverage) {
+        ServiceState ss = new ServiceState();
+        NetworkRegistrationInfo nri =
+                new NetworkRegistrationInfo(
+                        domain,
+                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                        coverage,
+                        TelephonyManager.NETWORK_TYPE_LTE,
+                        0,
+                        false,
+                        null,
+                        null,
+                        "00101",
+                        10,
+                        false,
+                        true,
+                        true,
+                        vopsSupportInfo);
+        ss.setRilVoiceRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+        ss.addNetworkRegistrationInfo(nri);
+        ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+        mQtListener.mTelephonyListener.onServiceStateChanged(ss);
         assertEquals(ss, mQtListener.mLastServiceState);
     }
 
+    private void validateOnCellularServiceStateChangedWithNrVopsOn(
+            VopsSupportInfo vopsSupportInfo) {
+        ServiceState ss = new ServiceState();
+        NetworkRegistrationInfo nri =
+                new NetworkRegistrationInfo(
+                        NetworkRegistrationInfo.DOMAIN_PS,
+                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                        NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
+                        TelephonyManager.NETWORK_TYPE_NR,
+                        0,
+                        false,
+                        null,
+                        null,
+                        "00101",
+                        10,
+                        false,
+                        true,
+                        true,
+                        vopsSupportInfo);
+        ss.setRilVoiceRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_NR);
+        ss.addNetworkRegistrationInfo(nri);
+        ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+        mQtListener.mTelephonyListener.onServiceStateChanged(ss);
+
+        assertTrue(mQtListener.mLastQnsTelephonyInfoIms.getVopsEmergencySupport());
+        assertTrue(mQtListener.mLastQnsTelephonyInfoIms.getVopsSupport());
+    }
+
     @Test
     public void testIsAirplaneModeEnabled() {
         assertFalse(mQtListener.isAirplaneModeEnabled());
@@ -443,22 +600,29 @@
         ServiceState ss = new ServiceState();
         ss.setRilVoiceRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
         ss.setVoiceRegState(ServiceState.STATE_POWER_OFF);
-        mQtListener.onServiceStateChanged(ss);
 
+        mQtListener.mTelephonyListener.onServiceStateChanged(ss);
         assertTrue(mQtListener.isAirplaneModeEnabled());
     }
 
     @Test
     public void testIsSupportVoPS() {
         assertFalse(mQtListener.isSupportVoPS());
-        testOnCellularServiceStateChanged();
+        testOnCellularServiceStateChangedWithLteVopsOnHome();
         assertTrue(mQtListener.isSupportVoPS());
     }
 
     @Test
+    public void testIsSupportVopsWithNullRegistrationInfo() {
+        ServiceState ss = new ServiceState();
+        ss.addNetworkRegistrationInfo(null);
+        assertFalse(mQtListener.isSupportVoPS());
+    }
+
+    @Test
     public void testIsSupportEmergencyService() {
         assertFalse(mQtListener.isSupportEmergencyService());
-        testOnCellularServiceStateChanged();
+        testOnCellularServiceStateChangedWithLteVopsOnHome();
         assertTrue(mQtListener.isSupportEmergencyService());
     }
 
@@ -486,7 +650,7 @@
 
         mQtListener.registerPreciseDataConnectionStateChanged(
                 ApnSetting.TYPE_XCAP, h, 1, null, false);
-        mQtListener.onPreciseDataConnectionStateChanged(connectionState);
+        mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(connectionState);
 
         Message msg = mTestLooper.nextMessage();
         assertNull(msg); // connection state is for IMS, but XCAP registered. So not notified.
@@ -510,7 +674,7 @@
 
         mQtListener.registerPreciseDataConnectionStateChanged(
                 ApnSetting.TYPE_IMS, h, 1, null, false);
-        mQtListener.onPreciseDataConnectionStateChanged(connectionState);
+        mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(connectionState);
 
         msg = mTestLooper.nextMessage();
         assertNotNull(msg);
@@ -522,22 +686,22 @@
     @Test
     public void testIsVoiceBarring() {
         BarringInfo barringInfo = setupBarringInfo(true, false);
-        mQtListener.onBarringInfoChanged(barringInfo);
+        mQtListener.mTelephonyListener.onBarringInfoChanged(barringInfo);
         assertTrue(mQtListener.isVoiceBarring());
 
         barringInfo = setupBarringInfo(false, false);
-        mQtListener.onBarringInfoChanged(barringInfo);
+        mQtListener.mTelephonyListener.onBarringInfoChanged(barringInfo);
         assertFalse(mQtListener.isVoiceBarring());
     }
 
     @Test
     public void testIsEmergencyBarring() {
         BarringInfo barringInfo = setupBarringInfo(false, true);
-        mQtListener.onBarringInfoChanged(barringInfo);
+        mQtListener.mTelephonyListener.onBarringInfoChanged(barringInfo);
         assertTrue(mQtListener.isEmergencyBarring());
 
         barringInfo = setupBarringInfo(false, false);
-        mQtListener.onBarringInfoChanged(barringInfo);
+        mQtListener.mTelephonyListener.onBarringInfoChanged(barringInfo);
         assertFalse(mQtListener.isEmergencyBarring());
     }
 
@@ -546,7 +710,7 @@
         mQtListener.registerQnsTelephonyInfoChanged(ApnSetting.TYPE_IMS, h, 1, null, false);
 
         BarringInfo barringInfo = setupBarringInfo(true, true);
-        mQtListener.onBarringInfoChanged(barringInfo);
+        mQtListener.mTelephonyListener.onBarringInfoChanged(barringInfo);
 
         Message msg = mTestLooper.nextMessage();
         assertNotNull(msg);
@@ -561,7 +725,7 @@
         mQtListener.registerQnsTelephonyInfoChanged(ApnSetting.TYPE_IMS, h, 1, null, false);
 
         BarringInfo barringInfo = setupBarringInfo(true, false);
-        mQtListener.onBarringInfoChanged(barringInfo);
+        mQtListener.mTelephonyListener.onBarringInfoChanged(barringInfo);
 
         Message msg = mTestLooper.nextMessage();
         assertNotNull(msg);
@@ -576,7 +740,7 @@
         mQtListener.registerQnsTelephonyInfoChanged(ApnSetting.TYPE_IMS, h, 1, null, false);
 
         BarringInfo barringInfo = setupBarringInfo(false, true);
-        mQtListener.onBarringInfoChanged(barringInfo);
+        mQtListener.mTelephonyListener.onBarringInfoChanged(barringInfo);
 
         Message msg = mTestLooper.nextMessage();
         assertNotNull(msg);
@@ -637,7 +801,7 @@
                     TelephonyManager.CALL_STATE_OFFHOOK
                 };
         for (int state : callStates) {
-            mQtListener.onCallStateChanged(state);
+            mQtListener.mTelephonyListener.onCallStateChanged(state);
             Message msg = mTestLooper.nextMessage();
             assertNotNull(msg);
             assertEquals(state, (int) ((AsyncResult) msg.obj).result);
@@ -656,7 +820,7 @@
                     TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED
                 };
         for (int state : srvccStates) {
-            mQtListener.onSrvccStateChanged(state);
+            mQtListener.mTelephonyListener.onSrvccStateChanged(state);
             Message msg = mTestLooper.nextMessage();
             assertNotNull(msg);
             assertEquals(state, (int) ((AsyncResult) msg.obj).result);
diff --git a/tests/src/com/android/qns/QualifiedNetworksServiceImplTest.java b/tests/src/com/android/qns/QualifiedNetworksServiceImplTest.java
index 2b54696..82d073c 100644
--- a/tests/src/com/android/qns/QualifiedNetworksServiceImplTest.java
+++ b/tests/src/com/android/qns/QualifiedNetworksServiceImplTest.java
@@ -30,7 +30,9 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.os.AsyncResult;
 import android.os.Handler;
+import android.os.Message;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.data.ApnSetting;
@@ -54,6 +56,7 @@
 
     QualifiedNetworksServiceImpl mQualifiedNetworksService;
     private static final int TEST_QNS_CONFIGURATION_LOADED = 1;
+    private static final int TEST_QUALIFIED_NETWORKS_CHANGED = 2;
     private static final int TEST_QNS_CONFIGURATION_CHANGED = 2;
     MockitoSession mMockitoSession;
     @Mock private QnsCarrierConfigManager mMockConfigManager;
@@ -73,7 +76,6 @@
                         .mockStatic(QnsProvisioningListener.class)
                         .startMocking();
         mQualifiedNetworksService = new QualifiedNetworksServiceImpl();
-
         Field f = QualifiedNetworksServiceImpl.class.getDeclaredField("mContext");
         f.setAccessible(true);
         f.set(mQualifiedNetworksService, sMockContext);
@@ -212,12 +214,35 @@
     public void testOnConfigurationChanged() {
         QualifiedNetworksServiceImpl.NetworkAvailabilityProviderImpl provider =
                 mQualifiedNetworksService.new NetworkAvailabilityProviderImpl(mSlotIndex);
+        provider.mConfigHandler.handleMessage(
+                Message.obtain(provider.mConfigHandler, TEST_QNS_CONFIGURATION_LOADED, null));
         ArgumentCaptor<Handler> capture = ArgumentCaptor.forClass(Handler.class);
+
         verify(mMockConfigManager)
                 .registerForConfigurationLoaded(
                         capture.capture(), eq(TEST_QNS_CONFIGURATION_LOADED));
+
         Handler configHandler = capture.getValue();
         configHandler.sendEmptyMessage(TEST_QNS_CONFIGURATION_CHANGED);
-        // Yet to verity - method not implemented yet.
+        provider.mConfigHandler.handleMessage(
+                Message.obtain(provider.mConfigHandler, TEST_QNS_CONFIGURATION_CHANGED, null));
+        provider.mConfigHandler.handleMessage(
+                Message.obtain(provider.mConfigHandler, TEST_QUALIFIED_NETWORKS_CHANGED, null));
+    }
+
+    @Test
+    public void testQnsChangedHandlerEvent() {
+        QualifiedNetworksServiceImpl.NetworkAvailabilityProviderImpl provider =
+                mQualifiedNetworksService.new NetworkAvailabilityProviderImpl(mSlotIndex);
+        QualifiedNetworksInfo info =
+                new QualifiedNetworksInfo(ApnSetting.TYPE_IMS, new ArrayList<>());
+        info.setAccessNetworkTypes(List.of(AccessNetworkType.EUTRAN));
+        AsyncResult ar = new AsyncResult(null, info, null);
+        provider.mHandler.handleMessage(
+                Message.obtain(provider.mHandler, TEST_QUALIFIED_NETWORKS_CHANGED, ar));
+        assertEquals(info.getApnType(), ApnSetting.TYPE_IMS);
+        assertEquals(List.of(AccessNetworkType.EUTRAN), info.getAccessNetworkTypes());
+        provider.mHandler.handleMessage(
+                Message.obtain(provider.mHandler, TEST_QNS_CONFIGURATION_LOADED, ar));
     }
 }
diff --git a/tests/src/com/android/qns/RestrictManagerTest.java b/tests/src/com/android/qns/RestrictManagerTest.java
index 3ec9faa..4286be3 100644
--- a/tests/src/com/android/qns/RestrictManagerTest.java
+++ b/tests/src/com/android/qns/RestrictManagerTest.java
@@ -69,7 +69,6 @@
 import org.mockito.MockitoSession;
 
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 @RunWith(JUnit4.class)
 public class RestrictManagerTest extends QnsTest {
@@ -1421,7 +1420,7 @@
                 mRestrictManager.hasRestrictionType(
                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                         RESTRICT_TYPE_FALLBACK_ON_DATA_CONNECTION_FAIL));
-        mTestLooper.moveTimeForward(11000);
+        mTestLooper.moveTimeForward(10000);
         mTestLooper.dispatchAll();
         assertFalse(
                 mRestrictManager.hasRestrictionType(
@@ -1717,13 +1716,8 @@
                                 DataConnectionStatusTracker.STATE_CONNECTED,
                                 AccessNetworkConstants.TRANSPORT_TYPE_WLAN),
                         null);
-        Message.obtain(mRestrictManager.mHandler, 3001, asyncResult).sendToTarget();
-        mLatch.await(2, TimeUnit.SECONDS);
-        Message msg = mTestLooper.nextMessage();
-        assertNotNull(msg);
-        assertNotNull(msg.obj);
-        AsyncResult ar = (AsyncResult) msg.obj;
-        assertNotNull(ar);
+        mRestrictManager.mHandler.handleMessage(
+                Message.obtain(mRestrictManager.mHandler, 3001, asyncResult));
 
         // Receive Handover started over Wwan
         asyncResult =
@@ -1734,30 +1728,12 @@
                                 DataConnectionStatusTracker.STATE_HANDOVER,
                                 AccessNetworkConstants.TRANSPORT_TYPE_WLAN),
                         null);
-        Message.obtain(mRestrictManager.mHandler, 3001, asyncResult).sendToTarget();
-        mLatch.await(2, TimeUnit.SECONDS);
-        msg = mTestLooper.nextMessage();
-        assertNotNull(msg);
-        assertNotNull(msg.obj);
-        ar = (AsyncResult) msg.obj;
-        assertNotNull(ar);
+        mRestrictManager.mHandler.handleMessage(
+                Message.obtain(mRestrictManager.mHandler, 3001, asyncResult));
 
-        // Receive Handover Success over Wwan
-        asyncResult =
-                new AsyncResult(
-                        null,
-                        new DataConnectionStatusTracker.DataConnectionChangedInfo(
-                                EVENT_DATA_CONNECTION_HANDOVER_SUCCESS,
-                                DataConnectionStatusTracker.STATE_CONNECTED,
-                                AccessNetworkConstants.TRANSPORT_TYPE_WWAN),
-                        null);
-        Message.obtain(mRestrictManager.mHandler, 3001, asyncResult).sendToTarget();
-        mLatch.await(2, TimeUnit.SECONDS);
-        msg = mTestLooper.nextMessage();
-        assertNotNull(msg);
-        assertNotNull(msg.obj);
-        ar = (AsyncResult) msg.obj;
-        assertNotNull(ar);
+        // start Guarding operation of Source Rat during HO in progress
+        mRestrictManager.hasRestrictionType(
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN, RESTRICT_TYPE_GUARDING);
     }
 
     @Test