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
