Dismiss TOFU dialog when the corresponding wifi entry is forgotten

Currently TOFU dialog is not dismissed when the corresponding wifi entry
is actually forgotten.

Add maybeDismissTofuDialog to InsecureEapNetworkHandler and call it in
the network update listener when network is removed by user clicking
forget.

Bug: 262456737
Test: atest InsecureEapNetworkHandlerTest
Change-Id: I88907dd32320e811004ec690da1a35a9856936f4
diff --git a/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java b/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java
index 97c9468..347620f 100644
--- a/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java
+++ b/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java
@@ -74,6 +74,7 @@
     private final InsecureEapNetworkHandlerCallbacks mCallbacks;
     private final String mInterfaceName;
     private final Handler mHandler;
+    private final OnNetworkUpdateListener mOnNetworkUpdateListener;
 
     // The latest connecting configuration from the caller, it is updated on calling
     // prepareConnection() always. This is used to ensure that current TOFU config is aligned
@@ -140,6 +141,9 @@
         mInterfaceName = interfaceName;
         mHandler = handler;
 
+        mOnNetworkUpdateListener = new OnNetworkUpdateListener();
+        mWifiConfigManager.addOnNetworkUpdateListener(mOnNetworkUpdateListener);
+
         mCaCertHelpLink = mContext.getString(R.string.config_wifiCertInstallationHelpLink);
     }
 
@@ -232,6 +236,7 @@
         dismissDialogAndNotification();
         unregisterCertificateNotificationReceiver();
         clearInternalData();
+        mWifiConfigManager.removeOnNetworkUpdateListener(mOnNetworkUpdateListener);
     }
 
     /**
@@ -782,4 +787,20 @@
          */
         public void onError(@Nullable String ssid) {}
     }
+
+    /**
+     * Listener for config manager network config related events.
+     */
+    private class OnNetworkUpdateListener implements
+            WifiConfigManager.OnNetworkUpdateListener {
+        @Override
+        public void onNetworkRemoved(WifiConfiguration config) {
+            // Dismiss TOFU dialog if the network of the current Tofu config is removed.
+            if (config == null || mCurrentTofuConfig == null
+                    || mTofuAlertDialog == null
+                    || config.networkId != mCurrentTofuConfig.networkId) return;
+
+            dismissDialogAndNotification();
+        }
+    }
 }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 93ade70..5c830b2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -2202,7 +2202,10 @@
         // Simulate the target network removal & the disconnect trigger.
         WifiConfiguration removedNetwork = new WifiConfiguration();
         removedNetwork.networkId = FRAMEWORK_NETWORK_ID;
-        mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedNetwork);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkRemoved(removedNetwork);
+        }
         mLooper.dispatchAll();
 
         verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID);
@@ -2884,7 +2887,10 @@
         // trigger removal callback to trigger disconnect.
         WifiConfiguration removedConfig = new WifiConfiguration();
         removedConfig.networkId = FRAMEWORK_NETWORK_ID;
-        mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkRemoved(removedConfig);
+        }
 
         reset(mWifiConfigManager);
 
@@ -5877,7 +5883,10 @@
 
         WifiConfiguration removedNetwork = new WifiConfiguration();
         removedNetwork.networkId = FRAMEWORK_NETWORK_ID;
-        mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedNetwork);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkRemoved(removedNetwork);
+        }
         mLooper.dispatchAll();
 
         verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID);
@@ -5894,8 +5903,11 @@
 
         WifiConfiguration disabledNetwork = new WifiConfiguration();
         disabledNetwork.networkId = FRAMEWORK_NETWORK_ID;
-        mConfigUpdateListenerCaptor.getValue().onNetworkPermanentlyDisabled(disabledNetwork,
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkPermanentlyDisabled(disabledNetwork,
                 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD);
+        }
         mLooper.dispatchAll();
 
         verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
@@ -5947,8 +5959,11 @@
 
         WifiConfiguration disabledNetwork = new WifiConfiguration();
         disabledNetwork.networkId = FRAMEWORK_NETWORK_ID;
-        mConfigUpdateListenerCaptor.getValue().onNetworkPermanentlyDisabled(disabledNetwork,
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkPermanentlyDisabled(disabledNetwork,
                 WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT);
+        }
         mLooper.dispatchAll();
 
         assertEquals("L3ConnectedState", getCurrentState().getName());
@@ -5964,8 +5979,11 @@
 
         WifiConfiguration disabledNetwork = new WifiConfiguration();
         disabledNetwork.networkId = FRAMEWORK_NETWORK_ID;
-        mConfigUpdateListenerCaptor.getValue().onNetworkTemporarilyDisabled(disabledNetwork,
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkTemporarilyDisabled(disabledNetwork,
                 WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY);
+        }
         mLooper.dispatchAll();
 
         assertEquals("L3ConnectedState", getCurrentState().getName());
@@ -6397,7 +6415,10 @@
         WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork);
         mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED;
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
         verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT),
@@ -6419,7 +6440,10 @@
         WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork);
         mConnectedNetwork.meteredOverride = METERED_OVERRIDE_NOT_METERED;
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         assertEquals("L3ConnectedState", getCurrentState().getName());
 
@@ -6449,7 +6473,10 @@
         WifiInfo wifiInfo = mWifiInfo;
         wifiInfo.setMeteredHint(true);
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
     }
@@ -6474,7 +6501,10 @@
         WifiInfo wifiInfo = mWifiInfo;
         wifiInfo.setMeteredHint(false);
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         assertEquals("L3ConnectedState", getCurrentState().getName());
 
@@ -6503,7 +6533,10 @@
         WifiInfo wifiInfo = mWifiInfo;
         wifiInfo.setMeteredHint(true);
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         assertEquals("L3ConnectedState", getCurrentState().getName());
 
@@ -6530,7 +6563,10 @@
         WifiInfo wifiInfo = mWifiInfo;
         wifiInfo.setMeteredHint(false);
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         assertEquals("L3ConnectedState", getCurrentState().getName());
 
@@ -6628,7 +6664,10 @@
         WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork);
         mConnectedNetwork.meteredOverride = METERED_OVERRIDE_METERED;
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         verify(mWifiNative).removeNetworkCachedData(eq(oldConfig.networkId));
     }
@@ -8043,7 +8082,10 @@
         when(mWifiNative.getCurrentNetworkSecurityParams(any())).thenReturn(
                 SecurityParams.createSecurityParamsBySecurityType(
                         WifiConfiguration.SECURITY_TYPE_PSK));
-        mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removeConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkRemoved(removeConfig);
+        }
         mLooper.dispatchAll();
 
         if (!isSecondary) {
@@ -8389,7 +8431,10 @@
         WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork);
         mConnectedNetwork.trusted = false;
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
         verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT),
@@ -8412,7 +8457,10 @@
         WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork);
         mConnectedNetwork.trusted = true;
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         assertEquals("L3ConnectedState", getCurrentState().getName());
 
@@ -8436,7 +8484,10 @@
         WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork);
         mConnectedNetwork.trusted = false;
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME);
         verify(mWifiMetrics, never()).logStaEvent(anyString(), anyInt(), anyInt());
@@ -8459,7 +8510,10 @@
         WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork);
         mConnectedNetwork.trusted = true;
 
-        mConfigUpdateListenerCaptor.getValue().onNetworkUpdated(mConnectedNetwork, oldConfig);
+        for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+                .getAllValues()) {
+            listener.onNetworkUpdated(mConnectedNetwork, oldConfig);
+        }
         mLooper.dispatchAll();
         assertEquals("L3ConnectedState", getCurrentState().getName());
         verifyNoMoreInteractions(mWifiNetworkAgent);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java b/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java
index 2117e1c..4739093 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java
@@ -80,6 +80,7 @@
     private static final int ACTION_ACCEPT = 0;
     private static final int ACTION_REJECT = 1;
     private static final int ACTION_TAP = 2;
+    private static final int ACTION_FORGET = 3;
     private static final String WIFI_IFACE_NAME = "wlan-test-9";
     private static final int FRAMEWORK_NETWORK_ID = 2;
     private static final String TEST_SSID = "\"test_ssid\"";
@@ -99,6 +100,8 @@
     @Mock private WifiDialogManager.DialogHandle mTofuAlertDialog;
 
     @Captor ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
+    @Captor ArgumentCaptor<WifiConfigManager.OnNetworkUpdateListener>
+        mOnNetworkUpdateListenerCaptor;
 
     TestLooper mLooper;
     Handler mHandler;
@@ -464,6 +467,9 @@
                     eq(null),
                     eq(mHandler));
         }
+
+        verify(mWifiConfigManager).addOnNetworkUpdateListener(
+                mOnNetworkUpdateListenerCaptor.capture());
     }
 
     /**
@@ -512,6 +518,28 @@
     }
 
     /**
+     * Verify Trust On First Use flow with a self-signed CA cert.
+     * - This network is selected by a user.
+     * - Forget the connection.
+     */
+    @Test
+    public void verifyTrustOnFirstUseForgetWhenConnectByUserWithSelfSignedCaCert()
+            throws Exception {
+        assumeTrue(SdkLevel.isAtLeastT());
+        boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true;
+        boolean needUserApproval = true;
+
+        WifiConfiguration config = prepareWifiConfiguration(isAtLeastT);
+        setupTest(config, isAtLeastT, isTrustOnFirstUseSupported);
+
+        X509Certificate mockSelfSignedCert = generateMockCert("self", "self", false);
+        mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, mockSelfSignedCert);
+
+        verifyTrustOnFirstUseFlow(config, ACTION_FORGET, isTrustOnFirstUseSupported,
+                isUserSelected, needUserApproval, mockSelfSignedCert, mockSelfSignedCert);
+    }
+
+    /**
      * Verify that the connection should be terminated.
      * - TOFU is supported.
      * - Insecure EAP network is not allowed.
@@ -748,6 +776,8 @@
                 dialogCallbackCaptor.getValue().onPositiveButtonClicked();
             } else if (action == ACTION_REJECT) {
                 dialogCallbackCaptor.getValue().onNegativeButtonClicked();
+            } else if (action == ACTION_FORGET) {
+                mOnNetworkUpdateListenerCaptor.getValue().onNetworkRemoved(config);
             }
         } else {
             verify(mFrameworkFacade, never()).makeAlertDialogBuilder(any());
@@ -809,6 +839,8 @@
             verify(mWifiDialogManager).createLegacySimpleDialogWithUrl(
                     any(), any(), any(), anyInt(), anyInt(), any(), any(), any(), any(), any());
             verify(mTofuAlertDialog).launchDialog();
+        } else if (action == ACTION_FORGET) {
+            verify(mTofuAlertDialog).dismissDialog();
         }
         verify(mCallbacks, never()).onError(any());
     }
@@ -852,5 +884,7 @@
         BroadcastReceiver br = mBroadcastReceiverCaptor.getValue();
         mInsecureEapNetworkHandler.cleanup();
         verify(mContext).unregisterReceiver(br);
+        verify(mWifiConfigManager).removeOnNetworkUpdateListener(
+                mOnNetworkUpdateListenerCaptor.capture());
     }
 }