Clear out callback when canceling an alarm

VSyncDispatchTimerQueue tries to cancel its timer callback when
destroying itself, but Timekeeper might still run the callback if
disarming its timer happened immediately after polling but before
invoking the callback. To avoid this race condition, delete the callback
while holding Timekeeper's mutex.

Bug: 304675978
Test: builds
Change-Id: Ifa7a4fcb65481b6a5ddfcfeb6bc7a53cb37ec168
diff --git a/services/surfaceflinger/Scheduler/src/Timer.cpp b/services/surfaceflinger/Scheduler/src/Timer.cpp
index a4cf57f..09e8a1e 100644
--- a/services/surfaceflinger/Scheduler/src/Timer.cpp
+++ b/services/surfaceflinger/Scheduler/src/Timer.cpp
@@ -93,8 +93,8 @@
         close(mPipes[kWritePipe]);
         mPipes[kWritePipe] = -1;
     }
-    mExpectingCallback = false;
-    mCallback = {};
+
+    setCallback({});
 }
 
 void Timer::endDispatch() {
@@ -112,8 +112,7 @@
     static constexpr int ns_per_s =
             std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
 
-    mCallback = std::move(callback);
-    mExpectingCallback = true;
+    setCallback(std::move(callback));
 
     struct itimerspec old_timer;
     struct itimerspec new_timer {
@@ -142,6 +141,8 @@
     if (timerfd_settime(mTimerFd, 0, &new_timer, &old_timer)) {
         ALOGW("Failed to disarm timerfd");
     }
+
+    setCallback({});
 }
 
 void Timer::threadMain() {
@@ -231,6 +232,11 @@
     mDebugState = state;
 }
 
+void Timer::setCallback(std::function<void()>&& callback) {
+    mExpectingCallback = bool(callback);
+    mCallback = std::move(callback);
+}
+
 void Timer::dump(std::string& result) const {
     std::lock_guard lock(mMutex);
     result.append("\t\tDebugState: ");