Make VSyncCallbackRegistration's move operator= call unregisterCallback

Skipping unregisterCallback means that we might delete a callback while
it is being called. Note that EventThread uses the move operator=, and
this behaves differently than if it were stored in a unique_ptr like in
MessageQueue. Update move operator= so that they do behave the same, and
add tests verifying this, along with a couple other behavior tests.

Note that this may result in deadlocks similar to those in b/276367387.
That is fixed by If490f88115aa298d31aa9ad392a1f9f9dc987549.

Cleanups:
- Remove comment for VsyncCallbackRegistration regarding the lifetime
requirement for the VSyncDispatch.
Icdb80253436b4d0034fc20fcae8583efb7c30292 switched the VSyncDispatch
to an std::shared_ptr from a reference, so the client no longer needs
to ensure that the VSyncDispatch outlives the VsyncCallbackRegistration.
- Replace mValidToken with using an std::optional for the token.

Bug: 279209321
Test: VSyncCallbackRegistrationTest
Change-Id: I3c1eccb36914f29560600d48bb08b1b8f2fe7c96
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index 26389eb..d431fbf 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
@@ -438,47 +438,44 @@
                                                      VSyncDispatch::Callback callback,
                                                      std::string callbackName)
       : mDispatch(std::move(dispatch)),
-        mToken(mDispatch->registerCallback(std::move(callback), std::move(callbackName))),
-        mValidToken(true) {}
+        mToken(mDispatch->registerCallback(std::move(callback), std::move(callbackName))) {}
 
 VSyncCallbackRegistration::VSyncCallbackRegistration(VSyncCallbackRegistration&& other)
-      : mDispatch(std::move(other.mDispatch)),
-        mToken(std::move(other.mToken)),
-        mValidToken(std::move(other.mValidToken)) {
-    other.mValidToken = false;
-}
+      : mDispatch(std::move(other.mDispatch)), mToken(std::exchange(other.mToken, std::nullopt)) {}
 
 VSyncCallbackRegistration& VSyncCallbackRegistration::operator=(VSyncCallbackRegistration&& other) {
+    if (this == &other) return *this;
+    if (mToken) {
+        mDispatch->unregisterCallback(*mToken);
+    }
     mDispatch = std::move(other.mDispatch);
-    mToken = std::move(other.mToken);
-    mValidToken = std::move(other.mValidToken);
-    other.mValidToken = false;
+    mToken = std::exchange(other.mToken, std::nullopt);
     return *this;
 }
 
 VSyncCallbackRegistration::~VSyncCallbackRegistration() {
-    if (mValidToken) mDispatch->unregisterCallback(mToken);
+    if (mToken) mDispatch->unregisterCallback(*mToken);
 }
 
 ScheduleResult VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming) {
-    if (!mValidToken) {
+    if (!mToken) {
         return std::nullopt;
     }
-    return mDispatch->schedule(mToken, scheduleTiming);
+    return mDispatch->schedule(*mToken, scheduleTiming);
 }
 
 ScheduleResult VSyncCallbackRegistration::update(VSyncDispatch::ScheduleTiming scheduleTiming) {
-    if (!mValidToken) {
+    if (!mToken) {
         return std::nullopt;
     }
-    return mDispatch->update(mToken, scheduleTiming);
+    return mDispatch->update(*mToken, scheduleTiming);
 }
 
 CancelResult VSyncCallbackRegistration::cancel() {
-    if (!mValidToken) {
+    if (!mToken) {
         return CancelResult::Error;
     }
-    return mDispatch->cancel(mToken);
+    return mDispatch->cancel(*mToken);
 }
 
 } // namespace android::scheduler