Handle multiple cancel calls from HAL client

Bug: 391083773
Test: Manual steps as listed in b/391083773
Change-Id: Ia954eb02563fc88ca6daa0bcf7ec4b05796fc93f
diff --git a/biometrics/common/util/CancellationSignal.cpp b/biometrics/common/util/CancellationSignal.cpp
index 7888838..2bfc39e 100644
--- a/biometrics/common/util/CancellationSignal.cpp
+++ b/biometrics/common/util/CancellationSignal.cpp
@@ -22,10 +22,13 @@
 namespace aidl::android::hardware::biometrics {
 
 CancellationSignal::CancellationSignal(std::promise<void>&& cancellationPromise)
-    : mCancellationPromise(std::move(cancellationPromise)) {}
+    : mCancellationPromise(std::move(cancellationPromise)), isSet(false) {}
 
 ndk::ScopedAStatus CancellationSignal::cancel() {
-    mCancellationPromise.set_value();
+    if (!isSet) {
+        mCancellationPromise.set_value();
+        isSet = true;
+    }
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/biometrics/common/util/include/util/CancellationSignal.h b/biometrics/common/util/include/util/CancellationSignal.h
index be77e29..d5a9a1d 100644
--- a/biometrics/common/util/include/util/CancellationSignal.h
+++ b/biometrics/common/util/include/util/CancellationSignal.h
@@ -30,6 +30,7 @@
 
   private:
     std::promise<void> mCancellationPromise;
+    bool isSet;
 };
 
 // Returns whether the given cancellation future is ready, i.e. whether the operation corresponding