Move PointerController from sp to shared_ptr

Bug: 160010896
Test: atest PointerController_test, manual usage
Change-Id: I4e665d00c56b44c9c1a4ea8cb27ffd10ade3315b
Merged-In: I4e665d00c56b44c9c1a4ea8cb27ffd10ade3315b
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 5c2ef15..f749894 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -24,37 +24,10 @@
 
 #include <log/log.h>
 
-#include <SkBitmap.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkPaint.h>
-#include <SkBlendMode.h>
+#include <memory>
 
 namespace android {
 
-// --- WeakLooperCallback ---
-
-class WeakLooperCallback: public LooperCallback {
-protected:
-    virtual ~WeakLooperCallback() { }
-
-public:
-    explicit WeakLooperCallback(const wp<LooperCallback>& callback) :
-        mCallback(callback) {
-    }
-
-    virtual int handleEvent(int fd, int events, void* data) {
-        sp<LooperCallback> callback = mCallback.promote();
-        if (callback != NULL) {
-            return callback->handleEvent(fd, events, data);
-        }
-        return 0; // the client is gone, remove the callback
-    }
-
-private:
-    wp<LooperCallback> mCallback;
-};
-
 // --- PointerController ---
 
 // Time to wait before starting the fade when the pointer is inactive.
@@ -70,21 +43,42 @@
 // The number of events to be read at once for DisplayEventReceiver.
 static const int EVENT_BUFFER_SIZE = 100;
 
-// --- PointerController ---
+std::shared_ptr<PointerController> PointerController::create(
+        const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
+        const sp<SpriteController>& spriteController) {
+    std::shared_ptr<PointerController> controller = std::shared_ptr<PointerController>(
+            new PointerController(policy, looper, spriteController));
 
-PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy,
-        const sp<Looper>& looper, const sp<SpriteController>& spriteController) :
-        mPolicy(policy), mLooper(looper), mSpriteController(spriteController) {
-    mHandler = new WeakMessageHandler(this);
-    mCallback = new WeakLooperCallback(this);
+    /*
+     * Now we need to hook up the constructed PointerController object to its callbacks.
+     *
+     * This must be executed after the constructor but before any other methods on PointerController
+     * in order to ensure that the fully constructed object is visible on the Looper thread, since
+     * that may be a different thread than where the PointerController is initially constructed.
+     *
+     * Unfortunately, this cannot be done as part of the constructor since we need to hand out
+     * weak_ptr's which themselves cannot be constructed until there's at least one shared_ptr.
+     */
 
-    if (mDisplayEventReceiver.initCheck() == NO_ERROR) {
-        mLooper->addFd(mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK,
-                       Looper::EVENT_INPUT, mCallback, nullptr);
+    controller->mHandler->pointerController = controller;
+    controller->mCallback->pointerController = controller;
+    if (controller->mDisplayEventReceiver.initCheck() == NO_ERROR) {
+        controller->mLooper->addFd(controller->mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK,
+                                   Looper::EVENT_INPUT, controller->mCallback, nullptr);
     } else {
         ALOGE("Failed to initialize DisplayEventReceiver.");
     }
+    return controller;
+}
 
+PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy,
+                                     const sp<Looper>& looper,
+                                     const sp<SpriteController>& spriteController)
+      : mPolicy(policy),
+        mLooper(looper),
+        mSpriteController(spriteController),
+        mHandler(new MessageHandler()),
+        mCallback(new LooperCallback()) {
     AutoMutex _l(mLock);
 
     mLocked.animationPending = false;
@@ -486,24 +480,35 @@
     updatePointerLocked();
 }
 
-void PointerController::handleMessage(const Message& message) {
+void PointerController::MessageHandler::handleMessage(const Message& message) {
+    std::shared_ptr<PointerController> controller = pointerController.lock();
+
+    if (controller == nullptr) {
+        ALOGE("PointerController instance was released before processing message: what=%d",
+              message.what);
+        return;
+    }
     switch (message.what) {
     case MSG_INACTIVITY_TIMEOUT:
-        doInactivityTimeout();
+        controller->doInactivityTimeout();
         break;
     }
 }
 
-int PointerController::handleEvent(int /* fd */, int events, void* /* data */) {
+int PointerController::LooperCallback::handleEvent(int /* fd */, int events, void* /* data */) {
+    std::shared_ptr<PointerController> controller = pointerController.lock();
+    if (controller == nullptr) {
+        ALOGW("PointerController instance was released with pending callbacks.  events=0x%x",
+              events);
+        return 0; // Remove the callback, the PointerController is gone anyways
+    }
     if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
-        ALOGE("Display event receiver pipe was closed or an error occurred.  "
-              "events=0x%x", events);
+        ALOGE("Display event receiver pipe was closed or an error occurred.  events=0x%x", events);
         return 0; // remove the callback
     }
 
     if (!(events & Looper::EVENT_INPUT)) {
-        ALOGW("Received spurious callback for unhandled poll event.  "
-              "events=0x%x", events);
+        ALOGW("Received spurious callback for unhandled poll event.  events=0x%x", events);
         return 1; // keep the callback
     }
 
@@ -511,7 +516,7 @@
     ssize_t n;
     nsecs_t timestamp;
     DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
-    while ((n = mDisplayEventReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
+    while ((n = controller->mDisplayEventReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
         for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
             if (buf[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                 timestamp = buf[i].header.timestamp;
@@ -520,7 +525,7 @@
         }
     }
     if (gotVsync) {
-        doAnimate(timestamp);
+        controller->doAnimate(timestamp);
     }
     return 1;  // keep the callback
 }
@@ -737,7 +742,7 @@
             return spot;
         }
     }
-    return NULL;
+    return nullptr;
 }
 
 void PointerController::releaseSpotLocked(Spot* spot) {