Fix flaky WorkerThreadTest

Bug: 183250492
Test: atest --host android.hardware.biometrics.fingerprint.WorkerThreadTest
Change-Id: Ic51681103989d13d5c968d9b7ce1ebf9a306edee
diff --git a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
index 0d5014bb..c548fe5 100644
--- a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
@@ -32,23 +32,41 @@
 TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) {
     WorkerThread worker(1 /*maxQueueSize*/);
     for (int i = 0; i < 100; ++i) {
-        EXPECT_TRUE(worker.schedule(Callable::from([] {})));
-        // Allow enough time for the previous task to be processed.
-        std::this_thread::sleep_for(2ms);
+        std::promise<void> promise;
+        auto future = promise.get_future();
+
+        ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
+            // Notify that the task has started.
+            promise.set_value();
+        })));
+
+        auto status = future.wait_for(1s);
+        EXPECT_EQ(status, std::future_status::ready);
     }
 }
 
 TEST(WorkerThreadTest, ScheduleReturnsFalseWhenQueueIsFull) {
     WorkerThread worker(2 /*maxQueueSize*/);
-    // Add a long-running task.
-    worker.schedule(Callable::from([] { std::this_thread::sleep_for(1s); }));
 
-    // Allow enough time for the worker to start working on the previous task.
-    std::this_thread::sleep_for(2ms);
+    std::promise<void> promise;
+    auto future = promise.get_future();
 
+    // Schedule a long-running task.
+    ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
+        // Notify that the task has started.
+        promise.set_value();
+        // Block for a "very long" time.
+        std::this_thread::sleep_for(2s);
+    })));
+
+    // Make sure the long-running task began executing.
+    auto status = future.wait_for(1s);
+    ASSERT_EQ(status, std::future_status::ready);
+
+    // The first task is already being worked on, which means the queue must be empty.
     // Fill the worker's queue to the maximum.
-    worker.schedule(Callable::from([] {}));
-    worker.schedule(Callable::from([] {}));
+    ASSERT_TRUE(worker.schedule(Callable::from([] {})));
+    ASSERT_TRUE(worker.schedule(Callable::from([] {})));
 
     EXPECT_FALSE(worker.schedule(Callable::from([] {})));
 }
@@ -71,7 +89,8 @@
     auto future = promise.get_future();
 
     // Schedule a special task to signal when all of the tasks are finished.
-    worker.schedule(Callable::from([&promise] { promise.set_value(); }));
+    worker.schedule(
+            Callable::from([promise = std::move(promise)]() mutable { promise.set_value(); }));
     auto status = future.wait_for(1s);
     ASSERT_EQ(status, std::future_status::ready);
 
@@ -84,23 +103,37 @@
     std::promise<void> promise2;
     auto future1 = promise1.get_future();
     auto future2 = promise2.get_future();
+    std::atomic<bool> value;
 
+    // Local scope for the worker to test its destructor when it goes out of scope.
     {
         WorkerThread worker(2 /*maxQueueSize*/);
-        worker.schedule(Callable::from([&promise1] {
-            promise1.set_value();
-            std::this_thread::sleep_for(200ms);
-        }));
-        worker.schedule(Callable::from([&promise2] { promise2.set_value(); }));
 
-        // Make sure the first task is executing.
-        auto status1 = future1.wait_for(1s);
-        ASSERT_EQ(status1, std::future_status::ready);
+        ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise1)]() mutable {
+            promise.set_value();
+            std::this_thread::sleep_for(200ms);
+        })));
+
+        // The first task should start executing.
+        auto status = future1.wait_for(1s);
+        ASSERT_EQ(status, std::future_status::ready);
+
+        // The second task should schedule successfully.
+        ASSERT_TRUE(
+                worker.schedule(Callable::from([promise = std::move(promise2), &value]() mutable {
+                    // The worker should destruct before it gets a chance to execute this.
+                    value = true;
+                    promise.set_value();
+                })));
     }
 
     // The second task should never execute.
-    auto status2 = future2.wait_for(1s);
-    EXPECT_EQ(status2, std::future_status::timeout);
+    auto status = future2.wait_for(1s);
+    ASSERT_EQ(status, std::future_status::ready);
+    // The future is expected to be ready but contain an exception.
+    // Cannot use ASSERT_THROW because exceptions are disabled in this codebase.
+    // ASSERT_THROW(future2.get(), std::future_error);
+    EXPECT_FALSE(value);
 }
 
 }  // namespace