diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index fd4371c..7942806 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -16,6 +16,9 @@
     name: "libinputservice",
     srcs: [
         "PointerController.cpp",
+        "PointerControllerContext.cpp",
+        "MouseCursorController.cpp",
+        "TouchSpotController.cpp",
         "SpriteController.cpp",
         "SpriteIcon.cpp",
     ],
diff --git a/libs/input/MouseCursorController.cpp b/libs/input/MouseCursorController.cpp
new file mode 100644
index 0000000..80b555b
--- /dev/null
+++ b/libs/input/MouseCursorController.cpp
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "MouseCursorController"
+//#define LOG_NDEBUG 0
+
+// Log debug messages about pointer updates
+#define DEBUG_MOUSE_CURSOR_UPDATES 0
+
+#include "MouseCursorController.h"
+
+#include <log/log.h>
+
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkCanvas.h>
+#include <SkColor.h>
+#include <SkPaint.h>
+
+namespace {
+// Time to spend fading out the pointer completely.
+const nsecs_t POINTER_FADE_DURATION = 500 * 1000000LL; // 500 ms
+} // namespace
+
+namespace android {
+
+// --- MouseCursorController ---
+
+MouseCursorController::MouseCursorController(PointerControllerContext& context)
+      : mContext(context) {
+    std::scoped_lock lock(mLock);
+
+    mLocked.animationFrameIndex = 0;
+    mLocked.lastFrameUpdatedTime = 0;
+
+    mLocked.pointerFadeDirection = 0;
+    mLocked.pointerX = 0;
+    mLocked.pointerY = 0;
+    mLocked.pointerAlpha = 0.0f; // pointer is initially faded
+    mLocked.pointerSprite = mContext.getSpriteController()->createSprite();
+    mLocked.updatePointerIcon = false;
+    mLocked.requestedPointerType = mContext.getPolicy()->getDefaultPointerIconId();
+
+    mLocked.resourcesLoaded = false;
+
+    mLocked.buttonState = 0;
+}
+
+MouseCursorController::~MouseCursorController() {
+    std::scoped_lock lock(mLock);
+
+    mLocked.pointerSprite.clear();
+}
+
+bool MouseCursorController::getBounds(float* outMinX, float* outMinY, float* outMaxX,
+                                      float* outMaxY) const {
+    std::scoped_lock lock(mLock);
+
+    return getBoundsLocked(outMinX, outMinY, outMaxX, outMaxY);
+}
+
+bool MouseCursorController::getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX,
+                                            float* outMaxY) const REQUIRES(mLock) {
+    if (!mLocked.viewport.isValid()) {
+        return false;
+    }
+
+    *outMinX = mLocked.viewport.logicalLeft;
+    *outMinY = mLocked.viewport.logicalTop;
+    *outMaxX = mLocked.viewport.logicalRight - 1;
+    *outMaxY = mLocked.viewport.logicalBottom - 1;
+    return true;
+}
+
+void MouseCursorController::move(float deltaX, float deltaY) {
+#if DEBUG_MOUSE_CURSOR_UPDATES
+    ALOGD("Move pointer by deltaX=%0.3f, deltaY=%0.3f", deltaX, deltaY);
+#endif
+    if (deltaX == 0.0f && deltaY == 0.0f) {
+        return;
+    }
+
+    std::scoped_lock lock(mLock);
+
+    setPositionLocked(mLocked.pointerX + deltaX, mLocked.pointerY + deltaY);
+}
+
+void MouseCursorController::setButtonState(int32_t buttonState) {
+#if DEBUG_MOUSE_CURSOR_UPDATES
+    ALOGD("Set button state 0x%08x", buttonState);
+#endif
+    std::scoped_lock lock(mLock);
+
+    if (mLocked.buttonState != buttonState) {
+        mLocked.buttonState = buttonState;
+    }
+}
+
+int32_t MouseCursorController::getButtonState() const {
+    std::scoped_lock lock(mLock);
+    return mLocked.buttonState;
+}
+
+void MouseCursorController::setPosition(float x, float y) {
+#if DEBUG_MOUSE_CURSOR_UPDATES
+    ALOGD("Set pointer position to x=%0.3f, y=%0.3f", x, y);
+#endif
+    std::scoped_lock lock(mLock);
+    setPositionLocked(x, y);
+}
+
+void MouseCursorController::setPositionLocked(float x, float y) REQUIRES(mLock) {
+    float minX, minY, maxX, maxY;
+    if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
+        if (x <= minX) {
+            mLocked.pointerX = minX;
+        } else if (x >= maxX) {
+            mLocked.pointerX = maxX;
+        } else {
+            mLocked.pointerX = x;
+        }
+        if (y <= minY) {
+            mLocked.pointerY = minY;
+        } else if (y >= maxY) {
+            mLocked.pointerY = maxY;
+        } else {
+            mLocked.pointerY = y;
+        }
+        updatePointerLocked();
+    }
+}
+
+void MouseCursorController::getPosition(float* outX, float* outY) const {
+    std::scoped_lock lock(mLock);
+
+    *outX = mLocked.pointerX;
+    *outY = mLocked.pointerY;
+}
+
+int32_t MouseCursorController::getDisplayId() const {
+    std::scoped_lock lock(mLock);
+    return mLocked.viewport.displayId;
+}
+
+void MouseCursorController::fade(PointerControllerInterface::Transition transition) {
+    std::scoped_lock lock(mLock);
+
+    // Remove the inactivity timeout, since we are fading now.
+    mContext.removeInactivityTimeout();
+
+    // Start fading.
+    if (transition == PointerControllerInterface::Transition::IMMEDIATE) {
+        mLocked.pointerFadeDirection = 0;
+        mLocked.pointerAlpha = 0.0f;
+        updatePointerLocked();
+    } else {
+        mLocked.pointerFadeDirection = -1;
+        mContext.startAnimation();
+    }
+}
+
+void MouseCursorController::unfade(PointerControllerInterface::Transition transition) {
+    std::scoped_lock lock(mLock);
+
+    // Always reset the inactivity timer.
+    mContext.resetInactivityTimeout();
+
+    // Start unfading.
+    if (transition == PointerControllerInterface::Transition::IMMEDIATE) {
+        mLocked.pointerFadeDirection = 0;
+        mLocked.pointerAlpha = 1.0f;
+        updatePointerLocked();
+    } else {
+        mLocked.pointerFadeDirection = 1;
+        mContext.startAnimation();
+    }
+}
+
+void MouseCursorController::reloadPointerResources(bool getAdditionalMouseResources) {
+    std::scoped_lock lock(mLock);
+
+    loadResourcesLocked(getAdditionalMouseResources);
+    updatePointerLocked();
+}
+
+/**
+ * The viewport values for deviceHeight and deviceWidth have already been adjusted for rotation,
+ * so here we are getting the dimensions in the original, unrotated orientation (orientation 0).
+ */
+static void getNonRotatedSize(const DisplayViewport& viewport, int32_t& width, int32_t& height) {
+    width = viewport.deviceWidth;
+    height = viewport.deviceHeight;
+
+    if (viewport.orientation == DISPLAY_ORIENTATION_90 ||
+        viewport.orientation == DISPLAY_ORIENTATION_270) {
+        std::swap(width, height);
+    }
+}
+
+void MouseCursorController::setDisplayViewport(const DisplayViewport& viewport,
+                                               bool getAdditionalMouseResources) {
+    std::scoped_lock lock(mLock);
+
+    if (viewport == mLocked.viewport) {
+        return;
+    }
+
+    const DisplayViewport oldViewport = mLocked.viewport;
+    mLocked.viewport = viewport;
+
+    int32_t oldDisplayWidth, oldDisplayHeight;
+    getNonRotatedSize(oldViewport, oldDisplayWidth, oldDisplayHeight);
+    int32_t newDisplayWidth, newDisplayHeight;
+    getNonRotatedSize(viewport, newDisplayWidth, newDisplayHeight);
+
+    // Reset cursor position to center if size or display changed.
+    if (oldViewport.displayId != viewport.displayId || oldDisplayWidth != newDisplayWidth ||
+        oldDisplayHeight != newDisplayHeight) {
+        float minX, minY, maxX, maxY;
+        if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
+            mLocked.pointerX = (minX + maxX) * 0.5f;
+            mLocked.pointerY = (minY + maxY) * 0.5f;
+            // Reload icon resources for density may be changed.
+            loadResourcesLocked(getAdditionalMouseResources);
+        } else {
+            mLocked.pointerX = 0;
+            mLocked.pointerY = 0;
+        }
+    } else if (oldViewport.orientation != viewport.orientation) {
+        // Apply offsets to convert from the pixel top-left corner position to the pixel center.
+        // This creates an invariant frame of reference that we can easily rotate when
+        // taking into account that the pointer may be located at fractional pixel offsets.
+        float x = mLocked.pointerX + 0.5f;
+        float y = mLocked.pointerY + 0.5f;
+        float temp;
+
+        // Undo the previous rotation.
+        switch (oldViewport.orientation) {
+            case DISPLAY_ORIENTATION_90:
+                temp = x;
+                x = oldViewport.deviceHeight - y;
+                y = temp;
+                break;
+            case DISPLAY_ORIENTATION_180:
+                x = oldViewport.deviceWidth - x;
+                y = oldViewport.deviceHeight - y;
+                break;
+            case DISPLAY_ORIENTATION_270:
+                temp = x;
+                x = y;
+                y = oldViewport.deviceWidth - temp;
+                break;
+        }
+
+        // Perform the new rotation.
+        switch (viewport.orientation) {
+            case DISPLAY_ORIENTATION_90:
+                temp = x;
+                x = y;
+                y = viewport.deviceHeight - temp;
+                break;
+            case DISPLAY_ORIENTATION_180:
+                x = viewport.deviceWidth - x;
+                y = viewport.deviceHeight - y;
+                break;
+            case DISPLAY_ORIENTATION_270:
+                temp = x;
+                x = viewport.deviceWidth - y;
+                y = temp;
+                break;
+        }
+
+        // Apply offsets to convert from the pixel center to the pixel top-left corner position
+        // and save the results.
+        mLocked.pointerX = x - 0.5f;
+        mLocked.pointerY = y - 0.5f;
+    }
+
+    updatePointerLocked();
+}
+
+void MouseCursorController::updatePointerIcon(int32_t iconId) {
+    std::scoped_lock lock(mLock);
+
+    if (mLocked.requestedPointerType != iconId) {
+        mLocked.requestedPointerType = iconId;
+        mLocked.updatePointerIcon = true;
+        updatePointerLocked();
+    }
+}
+
+void MouseCursorController::setCustomPointerIcon(const SpriteIcon& icon) {
+    std::scoped_lock lock(mLock);
+
+    const int32_t iconId = mContext.getPolicy()->getCustomPointerIconId();
+    mLocked.additionalMouseResources[iconId] = icon;
+    mLocked.requestedPointerType = iconId;
+    mLocked.updatePointerIcon = true;
+    updatePointerLocked();
+}
+
+bool MouseCursorController::doFadingAnimation(nsecs_t timestamp, bool keepAnimating) {
+    nsecs_t frameDelay = timestamp - mContext.getAnimationTime();
+
+    std::scoped_lock lock(mLock);
+
+    // Animate pointer fade.
+    if (mLocked.pointerFadeDirection < 0) {
+        mLocked.pointerAlpha -= float(frameDelay) / POINTER_FADE_DURATION;
+        if (mLocked.pointerAlpha <= 0.0f) {
+            mLocked.pointerAlpha = 0.0f;
+            mLocked.pointerFadeDirection = 0;
+        } else {
+            keepAnimating = true;
+        }
+        updatePointerLocked();
+    } else if (mLocked.pointerFadeDirection > 0) {
+        mLocked.pointerAlpha += float(frameDelay) / POINTER_FADE_DURATION;
+        if (mLocked.pointerAlpha >= 1.0f) {
+            mLocked.pointerAlpha = 1.0f;
+            mLocked.pointerFadeDirection = 0;
+        } else {
+            keepAnimating = true;
+        }
+        updatePointerLocked();
+    }
+
+    return keepAnimating;
+}
+
+bool MouseCursorController::doBitmapAnimation(nsecs_t timestamp) {
+    std::scoped_lock lock(mLock);
+
+    std::map<int32_t, PointerAnimation>::const_iterator iter =
+            mLocked.animationResources.find(mLocked.requestedPointerType);
+    if (iter == mLocked.animationResources.end()) {
+        return false;
+    }
+
+    if (timestamp - mLocked.lastFrameUpdatedTime > iter->second.durationPerFrame) {
+        sp<SpriteController> spriteController = mContext.getSpriteController();
+        spriteController->openTransaction();
+
+        int incr = (timestamp - mLocked.lastFrameUpdatedTime) / iter->second.durationPerFrame;
+        mLocked.animationFrameIndex += incr;
+        mLocked.lastFrameUpdatedTime += iter->second.durationPerFrame * incr;
+        while (mLocked.animationFrameIndex >= iter->second.animationFrames.size()) {
+            mLocked.animationFrameIndex -= iter->second.animationFrames.size();
+        }
+        mLocked.pointerSprite->setIcon(iter->second.animationFrames[mLocked.animationFrameIndex]);
+
+        spriteController->closeTransaction();
+    }
+
+    // Keep animating.
+    return true;
+}
+
+void MouseCursorController::updatePointerLocked() REQUIRES(mLock) {
+    if (!mLocked.viewport.isValid()) {
+        return;
+    }
+    sp<SpriteController> spriteController = mContext.getSpriteController();
+    spriteController->openTransaction();
+
+    mLocked.pointerSprite->setLayer(Sprite::BASE_LAYER_POINTER);
+    mLocked.pointerSprite->setPosition(mLocked.pointerX, mLocked.pointerY);
+    mLocked.pointerSprite->setDisplayId(mLocked.viewport.displayId);
+
+    if (mLocked.pointerAlpha > 0) {
+        mLocked.pointerSprite->setAlpha(mLocked.pointerAlpha);
+        mLocked.pointerSprite->setVisible(true);
+    } else {
+        mLocked.pointerSprite->setVisible(false);
+    }
+
+    if (mLocked.updatePointerIcon) {
+        if (mLocked.requestedPointerType == mContext.getPolicy()->getDefaultPointerIconId()) {
+            mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
+        } else {
+            std::map<int32_t, SpriteIcon>::const_iterator iter =
+                    mLocked.additionalMouseResources.find(mLocked.requestedPointerType);
+            if (iter != mLocked.additionalMouseResources.end()) {
+                std::map<int32_t, PointerAnimation>::const_iterator anim_iter =
+                        mLocked.animationResources.find(mLocked.requestedPointerType);
+                if (anim_iter != mLocked.animationResources.end()) {
+                    mLocked.animationFrameIndex = 0;
+                    mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
+                    mContext.startAnimation();
+                }
+                mLocked.pointerSprite->setIcon(iter->second);
+            } else {
+                ALOGW("Can't find the resource for icon id %d", mLocked.requestedPointerType);
+                mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
+            }
+        }
+        mLocked.updatePointerIcon = false;
+    }
+
+    spriteController->closeTransaction();
+}
+
+void MouseCursorController::loadResourcesLocked(bool getAdditionalMouseResources) REQUIRES(mLock) {
+    if (!mLocked.viewport.isValid()) {
+        return;
+    }
+
+    if (!mLocked.resourcesLoaded) mLocked.resourcesLoaded = true;
+
+    sp<PointerControllerPolicyInterface> policy = mContext.getPolicy();
+    policy->loadPointerResources(&mResources, mLocked.viewport.displayId);
+    policy->loadPointerIcon(&mLocked.pointerIcon, mLocked.viewport.displayId);
+
+    mLocked.additionalMouseResources.clear();
+    mLocked.animationResources.clear();
+    if (getAdditionalMouseResources) {
+        policy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
+                                             &mLocked.animationResources,
+                                             mLocked.viewport.displayId);
+    }
+
+    mLocked.updatePointerIcon = true;
+}
+
+bool MouseCursorController::isViewportValid() {
+    std::scoped_lock lock(mLock);
+    return mLocked.viewport.isValid();
+}
+
+void MouseCursorController::getAdditionalMouseResources() {
+    std::scoped_lock lock(mLock);
+
+    if (mLocked.additionalMouseResources.empty()) {
+        mContext.getPolicy()->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
+                                                           &mLocked.animationResources,
+                                                           mLocked.viewport.displayId);
+    }
+    mLocked.updatePointerIcon = true;
+    updatePointerLocked();
+}
+
+bool MouseCursorController::resourcesLoaded() {
+    std::scoped_lock lock(mLock);
+    return mLocked.resourcesLoaded;
+}
+
+} // namespace android
diff --git a/libs/input/MouseCursorController.h b/libs/input/MouseCursorController.h
new file mode 100644
index 0000000..448165b
--- /dev/null
+++ b/libs/input/MouseCursorController.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_MOUSE_CURSOR_CONTROLLER_H
+#define _UI_MOUSE_CURSOR_CONTROLLER_H
+
+#include <gui/DisplayEventReceiver.h>
+#include <input/DisplayViewport.h>
+#include <input/Input.h>
+#include <ui/DisplayInfo.h>
+#include <utils/BitSet.h>
+#include <utils/Looper.h>
+#include <utils/RefBase.h>
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "PointerControllerContext.h"
+#include "SpriteController.h"
+
+namespace android {
+
+/*
+ * Helper class for PointerController that specifically handles
+ * mouse cursor resources and actions.
+ */
+class MouseCursorController {
+public:
+    MouseCursorController(PointerControllerContext& context);
+    ~MouseCursorController();
+
+    bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
+    void move(float deltaX, float deltaY);
+    void setButtonState(int32_t buttonState);
+    int32_t getButtonState() const;
+    void setPosition(float x, float y);
+    void getPosition(float* outX, float* outY) const;
+    int32_t getDisplayId() const;
+    void fade(PointerControllerInterface::Transition transition);
+    void unfade(PointerControllerInterface::Transition transition);
+    void setDisplayViewport(const DisplayViewport& viewport, bool getAdditionalMouseResources);
+
+    void updatePointerIcon(int32_t iconId);
+    void setCustomPointerIcon(const SpriteIcon& icon);
+    void reloadPointerResources(bool getAdditionalMouseResources);
+
+    void getAdditionalMouseResources();
+    bool isViewportValid();
+
+    bool doBitmapAnimation(nsecs_t timestamp);
+    bool doFadingAnimation(nsecs_t timestamp, bool keepAnimating);
+
+    bool resourcesLoaded();
+
+private:
+    mutable std::mutex mLock;
+
+    PointerResources mResources;
+
+    PointerControllerContext& mContext;
+
+    struct Locked {
+        DisplayViewport viewport;
+
+        size_t animationFrameIndex;
+        nsecs_t lastFrameUpdatedTime;
+
+        int32_t pointerFadeDirection;
+        float pointerX;
+        float pointerY;
+        float pointerAlpha;
+        sp<Sprite> pointerSprite;
+        SpriteIcon pointerIcon;
+        bool updatePointerIcon;
+
+        bool resourcesLoaded;
+
+        std::map<int32_t, SpriteIcon> additionalMouseResources;
+        std::map<int32_t, PointerAnimation> animationResources;
+
+        int32_t requestedPointerType;
+
+        int32_t buttonState;
+
+    } mLocked GUARDED_BY(mLock);
+
+    bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
+    void setPositionLocked(float x, float y);
+
+    void updatePointerLocked();
+
+    void loadResourcesLocked(bool getAdditionalMouseResources);
+};
+
+} // namespace android
+
+#endif // _UI_MOUSE_CURSOR_CONTROLLER_H
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 5e480a6..14c96ce 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -21,31 +21,26 @@
 #define DEBUG_POINTER_UPDATES 0
 
 #include "PointerController.h"
+#include "MouseCursorController.h"
+#include "PointerControllerContext.h"
+#include "TouchSpotController.h"
 
 #include <log/log.h>
 
-#include <memory>
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkCanvas.h>
+#include <SkColor.h>
+#include <SkPaint.h>
 
 namespace android {
 
 // --- PointerController ---
 
-// Time to wait before starting the fade when the pointer is inactive.
-static const nsecs_t INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL = 15 * 1000 * 1000000LL; // 15 seconds
-static const nsecs_t INACTIVITY_TIMEOUT_DELAY_TIME_SHORT = 3 * 1000 * 1000000LL; // 3 seconds
-
-// Time to spend fading out the spot completely.
-static const nsecs_t SPOT_FADE_DURATION = 200 * 1000000LL; // 200 ms
-
-// Time to spend fading out the pointer completely.
-static const nsecs_t POINTER_FADE_DURATION = 500 * 1000000LL; // 500 ms
-
-// The number of events to be read at once for DisplayEventReceiver.
-static const int EVENT_BUFFER_SIZE = 100;
-
 std::shared_ptr<PointerController> PointerController::create(
         const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
         const sp<SpriteController>& spriteController) {
+    // using 'new' to access non-public constructor
     std::shared_ptr<PointerController> controller = std::shared_ptr<PointerController>(
             new PointerController(policy, looper, spriteController));
 
@@ -60,758 +55,175 @@
      * weak_ptr's which themselves cannot be constructed until there's at least one shared_ptr.
      */
 
-    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.");
-    }
+    controller->mContext.setHandlerController(controller);
+    controller->mContext.setCallbackController(controller);
+    controller->mContext.initializeDisplayEventReceiver();
     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;
-
-    mLocked.presentation = Presentation::POINTER;
-    mLocked.presentationChanged = false;
-
-    mLocked.inactivityTimeout = InactivityTimeout::NORMAL;
-
-    mLocked.pointerFadeDirection = 0;
-    mLocked.pointerX = 0;
-    mLocked.pointerY = 0;
-    mLocked.pointerAlpha = 0.0f; // pointer is initially faded
-    mLocked.pointerSprite = mSpriteController->createSprite();
-    mLocked.pointerIconChanged = false;
-    mLocked.requestedPointerType = mPolicy->getDefaultPointerIconId();
-
-    mLocked.animationFrameIndex = 0;
-    mLocked.lastFrameUpdatedTime = 0;
-
-    mLocked.buttonState = 0;
+      : mContext(policy, looper, spriteController, *this), mCursorController(mContext) {
+    std::scoped_lock lock(mLock);
+    mLocked.presentation = Presentation::SPOT;
 }
 
-PointerController::~PointerController() {
-    mLooper->removeMessages(mHandler);
-
-    AutoMutex _l(mLock);
-
-    mLocked.pointerSprite.clear();
-
-    for (auto& it : mLocked.spotsByDisplay) {
-        const std::vector<Spot*>& spots = it.second;
-        size_t numSpots = spots.size();
-        for (size_t i = 0; i < numSpots; i++) {
-            delete spots[i];
-        }
-    }
-    mLocked.spotsByDisplay.clear();
-    mLocked.recycledSprites.clear();
-}
-
-bool PointerController::getBounds(float* outMinX, float* outMinY,
-        float* outMaxX, float* outMaxY) const {
-    AutoMutex _l(mLock);
-
-    return getBoundsLocked(outMinX, outMinY, outMaxX, outMaxY);
-}
-
-bool PointerController::getBoundsLocked(float* outMinX, float* outMinY,
-        float* outMaxX, float* outMaxY) const {
-
-    if (!mLocked.viewport.isValid()) {
-        return false;
-    }
-
-    *outMinX = mLocked.viewport.logicalLeft;
-    *outMinY = mLocked.viewport.logicalTop;
-    *outMaxX = mLocked.viewport.logicalRight - 1;
-    *outMaxY = mLocked.viewport.logicalBottom - 1;
-    return true;
+bool PointerController::getBounds(float* outMinX, float* outMinY, float* outMaxX,
+                                  float* outMaxY) const {
+    return mCursorController.getBounds(outMinX, outMinY, outMaxX, outMaxY);
 }
 
 void PointerController::move(float deltaX, float deltaY) {
-#if DEBUG_POINTER_UPDATES
-    ALOGD("Move pointer by deltaX=%0.3f, deltaY=%0.3f", deltaX, deltaY);
-#endif
-    if (deltaX == 0.0f && deltaY == 0.0f) {
-        return;
-    }
-
-    AutoMutex _l(mLock);
-
-    setPositionLocked(mLocked.pointerX + deltaX, mLocked.pointerY + deltaY);
+    mCursorController.move(deltaX, deltaY);
 }
 
 void PointerController::setButtonState(int32_t buttonState) {
-#if DEBUG_POINTER_UPDATES
-    ALOGD("Set button state 0x%08x", buttonState);
-#endif
-    AutoMutex _l(mLock);
-
-    if (mLocked.buttonState != buttonState) {
-        mLocked.buttonState = buttonState;
-    }
+    mCursorController.setButtonState(buttonState);
 }
 
 int32_t PointerController::getButtonState() const {
-    AutoMutex _l(mLock);
-
-    return mLocked.buttonState;
+    return mCursorController.getButtonState();
 }
 
 void PointerController::setPosition(float x, float y) {
-#if DEBUG_POINTER_UPDATES
-    ALOGD("Set pointer position to x=%0.3f, y=%0.3f", x, y);
-#endif
-    AutoMutex _l(mLock);
-
-    setPositionLocked(x, y);
-}
-
-void PointerController::setPositionLocked(float x, float y) {
-    float minX, minY, maxX, maxY;
-    if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
-        if (x <= minX) {
-            mLocked.pointerX = minX;
-        } else if (x >= maxX) {
-            mLocked.pointerX = maxX;
-        } else {
-            mLocked.pointerX = x;
-        }
-        if (y <= minY) {
-            mLocked.pointerY = minY;
-        } else if (y >= maxY) {
-            mLocked.pointerY = maxY;
-        } else {
-            mLocked.pointerY = y;
-        }
-        updatePointerLocked();
-    }
+    std::scoped_lock lock(mLock);
+    mCursorController.setPosition(x, y);
 }
 
 void PointerController::getPosition(float* outX, float* outY) const {
-    AutoMutex _l(mLock);
-
-    *outX = mLocked.pointerX;
-    *outY = mLocked.pointerY;
+    mCursorController.getPosition(outX, outY);
 }
 
 int32_t PointerController::getDisplayId() const {
-    AutoMutex _l(mLock);
-
-    return mLocked.viewport.displayId;
+    return mCursorController.getDisplayId();
 }
 
 void PointerController::fade(Transition transition) {
-    AutoMutex _l(mLock);
-
-    // Remove the inactivity timeout, since we are fading now.
-    removeInactivityTimeoutLocked();
-
-    // Start fading.
-    if (transition == Transition::IMMEDIATE) {
-        mLocked.pointerFadeDirection = 0;
-        mLocked.pointerAlpha = 0.0f;
-        updatePointerLocked();
-    } else {
-        mLocked.pointerFadeDirection = -1;
-        startAnimationLocked();
-    }
+    std::scoped_lock lock(mLock);
+    mCursorController.fade(transition);
 }
 
 void PointerController::unfade(Transition transition) {
-    AutoMutex _l(mLock);
-
-    // Always reset the inactivity timer.
-    resetInactivityTimeoutLocked();
-
-    // Start unfading.
-    if (transition == Transition::IMMEDIATE) {
-        mLocked.pointerFadeDirection = 0;
-        mLocked.pointerAlpha = 1.0f;
-        updatePointerLocked();
-    } else {
-        mLocked.pointerFadeDirection = 1;
-        startAnimationLocked();
-    }
+    std::scoped_lock lock(mLock);
+    mCursorController.unfade(transition);
 }
 
 void PointerController::setPresentation(Presentation presentation) {
-    AutoMutex _l(mLock);
+    std::scoped_lock lock(mLock);
 
     if (mLocked.presentation == presentation) {
         return;
     }
 
     mLocked.presentation = presentation;
-    mLocked.presentationChanged = true;
 
-    if (!mLocked.viewport.isValid()) {
+    if (!mCursorController.isViewportValid()) {
         return;
     }
 
     if (presentation == Presentation::POINTER) {
-        if (mLocked.additionalMouseResources.empty()) {
-            mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
-                                                  &mLocked.animationResources,
-                                                  mLocked.viewport.displayId);
-        }
-        fadeOutAndReleaseAllSpotsLocked();
-        updatePointerLocked();
+        mCursorController.getAdditionalMouseResources();
+        clearSpotsLocked();
     }
 }
 
-void PointerController::setSpots(const PointerCoords* spotCoords,
-        const uint32_t* spotIdToIndex, BitSet32 spotIdBits, int32_t displayId) {
-#if DEBUG_POINTER_UPDATES
-    ALOGD("setSpots: idBits=%08x", spotIdBits.value);
-    for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
-        uint32_t id = idBits.firstMarkedBit();
-        idBits.clearBit(id);
-        const PointerCoords& c = spotCoords[spotIdToIndex[id]];
-        ALOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f, displayId=%" PRId32 ".", id,
-                c.getAxisValue(AMOTION_EVENT_AXIS_X),
-                c.getAxisValue(AMOTION_EVENT_AXIS_Y),
-                c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
-                displayId);
+void PointerController::setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
+                                 BitSet32 spotIdBits, int32_t displayId) {
+    std::scoped_lock lock(mLock);
+    auto it = mLocked.spotControllers.find(displayId);
+    if (it == mLocked.spotControllers.end()) {
+        mLocked.spotControllers.try_emplace(displayId, displayId, mContext);
     }
-#endif
-
-    AutoMutex _l(mLock);
-    if (!mLocked.viewport.isValid()) {
-        return;
-    }
-
-    std::vector<Spot*> newSpots;
-    std::map<int32_t, std::vector<Spot*>>::const_iterator iter =
-            mLocked.spotsByDisplay.find(displayId);
-    if (iter != mLocked.spotsByDisplay.end()) {
-        newSpots = iter->second;
-    }
-
-    mSpriteController->openTransaction();
-
-    // Add or move spots for fingers that are down.
-    for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
-        uint32_t id = idBits.clearFirstMarkedBit();
-        const PointerCoords& c = spotCoords[spotIdToIndex[id]];
-        const SpriteIcon& icon = c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE) > 0
-                ? mResources.spotTouch : mResources.spotHover;
-        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X);
-        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y);
-
-        Spot* spot = getSpot(id, newSpots);
-        if (!spot) {
-            spot = createAndAddSpotLocked(id, newSpots);
-        }
-
-        spot->updateSprite(&icon, x, y, displayId);
-    }
-
-    // Remove spots for fingers that went up.
-    for (size_t i = 0; i < newSpots.size(); i++) {
-        Spot* spot = newSpots[i];
-        if (spot->id != Spot::INVALID_ID
-                && !spotIdBits.hasBit(spot->id)) {
-            fadeOutAndReleaseSpotLocked(spot);
-        }
-    }
-
-    mSpriteController->closeTransaction();
-    mLocked.spotsByDisplay[displayId] = newSpots;
+    mLocked.spotControllers.at(displayId).setSpots(spotCoords, spotIdToIndex, spotIdBits);
 }
 
 void PointerController::clearSpots() {
-#if DEBUG_POINTER_UPDATES
-    ALOGD("clearSpots");
-#endif
+    std::scoped_lock lock(mLock);
+    clearSpotsLocked();
+}
 
-    AutoMutex _l(mLock);
-    if (!mLocked.viewport.isValid()) {
-        return;
+void PointerController::clearSpotsLocked() REQUIRES(mLock) {
+    for (auto& [displayID, spotController] : mLocked.spotControllers) {
+        spotController.clearSpots();
     }
-
-    fadeOutAndReleaseAllSpotsLocked();
 }
 
 void PointerController::setInactivityTimeout(InactivityTimeout inactivityTimeout) {
-    AutoMutex _l(mLock);
-
-    if (mLocked.inactivityTimeout != inactivityTimeout) {
-        mLocked.inactivityTimeout = inactivityTimeout;
-        resetInactivityTimeoutLocked();
-    }
+    mContext.setInactivityTimeout(inactivityTimeout);
 }
 
 void PointerController::reloadPointerResources() {
-    AutoMutex _l(mLock);
+    std::scoped_lock lock(mLock);
 
-    loadResourcesLocked();
-    updatePointerLocked();
-}
+    for (auto& [displayID, spotController] : mLocked.spotControllers) {
+        spotController.reloadSpotResources();
+    }
 
-/**
- * The viewport values for deviceHeight and deviceWidth have already been adjusted for rotation,
- * so here we are getting the dimensions in the original, unrotated orientation (orientation 0).
- */
-static void getNonRotatedSize(const DisplayViewport& viewport, int32_t& width, int32_t& height) {
-    width = viewport.deviceWidth;
-    height = viewport.deviceHeight;
-
-    if (viewport.orientation == DISPLAY_ORIENTATION_90
-            || viewport.orientation == DISPLAY_ORIENTATION_270) {
-        std::swap(width, height);
+    if (mCursorController.resourcesLoaded()) {
+        bool getAdditionalMouseResources = false;
+        if (mLocked.presentation == PointerController::Presentation::POINTER) {
+            getAdditionalMouseResources = true;
+        }
+        mCursorController.reloadPointerResources(getAdditionalMouseResources);
     }
 }
 
 void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
-    AutoMutex _l(mLock);
-    if (viewport == mLocked.viewport) {
-        return;
+    std::scoped_lock lock(mLock);
+
+    bool getAdditionalMouseResources = false;
+    if (mLocked.presentation == PointerController::Presentation::POINTER) {
+        getAdditionalMouseResources = true;
     }
-
-    const DisplayViewport oldViewport = mLocked.viewport;
-    mLocked.viewport = viewport;
-
-    int32_t oldDisplayWidth, oldDisplayHeight;
-    getNonRotatedSize(oldViewport, oldDisplayWidth, oldDisplayHeight);
-    int32_t newDisplayWidth, newDisplayHeight;
-    getNonRotatedSize(viewport, newDisplayWidth, newDisplayHeight);
-
-    // Reset cursor position to center if size or display changed.
-    if (oldViewport.displayId != viewport.displayId
-            || oldDisplayWidth != newDisplayWidth
-            || oldDisplayHeight != newDisplayHeight) {
-
-        float minX, minY, maxX, maxY;
-        if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
-            mLocked.pointerX = (minX + maxX) * 0.5f;
-            mLocked.pointerY = (minY + maxY) * 0.5f;
-            // Reload icon resources for density may be changed.
-            loadResourcesLocked();
-        } else {
-            mLocked.pointerX = 0;
-            mLocked.pointerY = 0;
-        }
-
-        fadeOutAndReleaseAllSpotsLocked();
-    } else if (oldViewport.orientation != viewport.orientation) {
-        // Apply offsets to convert from the pixel top-left corner position to the pixel center.
-        // This creates an invariant frame of reference that we can easily rotate when
-        // taking into account that the pointer may be located at fractional pixel offsets.
-        float x = mLocked.pointerX + 0.5f;
-        float y = mLocked.pointerY + 0.5f;
-        float temp;
-
-        // Undo the previous rotation.
-        switch (oldViewport.orientation) {
-        case DISPLAY_ORIENTATION_90:
-            temp = x;
-            x =  oldViewport.deviceHeight - y;
-            y = temp;
-            break;
-        case DISPLAY_ORIENTATION_180:
-            x = oldViewport.deviceWidth - x;
-            y = oldViewport.deviceHeight - y;
-            break;
-        case DISPLAY_ORIENTATION_270:
-            temp = x;
-            x = y;
-            y = oldViewport.deviceWidth - temp;
-            break;
-        }
-
-        // Perform the new rotation.
-        switch (viewport.orientation) {
-        case DISPLAY_ORIENTATION_90:
-            temp = x;
-            x = y;
-            y = viewport.deviceHeight - temp;
-            break;
-        case DISPLAY_ORIENTATION_180:
-            x = viewport.deviceWidth - x;
-            y = viewport.deviceHeight - y;
-            break;
-        case DISPLAY_ORIENTATION_270:
-            temp = x;
-            x = viewport.deviceWidth - y;
-            y = temp;
-            break;
-        }
-
-        // Apply offsets to convert from the pixel center to the pixel top-left corner position
-        // and save the results.
-        mLocked.pointerX = x - 0.5f;
-        mLocked.pointerY = y - 0.5f;
-    }
-
-    updatePointerLocked();
+    mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources);
 }
 
 void PointerController::updatePointerIcon(int32_t iconId) {
-    AutoMutex _l(mLock);
-    if (mLocked.requestedPointerType != iconId) {
-        mLocked.requestedPointerType = iconId;
-        mLocked.presentationChanged = true;
-        updatePointerLocked();
-    }
+    std::scoped_lock lock(mLock);
+    mCursorController.updatePointerIcon(iconId);
 }
 
 void PointerController::setCustomPointerIcon(const SpriteIcon& icon) {
-    AutoMutex _l(mLock);
-
-    const int32_t iconId = mPolicy->getCustomPointerIconId();
-    mLocked.additionalMouseResources[iconId] = icon;
-    mLocked.requestedPointerType = iconId;
-    mLocked.presentationChanged = true;
-
-    updatePointerLocked();
-}
-
-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:
-        controller->doInactivityTimeout();
-        break;
-    }
-}
-
-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);
-        return 0; // remove the callback
-    }
-
-    if (!(events & Looper::EVENT_INPUT)) {
-        ALOGW("Received spurious callback for unhandled poll event.  events=0x%x", events);
-        return 1; // keep the callback
-    }
-
-    bool gotVsync = false;
-    ssize_t n;
-    nsecs_t timestamp;
-    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
-    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;
-                gotVsync = true;
-            }
-        }
-    }
-    if (gotVsync) {
-        controller->doAnimate(timestamp);
-    }
-    return 1;  // keep the callback
+    std::scoped_lock lock(mLock);
+    mCursorController.setCustomPointerIcon(icon);
 }
 
 void PointerController::doAnimate(nsecs_t timestamp) {
-    AutoMutex _l(mLock);
+    std::scoped_lock lock(mLock);
 
-    mLocked.animationPending = false;
+    mContext.setAnimationPending(false);
 
-    bool keepFading = doFadingAnimationLocked(timestamp);
-    bool keepBitmapFlipping = doBitmapAnimationLocked(timestamp);
+    bool keepFading = false;
+    keepFading = mCursorController.doFadingAnimation(timestamp, keepFading);
+
+    for (auto& [displayID, spotController] : mLocked.spotControllers) {
+        keepFading = spotController.doFadingAnimation(timestamp, keepFading);
+    }
+
+    bool keepBitmapFlipping = mCursorController.doBitmapAnimation(timestamp);
     if (keepFading || keepBitmapFlipping) {
-        startAnimationLocked();
+        mContext.startAnimation();
     }
 }
 
-bool PointerController::doFadingAnimationLocked(nsecs_t timestamp) {
-    bool keepAnimating = false;
-    nsecs_t frameDelay = timestamp - mLocked.animationTime;
-
-    // Animate pointer fade.
-    if (mLocked.pointerFadeDirection < 0) {
-        mLocked.pointerAlpha -= float(frameDelay) / POINTER_FADE_DURATION;
-        if (mLocked.pointerAlpha <= 0.0f) {
-            mLocked.pointerAlpha = 0.0f;
-            mLocked.pointerFadeDirection = 0;
-        } else {
-            keepAnimating = true;
-        }
-        updatePointerLocked();
-    } else if (mLocked.pointerFadeDirection > 0) {
-        mLocked.pointerAlpha += float(frameDelay) / POINTER_FADE_DURATION;
-        if (mLocked.pointerAlpha >= 1.0f) {
-            mLocked.pointerAlpha = 1.0f;
-            mLocked.pointerFadeDirection = 0;
-        } else {
-            keepAnimating = true;
-        }
-        updatePointerLocked();
-    }
-
-    // Animate spots that are fading out and being removed.
-    for(auto it = mLocked.spotsByDisplay.begin(); it != mLocked.spotsByDisplay.end();) {
-        std::vector<Spot*>& spots = it->second;
-        size_t numSpots = spots.size();
-        for (size_t i = 0; i < numSpots;) {
-            Spot* spot = spots[i];
-            if (spot->id == Spot::INVALID_ID) {
-                spot->alpha -= float(frameDelay) / SPOT_FADE_DURATION;
-                if (spot->alpha <= 0) {
-                    spots.erase(spots.begin() + i);
-                    releaseSpotLocked(spot);
-                    numSpots--;
-                    continue;
-                } else {
-                    spot->sprite->setAlpha(spot->alpha);
-                    keepAnimating = true;
-                }
-            }
-            ++i;
-        }
-
-        if (spots.size() == 0) {
-            it = mLocked.spotsByDisplay.erase(it);
-        } else {
-            ++it;
-        }
-    }
-
-    return keepAnimating;
-}
-
-bool PointerController::doBitmapAnimationLocked(nsecs_t timestamp) {
-    std::map<int32_t, PointerAnimation>::const_iterator iter = mLocked.animationResources.find(
-            mLocked.requestedPointerType);
-    if (iter == mLocked.animationResources.end()) {
-        return false;
-    }
-
-    if (timestamp - mLocked.lastFrameUpdatedTime > iter->second.durationPerFrame) {
-        mSpriteController->openTransaction();
-
-        int incr = (timestamp - mLocked.lastFrameUpdatedTime) / iter->second.durationPerFrame;
-        mLocked.animationFrameIndex += incr;
-        mLocked.lastFrameUpdatedTime += iter->second.durationPerFrame * incr;
-        while (mLocked.animationFrameIndex >= iter->second.animationFrames.size()) {
-            mLocked.animationFrameIndex -= iter->second.animationFrames.size();
-        }
-        mLocked.pointerSprite->setIcon(iter->second.animationFrames[mLocked.animationFrameIndex]);
-
-        mSpriteController->closeTransaction();
-    }
-
-    // Keep animating.
-    return true;
-}
-
 void PointerController::doInactivityTimeout() {
     fade(Transition::GRADUAL);
 }
 
-void PointerController::startAnimationLocked() {
-    if (!mLocked.animationPending) {
-        mLocked.animationPending = true;
-        mLocked.animationTime = systemTime(SYSTEM_TIME_MONOTONIC);
-        mDisplayEventReceiver.requestNextVsync();
-    }
-}
-
-void PointerController::resetInactivityTimeoutLocked() {
-    mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT);
-
-    nsecs_t timeout = mLocked.inactivityTimeout == InactivityTimeout::SHORT
-            ? INACTIVITY_TIMEOUT_DELAY_TIME_SHORT
-            : INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL;
-    mLooper->sendMessageDelayed(timeout, mHandler, MSG_INACTIVITY_TIMEOUT);
-}
-
-void PointerController::removeInactivityTimeoutLocked() {
-    mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT);
-}
-
-void PointerController::updatePointerLocked() REQUIRES(mLock) {
-    if (!mLocked.viewport.isValid()) {
-        return;
+void PointerController::onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports) {
+    std::unordered_set<int32_t> displayIdSet;
+    for (DisplayViewport viewport : viewports) {
+        displayIdSet.insert(viewport.displayId);
     }
 
-    mSpriteController->openTransaction();
-
-    mLocked.pointerSprite->setLayer(Sprite::BASE_LAYER_POINTER);
-    mLocked.pointerSprite->setPosition(mLocked.pointerX, mLocked.pointerY);
-    mLocked.pointerSprite->setDisplayId(mLocked.viewport.displayId);
-
-    if (mLocked.pointerAlpha > 0) {
-        mLocked.pointerSprite->setAlpha(mLocked.pointerAlpha);
-        mLocked.pointerSprite->setVisible(true);
-    } else {
-        mLocked.pointerSprite->setVisible(false);
-    }
-
-    if (mLocked.pointerIconChanged || mLocked.presentationChanged) {
-        if (mLocked.presentation == Presentation::POINTER) {
-            if (mLocked.requestedPointerType == mPolicy->getDefaultPointerIconId()) {
-                mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
-            } else {
-                std::map<int32_t, SpriteIcon>::const_iterator iter =
-                    mLocked.additionalMouseResources.find(mLocked.requestedPointerType);
-                if (iter != mLocked.additionalMouseResources.end()) {
-                    std::map<int32_t, PointerAnimation>::const_iterator anim_iter =
-                            mLocked.animationResources.find(mLocked.requestedPointerType);
-                    if (anim_iter != mLocked.animationResources.end()) {
-                        mLocked.animationFrameIndex = 0;
-                        mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
-                        startAnimationLocked();
-                    }
-                    mLocked.pointerSprite->setIcon(iter->second);
-                } else {
-                    ALOGW("Can't find the resource for icon id %d", mLocked.requestedPointerType);
-                    mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
-                }
-            }
+    std::scoped_lock lock(mLock);
+    for (auto it = mLocked.spotControllers.begin(); it != mLocked.spotControllers.end();) {
+        int32_t displayID = it->first;
+        if (!displayIdSet.count(displayID)) {
+            it = mLocked.spotControllers.erase(it);
         } else {
-            mLocked.pointerSprite->setIcon(mResources.spotAnchor);
-        }
-        mLocked.pointerIconChanged = false;
-        mLocked.presentationChanged = false;
-    }
-
-    mSpriteController->closeTransaction();
-}
-
-PointerController::Spot* PointerController::getSpot(uint32_t id, const std::vector<Spot*>& spots) {
-    for (size_t i = 0; i < spots.size(); i++) {
-        Spot* spot = spots[i];
-        if (spot->id == id) {
-            return spot;
-        }
-    }
-
-    return nullptr;
-}
-
-PointerController::Spot* PointerController::createAndAddSpotLocked(uint32_t id,
-        std::vector<Spot*>& spots) {
-    // Remove spots until we have fewer than MAX_SPOTS remaining.
-    while (spots.size() >= MAX_SPOTS) {
-        Spot* spot = removeFirstFadingSpotLocked(spots);
-        if (!spot) {
-            spot = spots[0];
-            spots.erase(spots.begin());
-        }
-        releaseSpotLocked(spot);
-    }
-
-    // Obtain a sprite from the recycled pool.
-    sp<Sprite> sprite;
-    if (! mLocked.recycledSprites.empty()) {
-        sprite = mLocked.recycledSprites.back();
-        mLocked.recycledSprites.pop_back();
-    } else {
-        sprite = mSpriteController->createSprite();
-    }
-
-    // Return the new spot.
-    Spot* spot = new Spot(id, sprite);
-    spots.push_back(spot);
-    return spot;
-}
-
-PointerController::Spot* PointerController::removeFirstFadingSpotLocked(std::vector<Spot*>& spots) {
-    for (size_t i = 0; i < spots.size(); i++) {
-        Spot* spot = spots[i];
-        if (spot->id == Spot::INVALID_ID) {
-            spots.erase(spots.begin() + i);
-            return spot;
-        }
-    }
-    return nullptr;
-}
-
-void PointerController::releaseSpotLocked(Spot* spot) {
-    spot->sprite->clearIcon();
-
-    if (mLocked.recycledSprites.size() < MAX_RECYCLED_SPRITES) {
-        mLocked.recycledSprites.push_back(spot->sprite);
-    }
-
-    delete spot;
-}
-
-void PointerController::fadeOutAndReleaseSpotLocked(Spot* spot) {
-    if (spot->id != Spot::INVALID_ID) {
-        spot->id = Spot::INVALID_ID;
-        startAnimationLocked();
-    }
-}
-
-void PointerController::fadeOutAndReleaseAllSpotsLocked() {
-    for (auto& it : mLocked.spotsByDisplay) {
-        const std::vector<Spot*>& spots = it.second;
-        size_t numSpots = spots.size();
-        for (size_t i = 0; i < numSpots; i++) {
-            Spot* spot = spots[i];
-            fadeOutAndReleaseSpotLocked(spot);
-        }
-    }
-}
-
-void PointerController::loadResourcesLocked() REQUIRES(mLock) {
-    if (!mLocked.viewport.isValid()) {
-        return;
-    }
-
-    mPolicy->loadPointerResources(&mResources, mLocked.viewport.displayId);
-    mPolicy->loadPointerIcon(&mLocked.pointerIcon, mLocked.viewport.displayId);
-
-    mLocked.additionalMouseResources.clear();
-    mLocked.animationResources.clear();
-    if (mLocked.presentation == Presentation::POINTER) {
-        mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
-                &mLocked.animationResources, mLocked.viewport.displayId);
-    }
-
-    mLocked.pointerIconChanged = true;
-}
-
-
-// --- PointerController::Spot ---
-
-void PointerController::Spot::updateSprite(const SpriteIcon* icon, float x, float y,
-        int32_t displayId) {
-    sprite->setLayer(Sprite::BASE_LAYER_SPOT + id);
-    sprite->setAlpha(alpha);
-    sprite->setTransformationMatrix(SpriteTransformationMatrix(scale, 0.0f, 0.0f, scale));
-    sprite->setPosition(x, y);
-    sprite->setDisplayId(displayId);
-    this->x = x;
-    this->y = y;
-
-    if (icon != lastIcon) {
-        lastIcon = icon;
-        if (icon) {
-            sprite->setIcon(*icon);
-            sprite->setVisible(true);
-        } else {
-            sprite->setVisible(false);
+            ++it;
         }
     }
 }
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index 14c0679..1f561da 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -30,48 +30,14 @@
 #include <memory>
 #include <vector>
 
+#include "MouseCursorController.h"
+#include "PointerControllerContext.h"
 #include "SpriteController.h"
+#include "TouchSpotController.h"
 
 namespace android {
 
 /*
- * Pointer resources.
- */
-struct PointerResources {
-    SpriteIcon spotHover;
-    SpriteIcon spotTouch;
-    SpriteIcon spotAnchor;
-};
-
-struct PointerAnimation {
-    std::vector<SpriteIcon> animationFrames;
-    nsecs_t durationPerFrame;
-};
-
-/*
- * Pointer controller policy interface.
- *
- * The pointer controller policy is used by the pointer controller to interact with
- * the Window Manager and other system components.
- *
- * The actual implementation is partially supported by callbacks into the DVM
- * via JNI.  This interface is also mocked in the unit tests.
- */
-class PointerControllerPolicyInterface : public virtual RefBase {
-protected:
-    PointerControllerPolicyInterface() { }
-    virtual ~PointerControllerPolicyInterface() { }
-
-public:
-    virtual void loadPointerIcon(SpriteIcon* icon, int32_t displayId) = 0;
-    virtual void loadPointerResources(PointerResources* outResources, int32_t displayId) = 0;
-    virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
-            std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) = 0;
-    virtual int32_t getDefaultPointerIconId() = 0;
-    virtual int32_t getCustomPointerIconId() = 0;
-};
-
-/*
  * Tracks pointer movements and draws the pointer sprite to a surface.
  *
  * Handles pointer acceleration and animation.
@@ -81,15 +47,10 @@
     static std::shared_ptr<PointerController> create(
             const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
             const sp<SpriteController>& spriteController);
-    enum class InactivityTimeout {
-        NORMAL = 0,
-        SHORT = 1,
-    };
 
-    virtual ~PointerController();
+    virtual ~PointerController() = default;
 
-    virtual bool getBounds(float* outMinX, float* outMinY,
-            float* outMaxX, float* outMaxY) const;
+    virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
     virtual void move(float deltaX, float deltaY);
     virtual void setButtonState(int32_t buttonState);
     virtual int32_t getButtonState() const;
@@ -101,129 +62,37 @@
     virtual void setDisplayViewport(const DisplayViewport& viewport);
 
     virtual void setPresentation(Presentation presentation);
-    virtual void setSpots(const PointerCoords* spotCoords,
-            const uint32_t* spotIdToIndex, BitSet32 spotIdBits, int32_t displayId);
+    virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
+                          BitSet32 spotIdBits, int32_t displayId);
     virtual void clearSpots();
 
     void updatePointerIcon(int32_t iconId);
     void setCustomPointerIcon(const SpriteIcon& icon);
     void setInactivityTimeout(InactivityTimeout inactivityTimeout);
+    void doInactivityTimeout();
+    void doAnimate(nsecs_t timestamp);
     void reloadPointerResources();
+    void onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports);
 
 private:
-    static constexpr size_t MAX_RECYCLED_SPRITES = 12;
-    static constexpr size_t MAX_SPOTS = 12;
+    friend PointerControllerContext::LooperCallback;
+    friend PointerControllerContext::MessageHandler;
 
-    enum {
-        MSG_INACTIVITY_TIMEOUT,
-    };
+    mutable std::mutex mLock;
 
-    struct Spot {
-        static const uint32_t INVALID_ID = 0xffffffff;
+    PointerControllerContext mContext;
 
-        uint32_t id;
-        sp<Sprite> sprite;
-        float alpha;
-        float scale;
-        float x, y;
-
-        inline Spot(uint32_t id, const sp<Sprite>& sprite)
-              : id(id),
-                sprite(sprite),
-                alpha(1.0f),
-                scale(1.0f),
-                x(0.0f),
-                y(0.0f),
-                lastIcon(nullptr) {}
-
-        void updateSprite(const SpriteIcon* icon, float x, float y, int32_t displayId);
-
-    private:
-        const SpriteIcon* lastIcon;
-    };
-
-    class MessageHandler : public virtual android::MessageHandler {
-    public:
-        void handleMessage(const Message& message) override;
-        std::weak_ptr<PointerController> pointerController;
-    };
-
-    class LooperCallback : public virtual android::LooperCallback {
-    public:
-        int handleEvent(int fd, int events, void* data) override;
-        std::weak_ptr<PointerController> pointerController;
-    };
-
-    mutable Mutex mLock;
-
-    sp<PointerControllerPolicyInterface> mPolicy;
-    sp<Looper> mLooper;
-    sp<SpriteController> mSpriteController;
-    sp<MessageHandler> mHandler;
-    sp<LooperCallback> mCallback;
-
-    DisplayEventReceiver mDisplayEventReceiver;
-
-    PointerResources mResources;
+    MouseCursorController mCursorController;
 
     struct Locked {
-        bool animationPending;
-        nsecs_t animationTime;
-
-        size_t animationFrameIndex;
-        nsecs_t lastFrameUpdatedTime;
-
-        DisplayViewport viewport;
-
-        InactivityTimeout inactivityTimeout;
-
         Presentation presentation;
-        bool presentationChanged;
 
-        int32_t pointerFadeDirection;
-        float pointerX;
-        float pointerY;
-        float pointerAlpha;
-        sp<Sprite> pointerSprite;
-        SpriteIcon pointerIcon;
-        bool pointerIconChanged;
-
-        std::map<int32_t, SpriteIcon> additionalMouseResources;
-        std::map<int32_t, PointerAnimation> animationResources;
-
-        int32_t requestedPointerType;
-
-        int32_t buttonState;
-
-        std::map<int32_t /* displayId */, std::vector<Spot*>> spotsByDisplay;
-        std::vector<sp<Sprite>> recycledSprites;
+        std::unordered_map<int32_t /* displayId */, TouchSpotController> spotControllers;
     } mLocked GUARDED_BY(mLock);
 
     PointerController(const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
                       const sp<SpriteController>& spriteController);
-
-    bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
-    void setPositionLocked(float x, float y);
-
-    void doAnimate(nsecs_t timestamp);
-    bool doFadingAnimationLocked(nsecs_t timestamp);
-    bool doBitmapAnimationLocked(nsecs_t timestamp);
-    void doInactivityTimeout();
-
-    void startAnimationLocked();
-
-    void resetInactivityTimeoutLocked();
-    void removeInactivityTimeoutLocked();
-    void updatePointerLocked();
-
-    Spot* getSpot(uint32_t id, const std::vector<Spot*>& spots);
-    Spot* createAndAddSpotLocked(uint32_t id, std::vector<Spot*>& spots);
-    Spot* removeFirstFadingSpotLocked(std::vector<Spot*>& spots);
-    void releaseSpotLocked(Spot* spot);
-    void fadeOutAndReleaseSpotLocked(Spot* spot);
-    void fadeOutAndReleaseAllSpotsLocked();
-
-    void loadResourcesLocked();
+    void clearSpotsLocked();
 };
 
 } // namespace android
diff --git a/libs/input/PointerControllerContext.cpp b/libs/input/PointerControllerContext.cpp
new file mode 100644
index 0000000..2d7e22b
--- /dev/null
+++ b/libs/input/PointerControllerContext.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PointerControllerContext.h"
+#include "PointerController.h"
+
+namespace {
+// Time to wait before starting the fade when the pointer is inactive.
+const nsecs_t INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL = 15 * 1000 * 1000000LL; // 15 seconds
+const nsecs_t INACTIVITY_TIMEOUT_DELAY_TIME_SHORT = 3 * 1000 * 1000000LL;   // 3 seconds
+
+// The number of events to be read at once for DisplayEventReceiver.
+const int EVENT_BUFFER_SIZE = 100;
+} // namespace
+
+namespace android {
+
+// --- PointerControllerContext ---
+
+PointerControllerContext::PointerControllerContext(
+        const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
+        const sp<SpriteController>& spriteController, PointerController& controller)
+      : mPolicy(policy),
+        mLooper(looper),
+        mSpriteController(spriteController),
+        mHandler(new MessageHandler()),
+        mCallback(new LooperCallback()),
+        mController(controller) {
+    std::scoped_lock lock(mLock);
+    mLocked.inactivityTimeout = InactivityTimeout::NORMAL;
+    mLocked.animationPending = false;
+}
+
+PointerControllerContext::~PointerControllerContext() {
+    mLooper->removeMessages(mHandler);
+}
+
+void PointerControllerContext::setInactivityTimeout(InactivityTimeout inactivityTimeout) {
+    std::scoped_lock lock(mLock);
+
+    if (mLocked.inactivityTimeout != inactivityTimeout) {
+        mLocked.inactivityTimeout = inactivityTimeout;
+        resetInactivityTimeoutLocked();
+    }
+}
+
+void PointerControllerContext::startAnimation() {
+    std::scoped_lock lock(mLock);
+    if (!mLocked.animationPending) {
+        mLocked.animationPending = true;
+        mLocked.animationTime = systemTime(SYSTEM_TIME_MONOTONIC);
+        mDisplayEventReceiver.requestNextVsync();
+    }
+}
+
+void PointerControllerContext::resetInactivityTimeout() {
+    std::scoped_lock lock(mLock);
+    resetInactivityTimeoutLocked();
+}
+
+void PointerControllerContext::resetInactivityTimeoutLocked() REQUIRES(mLock) {
+    mLooper->removeMessages(mHandler, MessageHandler::MSG_INACTIVITY_TIMEOUT);
+
+    nsecs_t timeout = mLocked.inactivityTimeout == InactivityTimeout::SHORT
+            ? INACTIVITY_TIMEOUT_DELAY_TIME_SHORT
+            : INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL;
+    mLooper->sendMessageDelayed(timeout, mHandler, MessageHandler::MSG_INACTIVITY_TIMEOUT);
+}
+
+void PointerControllerContext::removeInactivityTimeout() {
+    std::scoped_lock lock(mLock);
+    mLooper->removeMessages(mHandler, MessageHandler::MSG_INACTIVITY_TIMEOUT);
+}
+
+void PointerControllerContext::setAnimationPending(bool animationPending) {
+    std::scoped_lock lock(mLock);
+    mLocked.animationPending = animationPending;
+}
+
+nsecs_t PointerControllerContext::getAnimationTime() {
+    std::scoped_lock lock(mLock);
+    return mLocked.animationTime;
+}
+
+void PointerControllerContext::setHandlerController(std::shared_ptr<PointerController> controller) {
+    mHandler->pointerController = controller;
+}
+
+void PointerControllerContext::setCallbackController(
+        std::shared_ptr<PointerController> controller) {
+    mCallback->pointerController = controller;
+}
+
+sp<PointerControllerPolicyInterface> PointerControllerContext::getPolicy() {
+    return mPolicy;
+}
+
+sp<SpriteController> PointerControllerContext::getSpriteController() {
+    return mSpriteController;
+}
+
+void PointerControllerContext::initializeDisplayEventReceiver() {
+    if (mDisplayEventReceiver.initCheck() == NO_ERROR) {
+        mLooper->addFd(mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK, Looper::EVENT_INPUT,
+                       mCallback, nullptr);
+    } else {
+        ALOGE("Failed to initialize DisplayEventReceiver.");
+    }
+}
+
+void PointerControllerContext::handleDisplayEvents() {
+    bool gotVsync = false;
+    ssize_t n;
+    nsecs_t timestamp;
+    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
+    while ((n = 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;
+                gotVsync = true;
+            }
+        }
+    }
+    if (gotVsync) {
+        mController.doAnimate(timestamp);
+    }
+}
+
+void PointerControllerContext::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:
+            controller->doInactivityTimeout();
+            break;
+    }
+}
+
+int PointerControllerContext::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);
+        return 0; // remove the callback
+    }
+
+    if (!(events & Looper::EVENT_INPUT)) {
+        ALOGW("Received spurious callback for unhandled poll event.  events=0x%x", events);
+        return 1; // keep the callback
+    }
+
+    controller->mContext.handleDisplayEvents();
+    return 1; // keep the callback
+}
+
+} // namespace android
diff --git a/libs/input/PointerControllerContext.h b/libs/input/PointerControllerContext.h
new file mode 100644
index 0000000..92e1bda
--- /dev/null
+++ b/libs/input/PointerControllerContext.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_POINTER_CONTROLLER_CONTEXT_H
+#define _UI_POINTER_CONTROLLER_CONTEXT_H
+
+#include <PointerControllerInterface.h>
+#include <gui/DisplayEventReceiver.h>
+#include <input/DisplayViewport.h>
+#include <input/Input.h>
+#include <ui/DisplayInfo.h>
+#include <utils/BitSet.h>
+#include <utils/Looper.h>
+#include <utils/RefBase.h>
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "SpriteController.h"
+
+namespace android {
+
+class PointerController;
+
+/*
+ * Pointer resources.
+ */
+struct PointerResources {
+    SpriteIcon spotHover;
+    SpriteIcon spotTouch;
+    SpriteIcon spotAnchor;
+};
+
+struct PointerAnimation {
+    std::vector<SpriteIcon> animationFrames;
+    nsecs_t durationPerFrame;
+};
+
+enum class InactivityTimeout {
+    NORMAL = 0,
+    SHORT = 1,
+};
+
+/*
+ * Pointer controller policy interface.
+ *
+ * The pointer controller policy is used by the pointer controller to interact with
+ * the Window Manager and other system components.
+ *
+ * The actual implementation is partially supported by callbacks into the DVM
+ * via JNI.  This interface is also mocked in the unit tests.
+ */
+class PointerControllerPolicyInterface : public virtual RefBase {
+protected:
+    PointerControllerPolicyInterface() {}
+    virtual ~PointerControllerPolicyInterface() {}
+
+public:
+    virtual void loadPointerIcon(SpriteIcon* icon, int32_t displayId) = 0;
+    virtual void loadPointerResources(PointerResources* outResources, int32_t displayId) = 0;
+    virtual void loadAdditionalMouseResources(
+            std::map<int32_t, SpriteIcon>* outResources,
+            std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) = 0;
+    virtual int32_t getDefaultPointerIconId() = 0;
+    virtual int32_t getCustomPointerIconId() = 0;
+};
+
+/*
+ * Contains logic and resources shared among PointerController,
+ * MouseCursorController, and TouchSpotController.
+ */
+
+class PointerControllerContext {
+public:
+    PointerControllerContext(const sp<PointerControllerPolicyInterface>& policy,
+                             const sp<Looper>& looper, const sp<SpriteController>& spriteController,
+                             PointerController& controller);
+    ~PointerControllerContext();
+
+    void removeInactivityTimeout();
+    void resetInactivityTimeout();
+    void startAnimation();
+    void setInactivityTimeout(InactivityTimeout inactivityTimeout);
+
+    void setAnimationPending(bool animationPending);
+    nsecs_t getAnimationTime();
+
+    void clearSpotsByDisplay(int32_t displayId);
+
+    void setHandlerController(std::shared_ptr<PointerController> controller);
+    void setCallbackController(std::shared_ptr<PointerController> controller);
+
+    sp<PointerControllerPolicyInterface> getPolicy();
+    sp<SpriteController> getSpriteController();
+
+    void initializeDisplayEventReceiver();
+    void handleDisplayEvents();
+
+    class MessageHandler : public virtual android::MessageHandler {
+    public:
+        enum {
+            MSG_INACTIVITY_TIMEOUT,
+        };
+
+        void handleMessage(const Message& message) override;
+        std::weak_ptr<PointerController> pointerController;
+    };
+
+    class LooperCallback : public virtual android::LooperCallback {
+    public:
+        int handleEvent(int fd, int events, void* data) override;
+        std::weak_ptr<PointerController> pointerController;
+    };
+
+private:
+    sp<PointerControllerPolicyInterface> mPolicy;
+    sp<Looper> mLooper;
+    sp<SpriteController> mSpriteController;
+    sp<MessageHandler> mHandler;
+    sp<LooperCallback> mCallback;
+
+    DisplayEventReceiver mDisplayEventReceiver;
+
+    PointerController& mController;
+
+    mutable std::mutex mLock;
+
+    struct Locked {
+        bool animationPending;
+        nsecs_t animationTime;
+
+        InactivityTimeout inactivityTimeout;
+    } mLocked GUARDED_BY(mLock);
+
+    void resetInactivityTimeoutLocked();
+};
+
+} // namespace android
+
+#endif // _UI_POINTER_CONTROLLER_CONTEXT_H
diff --git a/libs/input/TouchSpotController.cpp b/libs/input/TouchSpotController.cpp
new file mode 100644
index 0000000..c7430ce
--- /dev/null
+++ b/libs/input/TouchSpotController.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "TouchSpotController"
+
+// Log debug messages about pointer updates
+#define DEBUG_SPOT_UPDATES 0
+
+#include "TouchSpotController.h"
+
+#include <log/log.h>
+
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkCanvas.h>
+#include <SkColor.h>
+#include <SkPaint.h>
+
+namespace {
+// Time to spend fading out the spot completely.
+const nsecs_t SPOT_FADE_DURATION = 200 * 1000000LL; // 200 ms
+} // namespace
+
+namespace android {
+
+// --- Spot ---
+
+void TouchSpotController::Spot::updateSprite(const SpriteIcon* icon, float x, float y,
+                                             int32_t displayId) {
+    sprite->setLayer(Sprite::BASE_LAYER_SPOT + id);
+    sprite->setAlpha(alpha);
+    sprite->setTransformationMatrix(SpriteTransformationMatrix(scale, 0.0f, 0.0f, scale));
+    sprite->setPosition(x, y);
+    sprite->setDisplayId(displayId);
+    this->x = x;
+    this->y = y;
+
+    if (icon != mLastIcon) {
+        mLastIcon = icon;
+        if (icon) {
+            sprite->setIcon(*icon);
+            sprite->setVisible(true);
+        } else {
+            sprite->setVisible(false);
+        }
+    }
+}
+
+// --- TouchSpotController ---
+
+TouchSpotController::TouchSpotController(int32_t displayId, PointerControllerContext& context)
+      : mDisplayId(displayId), mContext(context) {
+    mContext.getPolicy()->loadPointerResources(&mResources, mDisplayId);
+}
+
+TouchSpotController::~TouchSpotController() {
+    std::scoped_lock lock(mLock);
+
+    size_t numSpots = mLocked.displaySpots.size();
+    for (size_t i = 0; i < numSpots; i++) {
+        delete mLocked.displaySpots[i];
+    }
+    mLocked.displaySpots.clear();
+}
+
+void TouchSpotController::setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
+                                   BitSet32 spotIdBits) {
+#if DEBUG_SPOT_UPDATES
+    ALOGD("setSpots: idBits=%08x", spotIdBits.value);
+    for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) {
+        uint32_t id = idBits.firstMarkedBit();
+        idBits.clearBit(id);
+        const PointerCoords& c = spotCoords[spotIdToIndex[id]];
+        ALOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f, displayId=%" PRId32 ".", id,
+              c.getAxisValue(AMOTION_EVENT_AXIS_X), c.getAxisValue(AMOTION_EVENT_AXIS_Y),
+              c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), displayId);
+    }
+#endif
+
+    std::scoped_lock lock(mLock);
+    sp<SpriteController> spriteController = mContext.getSpriteController();
+    spriteController->openTransaction();
+
+    // Add or move spots for fingers that are down.
+    for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) {
+        uint32_t id = idBits.clearFirstMarkedBit();
+        const PointerCoords& c = spotCoords[spotIdToIndex[id]];
+        const SpriteIcon& icon = c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE) > 0
+                ? mResources.spotTouch
+                : mResources.spotHover;
+        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X);
+        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y);
+
+        Spot* spot = getSpot(id, mLocked.displaySpots);
+        if (!spot) {
+            spot = createAndAddSpotLocked(id, mLocked.displaySpots);
+        }
+
+        spot->updateSprite(&icon, x, y, mDisplayId);
+    }
+
+    for (Spot* spot : mLocked.displaySpots) {
+        if (spot->id != Spot::INVALID_ID && !spotIdBits.hasBit(spot->id)) {
+            fadeOutAndReleaseSpotLocked(spot);
+        }
+    }
+
+    spriteController->closeTransaction();
+}
+
+void TouchSpotController::clearSpots() {
+#if DEBUG_SPOT_UPDATES
+    ALOGD("clearSpots");
+#endif
+
+    std::scoped_lock lock(mLock);
+    fadeOutAndReleaseAllSpotsLocked();
+}
+
+TouchSpotController::Spot* TouchSpotController::getSpot(uint32_t id,
+                                                        const std::vector<Spot*>& spots) {
+    for (size_t i = 0; i < spots.size(); i++) {
+        Spot* spot = spots[i];
+        if (spot->id == id) {
+            return spot;
+        }
+    }
+    return nullptr;
+}
+
+TouchSpotController::Spot* TouchSpotController::createAndAddSpotLocked(uint32_t id,
+                                                                       std::vector<Spot*>& spots) {
+    // Remove spots until we have fewer than MAX_SPOTS remaining.
+    while (spots.size() >= MAX_SPOTS) {
+        Spot* spot = removeFirstFadingSpotLocked(spots);
+        if (!spot) {
+            spot = spots[0];
+            spots.erase(spots.begin());
+        }
+        releaseSpotLocked(spot);
+    }
+
+    // Obtain a sprite from the recycled pool.
+    sp<Sprite> sprite;
+    if (!mLocked.recycledSprites.empty()) {
+        sprite = mLocked.recycledSprites.back();
+        mLocked.recycledSprites.pop_back();
+    } else {
+        sprite = mContext.getSpriteController()->createSprite();
+    }
+
+    // Return the new spot.
+    Spot* spot = new Spot(id, sprite);
+    spots.push_back(spot);
+    return spot;
+}
+
+TouchSpotController::Spot* TouchSpotController::removeFirstFadingSpotLocked(
+        std::vector<Spot*>& spots) REQUIRES(mLock) {
+    for (size_t i = 0; i < spots.size(); i++) {
+        Spot* spot = spots[i];
+        if (spot->id == Spot::INVALID_ID) {
+            spots.erase(spots.begin() + i);
+            return spot;
+        }
+    }
+    return NULL;
+}
+
+void TouchSpotController::releaseSpotLocked(Spot* spot) REQUIRES(mLock) {
+    spot->sprite->clearIcon();
+
+    if (mLocked.recycledSprites.size() < MAX_RECYCLED_SPRITES) {
+        mLocked.recycledSprites.push_back(spot->sprite);
+    }
+
+    delete spot;
+}
+
+void TouchSpotController::fadeOutAndReleaseSpotLocked(Spot* spot) REQUIRES(mLock) {
+    if (spot->id != Spot::INVALID_ID) {
+        spot->id = Spot::INVALID_ID;
+        mContext.startAnimation();
+    }
+}
+
+void TouchSpotController::fadeOutAndReleaseAllSpotsLocked() REQUIRES(mLock) {
+    size_t numSpots = mLocked.displaySpots.size();
+    for (size_t i = 0; i < numSpots; i++) {
+        Spot* spot = mLocked.displaySpots[i];
+        fadeOutAndReleaseSpotLocked(spot);
+    }
+}
+
+void TouchSpotController::reloadSpotResources() {
+    mContext.getPolicy()->loadPointerResources(&mResources, mDisplayId);
+}
+
+bool TouchSpotController::doFadingAnimation(nsecs_t timestamp, bool keepAnimating) {
+    std::scoped_lock lock(mLock);
+    nsecs_t animationTime = mContext.getAnimationTime();
+    nsecs_t frameDelay = timestamp - animationTime;
+    size_t numSpots = mLocked.displaySpots.size();
+    for (size_t i = 0; i < numSpots;) {
+        Spot* spot = mLocked.displaySpots[i];
+        if (spot->id == Spot::INVALID_ID) {
+            spot->alpha -= float(frameDelay) / SPOT_FADE_DURATION;
+            if (spot->alpha <= 0) {
+                mLocked.displaySpots.erase(mLocked.displaySpots.begin() + i);
+                releaseSpotLocked(spot);
+                numSpots--;
+                continue;
+            } else {
+                spot->sprite->setAlpha(spot->alpha);
+                keepAnimating = true;
+            }
+        }
+        ++i;
+    }
+    return keepAnimating;
+}
+
+} // namespace android
diff --git a/libs/input/TouchSpotController.h b/libs/input/TouchSpotController.h
new file mode 100644
index 0000000..f3b3550
--- /dev/null
+++ b/libs/input/TouchSpotController.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_TOUCH_SPOT_CONTROLLER_H
+#define _UI_TOUCH_SPOT_CONTROLLER_H
+
+#include "PointerControllerContext.h"
+
+namespace android {
+
+/*
+ * Helper class for PointerController that specifically handles
+ * touch spot resources and actions for a single display.
+ */
+class TouchSpotController {
+public:
+    TouchSpotController(int32_t displayId, PointerControllerContext& context);
+    ~TouchSpotController();
+    void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
+                  BitSet32 spotIdBits);
+    void clearSpots();
+
+    void reloadSpotResources();
+    bool doFadingAnimation(nsecs_t timestamp, bool keepAnimating);
+
+private:
+    struct Spot {
+        static const uint32_t INVALID_ID = 0xffffffff;
+
+        uint32_t id;
+        sp<Sprite> sprite;
+        float alpha;
+        float scale;
+        float x, y;
+
+        inline Spot(uint32_t id, const sp<Sprite>& sprite)
+              : id(id),
+                sprite(sprite),
+                alpha(1.0f),
+                scale(1.0f),
+                x(0.0f),
+                y(0.0f),
+                mLastIcon(nullptr) {}
+
+        void updateSprite(const SpriteIcon* icon, float x, float y, int32_t displayId);
+
+    private:
+        const SpriteIcon* mLastIcon;
+    };
+
+    int32_t mDisplayId;
+
+    mutable std::mutex mLock;
+
+    PointerResources mResources;
+
+    PointerControllerContext& mContext;
+
+    static constexpr size_t MAX_RECYCLED_SPRITES = 12;
+    static constexpr size_t MAX_SPOTS = 12;
+
+    struct Locked {
+        std::vector<Spot*> displaySpots;
+        std::vector<sp<Sprite>> recycledSprites;
+
+    } mLocked GUARDED_BY(mLock);
+
+    Spot* getSpot(uint32_t id, const std::vector<Spot*>& spots);
+    Spot* createAndAddSpotLocked(uint32_t id, std::vector<Spot*>& spots);
+    Spot* removeFirstFadingSpotLocked(std::vector<Spot*>& spots);
+    void releaseSpotLocked(Spot* spot);
+    void fadeOutAndReleaseSpotLocked(Spot* spot);
+    void fadeOutAndReleaseAllSpotsLocked();
+};
+
+} // namespace android
+
+#endif // _UI_TOUCH_SPOT_CONTROLLER_H
diff --git a/libs/input/tests/PointerController_test.cpp b/libs/input/tests/PointerController_test.cpp
index 6e129a0..b67088a 100644
--- a/libs/input/tests/PointerController_test.cpp
+++ b/libs/input/tests/PointerController_test.cpp
@@ -178,9 +178,6 @@
     viewport.deviceWidth = 400;
     viewport.deviceHeight = 300;
     mPointerController->setDisplayViewport(viewport);
-
-    // The first call to setDisplayViewport should trigger the loading of the necessary resources.
-    EXPECT_TRUE(mPolicy->allResourcesAreLoaded());
 }
 
 void PointerControllerTest::loopThread() {
@@ -208,6 +205,7 @@
 
 TEST_F(PointerControllerTest, updatePointerIcon) {
     ensureDisplayViewportIsSet();
+    mPointerController->setPresentation(PointerController::Presentation::POINTER);
     mPointerController->unfade(PointerController::Transition::IMMEDIATE);
 
     int32_t type = CURSOR_TYPE_ADDITIONAL;
@@ -247,8 +245,6 @@
 
 TEST_F(PointerControllerTest, doesNotGetResourcesBeforeSettingViewport) {
     mPointerController->setPresentation(PointerController::Presentation::POINTER);
-    mPointerController->setSpots(nullptr, nullptr, BitSet32(), -1);
-    mPointerController->clearSpots();
     mPointerController->setPosition(1.0f, 1.0f);
     mPointerController->move(1.0f, 1.0f);
     mPointerController->unfade(PointerController::Transition::IMMEDIATE);
