Synchronize triggering of emergency network scan

Ignore duplicated callbacks

Bug: 243878608
Bug: 264333443
Test: atest EmergencyCallDomainSelectorTest
Change-Id: I97d27be7ba72d39f82a643e58299f06678f850d5
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index 9aaf6da..dcb1de7 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -221,8 +221,14 @@
 
     @Override
     public void reselectDomain(SelectionAttributes attr) {
-        logi("reselectDomain tryCsWhenPsFails=" + mTryCsWhenPsFails + ", attr=" + attr);
+        logi("reselectDomain attr=" + attr);
         mSelectionAttributes = attr;
+        post(() -> { reselectDomain(); });
+    }
+
+    private void reselectDomain() {
+        logi("reselectDomain tryCsWhenPsFails=" + mTryCsWhenPsFails);
+
         if (mTryCsWhenPsFails) {
             mTryCsWhenPsFails = false;
             mCsNetworkType = getSelectableCsNetworkType();
@@ -241,10 +247,7 @@
 
         if (mLastTransportType == TRANSPORT_TYPE_WLAN) {
             // Dialing over Wi-Fi failed. Try scanning cellular networks.
-            onWwanSelected(() -> {
-                requestScan(true, false, true);
-                mDomainSelected = false;
-            });
+            onWwanSelected(this::reselectDomainInternal);
             return;
         }
 
@@ -252,6 +255,13 @@
         mDomainSelected = false;
     }
 
+    private void reselectDomainInternal() {
+        post(() -> {
+            requestScan(true, false, true);
+            mDomainSelected = false;
+        });
+    }
+
     @Override
     public void finishSelection() {
         logi("finishSelection");
@@ -422,6 +432,10 @@
     }
 
     private void selectDomainInternal() {
+        post(this::selectDomainFromInitialState);
+    }
+
+    private void selectDomainFromInitialState() {
         if (getImsNetworkTypeConfiguration().isEmpty()
                 || (mRequiresVoLteEnabled && !isAdvancedCallingSettingEnabled())) {
             // Emergency call over IMS is not supported.
@@ -896,6 +910,12 @@
 
     private void onWlanSelected() {
         logi("onWlanSelected");
+        if (mLastTransportType == TRANSPORT_TYPE_WLAN) {
+            logi("onWlanSelected ignore duplicated callback");
+            return;
+        }
+
+        mDomainSelected = true;
         mLastTransportType = TRANSPORT_TYPE_WLAN;
         mVoWifiTrialCount++;
         mTransportSelectorCallback.onWlanSelected();
@@ -904,10 +924,8 @@
 
     private void onWwanSelected(Runnable runnable) {
         logi("onWwanSelected");
-        if (mLastTransportType == TRANSPORT_TYPE_WWAN
-                && mWwanSelectorCallback != null) {
-            logi("onWwanSelected already notified");
-            runnable.run();
+        if (mLastTransportType == TRANSPORT_TYPE_WWAN) {
+            logi("onWwanSelected ignore duplicated callback");
             return;
         }
 
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index e1de0ab..3f6ce98 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -903,6 +903,39 @@
         verify(mTransportSelectorCallback, times(1)).onWlanSelected();
     }
 
+    @Test
+    public void testIgnoreDuplicatedCallbacks() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService(true);
+
+        verify(mTransportSelectorCallback, times(1)).onWwanSelected(any());
+
+        // duplicated event
+        unsolBarringInfoChanged(true);
+
+        // ignore duplicated callback, no change in interaction
+        verify(mTransportSelectorCallback, times(1)).onWwanSelected(any());
+
+        mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
+
+        verify(mTransportSelectorCallback, times(1)).onWlanSelected();
+
+        // duplicated event
+        mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
+
+        // ignore duplicated callback, no change in interaction
+        verify(mTransportSelectorCallback, times(1)).onWlanSelected();
+    }
+
     private void createSelector(int subId) throws Exception {
         mDomainSelector = new EmergencyCallDomainSelector(
                 mContext, SLOT_0, subId, mHandlerThread.getLooper(),
@@ -913,10 +946,12 @@
     }
 
     private void verifyCsDialed() {
+        processAllMessages();
         verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS));
     }
 
     private void verifyPsDialed() {
+        processAllMessages();
         verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_PS));
     }
 
@@ -929,6 +964,7 @@
     }
 
     private void verifyScanPreferred(int scanType, int expectedPreferredAccessNetwork) {
+        processAllMessages();
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
                 any(), eq(scanType), any(), any());
         assertEquals(expectedPreferredAccessNetwork, (int) mAccessNetwork.get(0));