Handle identical timestamps for health events

Bug: 239845631
Test: Built and ran emulator. Additional unit test.
Change-Id: I9f49d97de7dc391e306dcb34cabae9ac5caf8c9f
diff --git a/base/HealthMonitor.cpp b/base/HealthMonitor.cpp
index 0dd56d7..cc2fc06 100644
--- a/base/HealthMonitor.cpp
+++ b/base/HealthMonitor.cpp
@@ -185,10 +185,10 @@
                        *event);

         }

 

-        // Sort by what times out first

-        std::map<Timestamp, uint64_t> sortedTasks;

+        // Sort by what times out first. Identical timestamps are possible

+        std::multimap<Timestamp, uint64_t> sortedTasks;

         for (auto& [_, task] : mMonitoredTasks) {

-            sortedTasks[task.timeoutTimestamp] = task.id;

+            sortedTasks.insert(std::pair<Timestamp, uint64_t>(task.timeoutTimestamp, task.id));

         }

 

         for (auto& [_, task_id] : sortedTasks) {

diff --git a/base/HealthMonitor_unittest.cpp b/base/HealthMonitor_unittest.cpp
index b2ea4f0..76b474e 100644
--- a/base/HealthMonitor_unittest.cpp
+++ b/base/HealthMonitor_unittest.cpp
@@ -288,4 +288,32 @@
     healthMonitor.stopMonitoringTask(id2);

 }

 

+TEST_F(HealthMonitorTest, simultaneousTasks) {

+    int expectedHangDurationS = 5;

+    {

+        InSequence s;

+        EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(

+                                Field(&MetricEventHang::otherHungTasks, 0))))

+            .Times(1);

+        EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(

+                                Field(&MetricEventHang::otherHungTasks, 1))))

+            .Times(1);

+        EXPECT_CALL(logger,

+                    logMetricEvent(VariantWith<MetricEventUnHang>(Field(

+                        &MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS - 1)),

+                                                           Le(SToMs(expectedHangDurationS + 1)))))))

+            .Times(1);

+        EXPECT_CALL(logger,

+                    logMetricEvent(VariantWith<MetricEventUnHang>(Field(

+                        &MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS - 1)),

+                                                           Le(SToMs(expectedHangDurationS + 1)))))))

+            .Times(1);

+    }

+    auto id1 = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());

+    auto id2 = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());

+    step(defaultHangThresholdS + expectedHangDurationS);

+    healthMonitor.stopMonitoringTask(id1);

+    healthMonitor.stopMonitoringTask(id2);

+}

+

 }  // namespace emugl
\ No newline at end of file