Switch to callback animation

Modified current animation logic to use callbacks from the controllers
to further clean and modularize code.
Test: Pixel 3XL device, atest PointerController_test, compile

Change-Id: I1073bd78687cca491663c0349751dab4b30aa8e2
diff --git a/libs/input/MouseCursorController.cpp b/libs/input/MouseCursorController.cpp
index 80b555b..45da008 100644
--- a/libs/input/MouseCursorController.cpp
+++ b/libs/input/MouseCursorController.cpp
@@ -168,7 +168,7 @@
         updatePointerLocked();
     } else {
         mLocked.pointerFadeDirection = -1;
-        mContext.startAnimation();
+        startAnimationLocked();
     }
 }
 
@@ -185,7 +185,7 @@
         updatePointerLocked();
     } else {
         mLocked.pointerFadeDirection = 1;
-        mContext.startAnimation();
+        startAnimationLocked();
     }
 }
 
@@ -312,10 +312,9 @@
     updatePointerLocked();
 }
 
-bool MouseCursorController::doFadingAnimation(nsecs_t timestamp, bool keepAnimating) {
+bool MouseCursorController::doFadingAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) {
     nsecs_t frameDelay = timestamp - mContext.getAnimationTime();
-
-    std::scoped_lock lock(mLock);
+    bool keepAnimating = false;
 
     // Animate pointer fade.
     if (mLocked.pointerFadeDirection < 0) {
@@ -337,13 +336,10 @@
         }
         updatePointerLocked();
     }
-
     return keepAnimating;
 }
 
-bool MouseCursorController::doBitmapAnimation(nsecs_t timestamp) {
-    std::scoped_lock lock(mLock);
-
+bool MouseCursorController::doBitmapAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) {
     std::map<int32_t, PointerAnimation>::const_iterator iter =
             mLocked.animationResources.find(mLocked.requestedPointerType);
     if (iter == mLocked.animationResources.end()) {
@@ -364,7 +360,6 @@
 
         spriteController->closeTransaction();
     }
-
     // Keep animating.
     return true;
 }
@@ -399,7 +394,7 @@
                 if (anim_iter != mLocked.animationResources.end()) {
                     mLocked.animationFrameIndex = 0;
                     mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
-                    mContext.startAnimation();
+                    startAnimationLocked();
                 }
                 mLocked.pointerSprite->setIcon(iter->second);
             } else {
@@ -457,4 +452,38 @@
     return mLocked.resourcesLoaded;
 }
 
+bool MouseCursorController::doAnimations(nsecs_t timestamp) {
+    std::scoped_lock lock(mLock);
+    bool keepFading = doFadingAnimationLocked(timestamp);
+    bool keepBitmap = doBitmapAnimationLocked(timestamp);
+    bool keepAnimating = keepFading || keepBitmap;
+    if (!keepAnimating) {
+        /*
+         * We know that this callback will be removed before another
+         * is added. mLock in PointerAnimator will not be released
+         * until after this is removed, and adding another callback
+         * requires that lock. Thus it's safe to set mLocked.animating
+         * here.
+         */
+        mLocked.animating = false;
+    }
+    return keepAnimating;
+}
+
+void MouseCursorController::startAnimationLocked() REQUIRES(mLock) {
+    using namespace std::placeholders;
+
+    if (mLocked.animating) {
+        return;
+    }
+    mLocked.animating = true;
+
+    std::function<bool(nsecs_t)> func = std::bind(&MouseCursorController::doAnimations, this, _1);
+    /*
+     * Using -1 for displayId here to avoid removing the callback
+     * if a TouchSpotController with the same display is removed.
+     */
+    mContext.addAnimationCallback(-1, func);
+}
+
 } // namespace android