Fix disabling the scan monitoring am: c6549e2b7f

Original change: https://googleplex-android-review.googlesource.com/c/platform/system/chre/+/18408951

Change-Id: I98c1e72046e4b3505a045373598b6030f049c878
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/core/wifi_request_manager.cc b/core/wifi_request_manager.cc
index 17ffade..5939618 100644
--- a/core/wifi_request_manager.cc
+++ b/core/wifi_request_manager.cc
@@ -665,12 +665,21 @@
   Nanoapp *nanoapp =
       EventLoopManagerSingleton::get()->getEventLoop().findNanoappByInstanceId(
           instanceId);
+  size_t nanoappIndex;
+  bool hasExistingRequest =
+      nanoappHasScanMonitorRequest(instanceId, &nanoappIndex);
+
   if (nanoapp == nullptr) {
-    LOGW("Failed to update scan monitoring list for non-existent nanoapp");
+    // When the scan monitoring is disabled from inside nanoappEnd() or when
+    // CHRE cleanup the subscription automatically it is possible that the
+    // current method is called after the nanoapp is unloaded. In such a case
+    // we still want to remove the nanoapp from mScanMonitorNanoapps.
+    if (!enable && hasExistingRequest) {
+      mScanMonitorNanoapps.erase(nanoappIndex);
+    } else {
+      LOGW("Failed to update scan monitoring list for non-existent nanoapp");
+    }
   } else {
-    size_t nanoappIndex;
-    bool hasExistingRequest =
-        nanoappHasScanMonitorRequest(instanceId, &nanoappIndex);
     if (enable) {
       if (!hasExistingRequest) {
         // The scan monitor was successfully enabled for this nanoapp and
diff --git a/test/simulation/wifi_test.cc b/test/simulation/wifi_test.cc
index a8f0344..6ce594f 100644
--- a/test/simulation/wifi_test.cc
+++ b/test/simulation/wifi_test.cc
@@ -96,7 +96,7 @@
   EXPECT_FALSE(chrePalWifiIsScanMonitoringActive());
 }
 
-TEST_F(TestBase, WifiSubscribeAreDisabledOnUnload) {
+TEST_F(TestBase, WifiScanMonitoringDisabledOnUnload) {
   CREATE_CHRE_TEST_EVENT(MONITORING_REQUEST, 1);
 
   struct MonitoringRequest {
@@ -156,5 +156,76 @@
   EXPECT_FALSE(chrePalWifiIsScanMonitoringActive());
 }
 
+TEST_F(TestBase, WifiScanMonitoringDisabledOnUnloadAndCanBeReEnabled) {
+  CREATE_CHRE_TEST_EVENT(MONITORING_REQUEST, 1);
+
+  struct MonitoringRequest {
+    bool enable;
+    uint32_t cookie;
+  };
+
+  struct App : public TestNanoapp {
+    uint32_t perms = NanoappPermissions::CHRE_PERMS_WIFI;
+
+    void (*handleEvent)(uint32_t, uint16_t, const void *) =
+        [](uint32_t, uint16_t eventType, const void *eventData) {
+          static uint32_t cookie;
+
+          switch (eventType) {
+            case CHRE_EVENT_WIFI_ASYNC_RESULT: {
+              auto *event = static_cast<const chreAsyncResult *>(eventData);
+              if (event->success) {
+                TestEventQueueSingleton::get()->pushEvent(
+                    CHRE_EVENT_WIFI_ASYNC_RESULT,
+                    *(static_cast<const uint32_t *>(event->cookie)));
+              }
+              break;
+            }
+
+            case CHRE_EVENT_TEST_EVENT: {
+              auto event = static_cast<const TestEvent *>(eventData);
+              switch (event->type) {
+                case MONITORING_REQUEST:
+                  auto request =
+                      static_cast<const MonitoringRequest *>(event->data);
+                  cookie = request->cookie;
+                  bool success = chreWifiConfigureScanMonitorAsync(
+                      request->enable, &cookie);
+                  TestEventQueueSingleton::get()->pushEvent(MONITORING_REQUEST,
+                                                            success);
+              }
+            }
+          }
+        };
+  };
+
+  auto app = loadNanoapp<App>();
+  EXPECT_FALSE(chrePalWifiIsScanMonitoringActive());
+
+  MonitoringRequest request{.enable = true, .cookie = 0x123};
+  sendEventToNanoapp(app, MONITORING_REQUEST, request);
+  bool success;
+  waitForEvent(MONITORING_REQUEST, &success);
+  EXPECT_TRUE(success);
+  uint32_t cookie;
+  waitForEvent(CHRE_EVENT_WIFI_ASYNC_RESULT, &cookie);
+  EXPECT_EQ(cookie, request.cookie);
+  EXPECT_TRUE(chrePalWifiIsScanMonitoringActive());
+
+  unloadNanoapp(app);
+  EXPECT_FALSE(chrePalWifiIsScanMonitoringActive());
+
+  app = loadNanoapp<App>();
+  EXPECT_FALSE(chrePalWifiIsScanMonitoringActive());
+
+  request = {.enable = true, .cookie = 0x456};
+  sendEventToNanoapp(app, MONITORING_REQUEST, request);
+  waitForEvent(MONITORING_REQUEST, &success);
+  EXPECT_TRUE(success);
+  waitForEvent(CHRE_EVENT_WIFI_ASYNC_RESULT, &cookie);
+  EXPECT_EQ(cookie, request.cookie);
+  EXPECT_TRUE(chrePalWifiIsScanMonitoringActive());
+}
+
 }  // namespace
 }  // namespace chre
\ No newline at end of file