diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 757cde2..8656b26 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -139,6 +139,7 @@
         "KeyCharacterMap.cpp",
         "KeyLayoutMap.cpp",
         "MotionPredictor.cpp",
+        "MotionPredictorMetricsManager.cpp",
         "PrintTools.cpp",
         "PropertyMap.cpp",
         "TfLiteMotionPredictor.cpp",
@@ -152,9 +153,13 @@
     header_libs: [
         "flatbuffer_headers",
         "jni_headers",
+        "libeigen",
         "tensorflow_headers",
     ],
-    export_header_lib_headers: ["jni_headers"],
+    export_header_lib_headers: [
+        "jni_headers",
+        "libeigen",
+    ],
 
     generated_headers: [
         "cxx-bridge-header",
@@ -206,6 +211,17 @@
 
     target: {
         android: {
+            export_shared_lib_headers: ["libbinder"],
+
+            shared_libs: [
+                "libutils",
+                "libbinder",
+                // Stats logging library and its dependencies.
+                "libstatslog_libinput",
+                "libstatsbootstrap",
+                "android.os.statsbootstrap_aidl-cpp",
+            ],
+
             required: [
                 "motion_predictor_model_prebuilt",
                 "motion_predictor_model_config",
@@ -228,6 +244,43 @@
     },
 }
 
+// Use bootstrap version of stats logging library.
+// libinput is a bootstrap process (starts early in the boot process), and thus can't use the normal
+// `libstatslog` because that requires `libstatssocket`, which is only available later in the boot.
+cc_library {
+    name: "libstatslog_libinput",
+    generated_sources: ["statslog_libinput.cpp"],
+    generated_headers: ["statslog_libinput.h"],
+    export_generated_headers: ["statslog_libinput.h"],
+    shared_libs: [
+        "libbinder",
+        "libstatsbootstrap",
+        "libutils",
+        "android.os.statsbootstrap_aidl-cpp",
+    ],
+}
+
+genrule {
+    name: "statslog_libinput.h",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_libinput.h --module libinput" +
+        " --namespace android,stats,libinput --bootstrap",
+    out: [
+        "statslog_libinput.h",
+    ],
+}
+
+genrule {
+    name: "statslog_libinput.cpp",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_libinput.cpp --module libinput" +
+        " --namespace android,stats,libinput --importHeader statslog_libinput.h" +
+        " --bootstrap",
+    out: [
+        "statslog_libinput.cpp",
+    ],
+}
+
 cc_defaults {
     name: "libinput_fuzz_defaults",
     cpp_std: "c++20",
diff --git a/libs/input/MotionPredictor.cpp b/libs/input/MotionPredictor.cpp
index 0961a9d..b5a5e72 100644
--- a/libs/input/MotionPredictor.cpp
+++ b/libs/input/MotionPredictor.cpp
@@ -137,10 +137,7 @@
 
     // Pass input event to the MetricsManager.
     if (!mMetricsManager) {
-        mMetricsManager =
-                std::make_optional<MotionPredictorMetricsManager>(mModel->config()
-                                                                          .predictionInterval,
-                                                                  mModel->outputLength());
+        mMetricsManager.emplace(mModel->config().predictionInterval, mModel->outputLength());
     }
     mMetricsManager->onRecord(event);
 
diff --git a/libs/input/MotionPredictorMetricsManager.cpp b/libs/input/MotionPredictorMetricsManager.cpp
new file mode 100644
index 0000000..67b1032
--- /dev/null
+++ b/libs/input/MotionPredictorMetricsManager.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright 2023 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 "MotionPredictorMetricsManager"
+
+#include <input/MotionPredictorMetricsManager.h>
+
+#include <algorithm>
+
+#include <android-base/logging.h>
+
+#include "Eigen/Core"
+#include "Eigen/Geometry"
+
+#ifdef __ANDROID__
+#include <statslog_libinput.h>
+#endif
+
+namespace android {
+namespace {
+
+inline constexpr int NANOS_PER_SECOND = 1'000'000'000; // nanoseconds per second
+inline constexpr int NANOS_PER_MILLIS = 1'000'000;     // nanoseconds per millisecond
+
+// Velocity threshold at which we report "high-velocity" metrics, in pixels per second.
+// This value was selected from manual experimentation, as a threshold that separates "fast"
+// (semi-sloppy) handwriting from more careful medium to slow handwriting.
+inline constexpr float HIGH_VELOCITY_THRESHOLD = 1100.0;
+
+// Small value to add to the path length when computing scale-invariant error to avoid division by
+// zero.
+inline constexpr float PATH_LENGTH_EPSILON = 0.001;
+
+} // namespace
+
+MotionPredictorMetricsManager::MotionPredictorMetricsManager(nsecs_t predictionInterval,
+                                                             size_t maxNumPredictions)
+      : mPredictionInterval(predictionInterval),
+        mMaxNumPredictions(maxNumPredictions),
+        mRecentGroundTruthPoints(maxNumPredictions + 1),
+        mAggregatedMetrics(maxNumPredictions),
+        mAtomFields(maxNumPredictions) {}
+
+void MotionPredictorMetricsManager::onRecord(const MotionEvent& inputEvent) {
+    // Convert MotionEvent to GroundTruthPoint.
+    const PointerCoords* coords = inputEvent.getRawPointerCoords(/*pointerIndex=*/0);
+    LOG_ALWAYS_FATAL_IF(coords == nullptr);
+    const GroundTruthPoint groundTruthPoint{{.position = Eigen::Vector2f{coords->getY(),
+                                                                         coords->getX()},
+                                             .pressure =
+                                                     inputEvent.getPressure(/*pointerIndex=*/0)},
+                                            .timestamp = inputEvent.getEventTime()};
+
+    // Handle event based on action type.
+    switch (inputEvent.getActionMasked()) {
+        case AMOTION_EVENT_ACTION_DOWN: {
+            clearStrokeData();
+            incorporateNewGroundTruth(groundTruthPoint);
+            break;
+        }
+        case AMOTION_EVENT_ACTION_MOVE: {
+            incorporateNewGroundTruth(groundTruthPoint);
+            break;
+        }
+        case AMOTION_EVENT_ACTION_UP:
+        case AMOTION_EVENT_ACTION_CANCEL: {
+            // Only expect meaningful predictions when given at least two input points.
+            if (mRecentGroundTruthPoints.size() >= 2) {
+                computeAtomFields();
+                reportMetrics();
+                break;
+            }
+        }
+    }
+}
+
+// Adds new predictions to mRecentPredictions and maintains the invariant that elements are
+// sorted in ascending order of targetTimestamp.
+void MotionPredictorMetricsManager::onPredict(const MotionEvent& predictionEvent) {
+    for (size_t i = 0; i < predictionEvent.getHistorySize() + 1; ++i) {
+        // Convert MotionEvent to PredictionPoint.
+        const PointerCoords* coords =
+                predictionEvent.getHistoricalRawPointerCoords(/*pointerIndex=*/0, i);
+        LOG_ALWAYS_FATAL_IF(coords == nullptr);
+        const nsecs_t targetTimestamp = predictionEvent.getHistoricalEventTime(i);
+        mRecentPredictions.push_back(
+                PredictionPoint{{.position = Eigen::Vector2f{coords->getY(), coords->getX()},
+                                 .pressure =
+                                         predictionEvent.getHistoricalPressure(/*pointerIndex=*/0,
+                                                                               i)},
+                                .originTimestamp = mRecentGroundTruthPoints.back().timestamp,
+                                .targetTimestamp = targetTimestamp});
+    }
+
+    std::sort(mRecentPredictions.begin(), mRecentPredictions.end());
+}
+
+void MotionPredictorMetricsManager::clearStrokeData() {
+    mRecentGroundTruthPoints.clear();
+    mRecentPredictions.clear();
+    std::fill(mAggregatedMetrics.begin(), mAggregatedMetrics.end(), AggregatedStrokeMetrics{});
+    std::fill(mAtomFields.begin(), mAtomFields.end(), AtomFields{});
+}
+
+void MotionPredictorMetricsManager::incorporateNewGroundTruth(
+        const GroundTruthPoint& groundTruthPoint) {
+    // Note: this removes the oldest point if `mRecentGroundTruthPoints` is already at capacity.
+    mRecentGroundTruthPoints.pushBack(groundTruthPoint);
+
+    // Remove outdated predictions – those that can never be matched with the current or any future
+    // ground truth points. We use fuzzy association for the timestamps here, because ground truth
+    // and prediction timestamps may not be perfectly synchronized.
+    const nsecs_t fuzzy_association_time_delta = mPredictionInterval / 4;
+    const auto firstCurrentIt =
+            std::find_if(mRecentPredictions.begin(), mRecentPredictions.end(),
+                         [&groundTruthPoint,
+                          fuzzy_association_time_delta](const PredictionPoint& prediction) {
+                             return prediction.targetTimestamp >
+                                     groundTruthPoint.timestamp - fuzzy_association_time_delta;
+                         });
+    mRecentPredictions.erase(mRecentPredictions.begin(), firstCurrentIt);
+
+    // Fuzzily match the new ground truth's timestamp to recent predictions' targetTimestamp and
+    // update the corresponding metrics.
+    for (const PredictionPoint& prediction : mRecentPredictions) {
+        if ((prediction.targetTimestamp >
+             groundTruthPoint.timestamp - fuzzy_association_time_delta) &&
+            (prediction.targetTimestamp <
+             groundTruthPoint.timestamp + fuzzy_association_time_delta)) {
+            updateAggregatedMetrics(prediction);
+        }
+    }
+}
+
+void MotionPredictorMetricsManager::updateAggregatedMetrics(
+        const PredictionPoint& predictionPoint) {
+    if (mRecentGroundTruthPoints.size() < 2) {
+        return;
+    }
+
+    const GroundTruthPoint& latestGroundTruthPoint = mRecentGroundTruthPoints.back();
+    const GroundTruthPoint& previousGroundTruthPoint =
+            mRecentGroundTruthPoints[mRecentGroundTruthPoints.size() - 2];
+    // Calculate prediction error vector.
+    const Eigen::Vector2f groundTruthTrajectory =
+            latestGroundTruthPoint.position - previousGroundTruthPoint.position;
+    const Eigen::Vector2f predictionTrajectory =
+            predictionPoint.position - previousGroundTruthPoint.position;
+    const Eigen::Vector2f predictionError = predictionTrajectory - groundTruthTrajectory;
+
+    // By default, prediction error counts fully as both off-trajectory and along-trajectory error.
+    // This serves as the fallback when the two most recent ground truth points are equal.
+    const float predictionErrorNorm = predictionError.norm();
+    float alongTrajectoryError = predictionErrorNorm;
+    float offTrajectoryError = predictionErrorNorm;
+    if (groundTruthTrajectory.squaredNorm() > 0) {
+        // Rotate the prediction error vector by the angle of the ground truth trajectory vector.
+        // This yields a vector whose first component is the along-trajectory error and whose
+        // second component is the off-trajectory error.
+        const float theta = std::atan2(groundTruthTrajectory[1], groundTruthTrajectory[0]);
+        const Eigen::Vector2f rotatedPredictionError = Eigen::Rotation2Df(-theta) * predictionError;
+        alongTrajectoryError = rotatedPredictionError[0];
+        offTrajectoryError = rotatedPredictionError[1];
+    }
+
+    // Compute the multiple of mPredictionInterval nearest to the amount of time into the
+    // future being predicted. This serves as the time bucket index into mAggregatedMetrics.
+    const float timestampDeltaFloat =
+            static_cast<float>(predictionPoint.targetTimestamp - predictionPoint.originTimestamp);
+    const size_t tIndex =
+            static_cast<size_t>(std::round(timestampDeltaFloat / mPredictionInterval - 1));
+
+    // Aggregate values into "general errors".
+    mAggregatedMetrics[tIndex].alongTrajectoryErrorSum += alongTrajectoryError;
+    mAggregatedMetrics[tIndex].alongTrajectorySumSquaredErrors +=
+            alongTrajectoryError * alongTrajectoryError;
+    mAggregatedMetrics[tIndex].offTrajectorySumSquaredErrors +=
+            offTrajectoryError * offTrajectoryError;
+    const float pressureError = predictionPoint.pressure - latestGroundTruthPoint.pressure;
+    mAggregatedMetrics[tIndex].pressureSumSquaredErrors += pressureError * pressureError;
+    ++mAggregatedMetrics[tIndex].generalErrorsCount;
+
+    // Aggregate values into high-velocity metrics, if we are in one of the last two time buckets
+    // and the velocity is above the threshold. Velocity here is measured in pixels per second.
+    const float velocity = groundTruthTrajectory.norm() /
+            (static_cast<float>(latestGroundTruthPoint.timestamp -
+                                previousGroundTruthPoint.timestamp) /
+             NANOS_PER_SECOND);
+    if ((tIndex + 2 >= mMaxNumPredictions) && (velocity > HIGH_VELOCITY_THRESHOLD)) {
+        mAggregatedMetrics[tIndex].highVelocityAlongTrajectorySse +=
+                alongTrajectoryError * alongTrajectoryError;
+        mAggregatedMetrics[tIndex].highVelocityOffTrajectorySse +=
+                offTrajectoryError * offTrajectoryError;
+        ++mAggregatedMetrics[tIndex].highVelocityErrorsCount;
+    }
+
+    // Compute path length for scale-invariant errors.
+    float pathLength = 0;
+    for (size_t i = 1; i < mRecentGroundTruthPoints.size(); ++i) {
+        pathLength +=
+                (mRecentGroundTruthPoints[i].position - mRecentGroundTruthPoints[i - 1].position)
+                        .norm();
+    }
+    // Avoid overweighting errors at the beginning of a stroke: compute the path length as if there
+    // were a full ground truth history by filling in missing segments with the average length.
+    // Note: the "- 1" is needed to translate from number of endpoints to number of segments.
+    pathLength *= static_cast<float>(mRecentGroundTruthPoints.capacity() - 1) /
+            (mRecentGroundTruthPoints.size() - 1);
+    pathLength += PATH_LENGTH_EPSILON; // Ensure path length is nonzero (>= PATH_LENGTH_EPSILON).
+
+    // Compute and aggregate scale-invariant errors.
+    const float scaleInvariantAlongTrajectoryError = alongTrajectoryError / pathLength;
+    const float scaleInvariantOffTrajectoryError = offTrajectoryError / pathLength;
+    mAggregatedMetrics[tIndex].scaleInvariantAlongTrajectorySse +=
+            scaleInvariantAlongTrajectoryError * scaleInvariantAlongTrajectoryError;
+    mAggregatedMetrics[tIndex].scaleInvariantOffTrajectorySse +=
+            scaleInvariantOffTrajectoryError * scaleInvariantOffTrajectoryError;
+    ++mAggregatedMetrics[tIndex].scaleInvariantErrorsCount;
+}
+
+void MotionPredictorMetricsManager::computeAtomFields() {
+    for (size_t i = 0; i < mAggregatedMetrics.size(); ++i) {
+        if (mAggregatedMetrics[i].generalErrorsCount == 0) {
+            // We have not received data corresponding to metrics for this time bucket.
+            continue;
+        }
+
+        mAtomFields[i].deltaTimeBucketMilliseconds =
+                static_cast<int>(mPredictionInterval / NANOS_PER_MILLIS * (i + 1));
+
+        // Note: we need the "* 1000"s below because we report values in integral milli-units.
+
+        { // General errors: reported for every time bucket.
+            const float alongTrajectoryErrorMean = mAggregatedMetrics[i].alongTrajectoryErrorSum /
+                    mAggregatedMetrics[i].generalErrorsCount;
+            mAtomFields[i].alongTrajectoryErrorMeanMillipixels =
+                    static_cast<int>(alongTrajectoryErrorMean * 1000);
+
+            const float alongTrajectoryMse = mAggregatedMetrics[i].alongTrajectorySumSquaredErrors /
+                    mAggregatedMetrics[i].generalErrorsCount;
+            // Take the max with 0 to avoid negative values caused by numerical instability.
+            const float alongTrajectoryErrorVariance =
+                    std::max(0.0f,
+                             alongTrajectoryMse -
+                                     alongTrajectoryErrorMean * alongTrajectoryErrorMean);
+            const float alongTrajectoryErrorStd = std::sqrt(alongTrajectoryErrorVariance);
+            mAtomFields[i].alongTrajectoryErrorStdMillipixels =
+                    static_cast<int>(alongTrajectoryErrorStd * 1000);
+
+            LOG_ALWAYS_FATAL_IF(mAggregatedMetrics[i].offTrajectorySumSquaredErrors < 0,
+                                "mAggregatedMetrics[%zu].offTrajectorySumSquaredErrors = %f should "
+                                "not be negative",
+                                i, mAggregatedMetrics[i].offTrajectorySumSquaredErrors);
+            const float offTrajectoryRmse =
+                    std::sqrt(mAggregatedMetrics[i].offTrajectorySumSquaredErrors /
+                              mAggregatedMetrics[i].generalErrorsCount);
+            mAtomFields[i].offTrajectoryRmseMillipixels =
+                    static_cast<int>(offTrajectoryRmse * 1000);
+
+            LOG_ALWAYS_FATAL_IF(mAggregatedMetrics[i].pressureSumSquaredErrors < 0,
+                                "mAggregatedMetrics[%zu].pressureSumSquaredErrors = %f should not "
+                                "be negative",
+                                i, mAggregatedMetrics[i].pressureSumSquaredErrors);
+            const float pressureRmse = std::sqrt(mAggregatedMetrics[i].pressureSumSquaredErrors /
+                                                 mAggregatedMetrics[i].generalErrorsCount);
+            mAtomFields[i].pressureRmseMilliunits = static_cast<int>(pressureRmse * 1000);
+        }
+
+        // High-velocity errors: reported only for last two time buckets.
+        // Check if we are in one of the last two time buckets, and there is high-velocity data.
+        if ((i + 2 >= mMaxNumPredictions) && (mAggregatedMetrics[i].highVelocityErrorsCount > 0)) {
+            LOG_ALWAYS_FATAL_IF(mAggregatedMetrics[i].highVelocityAlongTrajectorySse < 0,
+                                "mAggregatedMetrics[%zu].highVelocityAlongTrajectorySse = %f "
+                                "should not be negative",
+                                i, mAggregatedMetrics[i].highVelocityAlongTrajectorySse);
+            const float alongTrajectoryRmse =
+                    std::sqrt(mAggregatedMetrics[i].highVelocityAlongTrajectorySse /
+                              mAggregatedMetrics[i].highVelocityErrorsCount);
+            mAtomFields[i].highVelocityAlongTrajectoryRmse =
+                    static_cast<int>(alongTrajectoryRmse * 1000);
+
+            LOG_ALWAYS_FATAL_IF(mAggregatedMetrics[i].highVelocityOffTrajectorySse < 0,
+                                "mAggregatedMetrics[%zu].highVelocityOffTrajectorySse = %f should "
+                                "not be negative",
+                                i, mAggregatedMetrics[i].highVelocityOffTrajectorySse);
+            const float offTrajectoryRmse =
+                    std::sqrt(mAggregatedMetrics[i].highVelocityOffTrajectorySse /
+                              mAggregatedMetrics[i].highVelocityErrorsCount);
+            mAtomFields[i].highVelocityOffTrajectoryRmse =
+                    static_cast<int>(offTrajectoryRmse * 1000);
+        }
+
+        // Scale-invariant errors: reported only for the last time bucket, where the values
+        // represent an average across all time buckets.
+        if (i + 1 == mMaxNumPredictions) {
+            // Compute error averages.
+            float alongTrajectoryRmseSum = 0;
+            float offTrajectoryRmseSum = 0;
+            for (size_t j = 0; j < mAggregatedMetrics.size(); ++j) {
+                // If we have general errors (checked above), we should always also have
+                // scale-invariant errors.
+                LOG_ALWAYS_FATAL_IF(mAggregatedMetrics[j].scaleInvariantErrorsCount == 0,
+                                    "mAggregatedMetrics[%zu].scaleInvariantErrorsCount is 0", j);
+
+                LOG_ALWAYS_FATAL_IF(mAggregatedMetrics[j].scaleInvariantAlongTrajectorySse < 0,
+                                    "mAggregatedMetrics[%zu].scaleInvariantAlongTrajectorySse = %f "
+                                    "should not be negative",
+                                    j, mAggregatedMetrics[j].scaleInvariantAlongTrajectorySse);
+                alongTrajectoryRmseSum +=
+                        std::sqrt(mAggregatedMetrics[j].scaleInvariantAlongTrajectorySse /
+                                  mAggregatedMetrics[j].scaleInvariantErrorsCount);
+
+                LOG_ALWAYS_FATAL_IF(mAggregatedMetrics[j].scaleInvariantOffTrajectorySse < 0,
+                                    "mAggregatedMetrics[%zu].scaleInvariantOffTrajectorySse = %f "
+                                    "should not be negative",
+                                    j, mAggregatedMetrics[j].scaleInvariantOffTrajectorySse);
+                offTrajectoryRmseSum +=
+                        std::sqrt(mAggregatedMetrics[j].scaleInvariantOffTrajectorySse /
+                                  mAggregatedMetrics[j].scaleInvariantErrorsCount);
+            }
+
+            const float averageAlongTrajectoryRmse =
+                    alongTrajectoryRmseSum / mAggregatedMetrics.size();
+            mAtomFields.back().scaleInvariantAlongTrajectoryRmse =
+                    static_cast<int>(averageAlongTrajectoryRmse * 1000);
+
+            const float averageOffTrajectoryRmse = offTrajectoryRmseSum / mAggregatedMetrics.size();
+            mAtomFields.back().scaleInvariantOffTrajectoryRmse =
+                    static_cast<int>(averageOffTrajectoryRmse * 1000);
+        }
+    }
+}
+
+void MotionPredictorMetricsManager::reportMetrics() {
+    // Report one atom for each time bucket.
+    for (size_t i = 0; i < mAtomFields.size(); ++i) {
+        // Call stats_write logging function only on Android targets (not supported on host).
+#ifdef __ANDROID__
+        android::stats::libinput::
+                stats_write(android::stats::libinput::STYLUS_PREDICTION_METRICS_REPORTED,
+                            /*stylus_vendor_id=*/0,
+                            /*stylus_product_id=*/0, mAtomFields[i].deltaTimeBucketMilliseconds,
+                            mAtomFields[i].alongTrajectoryErrorMeanMillipixels,
+                            mAtomFields[i].alongTrajectoryErrorStdMillipixels,
+                            mAtomFields[i].offTrajectoryRmseMillipixels,
+                            mAtomFields[i].pressureRmseMilliunits,
+                            mAtomFields[i].highVelocityAlongTrajectoryRmse,
+                            mAtomFields[i].highVelocityOffTrajectoryRmse,
+                            mAtomFields[i].scaleInvariantAlongTrajectoryRmse,
+                            mAtomFields[i].scaleInvariantOffTrajectoryRmse);
+#endif
+    }
+
+    // Set mock atom fields, if available.
+    if (mMockLoggedAtomFields != nullptr) {
+        *mMockLoggedAtomFields = mAtomFields;
+    }
+}
+
+} // namespace android
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index 86b996b..e7224ff 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -20,6 +20,7 @@
         "InputPublisherAndConsumer_test.cpp",
         "InputVerifier_test.cpp",
         "MotionPredictor_test.cpp",
+        "MotionPredictorMetricsManager_test.cpp",
         "RingBuffer_test.cpp",
         "TfLiteMotionPredictor_test.cpp",
         "TouchResampling_test.cpp",
@@ -52,13 +53,6 @@
             undefined: true,
         },
     },
-    target: {
-        host: {
-            sanitize: {
-                address: true,
-            },
-        },
-    },
     shared_libs: [
         "libbase",
         "libbinder",
@@ -77,6 +71,21 @@
         unit_test: true,
     },
     test_suites: ["device-tests"],
+    target: {
+        host: {
+            sanitize: {
+                address: true,
+            },
+        },
+        android: {
+            static_libs: [
+                // Stats logging library and its dependencies.
+                "libstatslog_libinput",
+                "libstatsbootstrap",
+                "android.os.statsbootstrap_aidl-cpp",
+            ],
+        },
+    },
 }
 
 // NOTE: This is a compile time test, and does not need to be
diff --git a/libs/input/tests/MotionPredictorMetricsManager_test.cpp b/libs/input/tests/MotionPredictorMetricsManager_test.cpp
new file mode 100644
index 0000000..b420a5a
--- /dev/null
+++ b/libs/input/tests/MotionPredictorMetricsManager_test.cpp
@@ -0,0 +1,972 @@
+/*
+ * Copyright 2023 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 <input/MotionPredictor.h>
+
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <numeric>
+#include <vector>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <input/InputEventBuilders.h>
+#include <utils/Timers.h> // for nsecs_t
+
+#include "Eigen/Core"
+#include "Eigen/Geometry"
+
+namespace android {
+namespace {
+
+using ::testing::FloatNear;
+using ::testing::Matches;
+
+using GroundTruthPoint = MotionPredictorMetricsManager::GroundTruthPoint;
+using PredictionPoint = MotionPredictorMetricsManager::PredictionPoint;
+using AtomFields = MotionPredictorMetricsManager::AtomFields;
+
+inline constexpr int NANOS_PER_MILLIS = 1'000'000;
+
+inline constexpr nsecs_t TEST_INITIAL_TIMESTAMP = 1'000'000'000;
+inline constexpr size_t TEST_MAX_NUM_PREDICTIONS = 5;
+inline constexpr nsecs_t TEST_PREDICTION_INTERVAL_NANOS = 12'500'000 / 3; // 1 / (240 hz)
+inline constexpr int NO_DATA_SENTINEL = MotionPredictorMetricsManager::NO_DATA_SENTINEL;
+
+// Parameters:
+//  • arg: Eigen::Vector2f
+//  • target: Eigen::Vector2f
+//  • epsilon: float
+MATCHER_P2(Vector2fNear, target, epsilon, "") {
+    return Matches(FloatNear(target[0], epsilon))(arg[0]) &&
+            Matches(FloatNear(target[1], epsilon))(arg[1]);
+}
+
+// Parameters:
+//  • arg: PredictionPoint
+//  • target: PredictionPoint
+//  • epsilon: float
+MATCHER_P2(PredictionPointNear, target, epsilon, "") {
+    if (!Matches(Vector2fNear(target.position, epsilon))(arg.position)) {
+        *result_listener << "Position mismatch. Actual: (" << arg.position[0] << ", "
+                         << arg.position[1] << "), expected: (" << target.position[0] << ", "
+                         << target.position[1] << ")";
+        return false;
+    }
+    if (!Matches(FloatNear(target.pressure, epsilon))(arg.pressure)) {
+        *result_listener << "Pressure mismatch. Actual: " << arg.pressure
+                         << ", expected: " << target.pressure;
+        return false;
+    }
+    if (arg.originTimestamp != target.originTimestamp) {
+        *result_listener << "Origin timestamp mismatch. Actual: " << arg.originTimestamp
+                         << ", expected: " << target.originTimestamp;
+        return false;
+    }
+    if (arg.targetTimestamp != target.targetTimestamp) {
+        *result_listener << "Target timestamp mismatch. Actual: " << arg.targetTimestamp
+                         << ", expected: " << target.targetTimestamp;
+        return false;
+    }
+    return true;
+}
+
+// --- Mathematical helper functions. ---
+
+template <typename T>
+T average(std::vector<T> values) {
+    return std::accumulate(values.begin(), values.end(), T{}) / static_cast<T>(values.size());
+}
+
+template <typename T>
+T standardDeviation(std::vector<T> values) {
+    T mean = average(values);
+    T accumulator = {};
+    for (const T value : values) {
+        accumulator += value * value - mean * mean;
+    }
+    // Take the max with 0 to avoid negative values caused by numerical instability.
+    return std::sqrt(std::max(T{}, accumulator) / static_cast<T>(values.size()));
+}
+
+template <typename T>
+T rmse(std::vector<T> errors) {
+    T sse = {};
+    for (const T error : errors) {
+        sse += error * error;
+    }
+    return std::sqrt(sse / static_cast<T>(errors.size()));
+}
+
+TEST(MathematicalHelperFunctionTest, Average) {
+    std::vector<float> values{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    EXPECT_EQ(5.5f, average(values));
+}
+
+TEST(MathematicalHelperFunctionTest, StandardDeviation) {
+    // https://www.calculator.net/standard-deviation-calculator.html?numberinputs=10%2C+12%2C+23%2C+23%2C+16%2C+23%2C+21%2C+16
+    std::vector<float> values{10, 12, 23, 23, 16, 23, 21, 16};
+    EXPECT_FLOAT_EQ(4.8989794855664f, standardDeviation(values));
+}
+
+TEST(MathematicalHelperFunctionTest, Rmse) {
+    std::vector<float> errors{1, 5, 7, 7, 8, 20};
+    EXPECT_FLOAT_EQ(9.899494937f, rmse(errors));
+}
+
+// --- MotionEvent-related helper functions. ---
+
+// Creates a MotionEvent corresponding to the given GroundTruthPoint.
+MotionEvent makeMotionEvent(const GroundTruthPoint& groundTruthPoint) {
+    // Build single pointer of type STYLUS, with coordinates from groundTruthPoint.
+    PointerBuilder pointerBuilder =
+            PointerBuilder(/*id=*/0, ToolType::STYLUS)
+                    .x(groundTruthPoint.position[1])
+                    .y(groundTruthPoint.position[0])
+                    .axis(AMOTION_EVENT_AXIS_PRESSURE, groundTruthPoint.pressure);
+    return MotionEventBuilder(/*action=*/AMOTION_EVENT_ACTION_MOVE,
+                              /*source=*/AINPUT_SOURCE_CLASS_POINTER)
+            .eventTime(groundTruthPoint.timestamp)
+            .pointer(pointerBuilder)
+            .build();
+}
+
+// Creates a MotionEvent corresponding to the given sequence of PredictionPoints.
+MotionEvent makeMotionEvent(const std::vector<PredictionPoint>& predictionPoints) {
+    // Build single pointer of type STYLUS, with coordinates from first prediction point.
+    PointerBuilder pointerBuilder =
+            PointerBuilder(/*id=*/0, ToolType::STYLUS)
+                    .x(predictionPoints[0].position[1])
+                    .y(predictionPoints[0].position[0])
+                    .axis(AMOTION_EVENT_AXIS_PRESSURE, predictionPoints[0].pressure);
+    MotionEvent predictionEvent =
+            MotionEventBuilder(
+                    /*action=*/AMOTION_EVENT_ACTION_MOVE, /*source=*/AINPUT_SOURCE_CLASS_POINTER)
+                    .eventTime(predictionPoints[0].targetTimestamp)
+                    .pointer(pointerBuilder)
+                    .build();
+    for (size_t i = 1; i < predictionPoints.size(); ++i) {
+        PointerCoords coords =
+                PointerBuilder(/*id=*/0, ToolType::STYLUS)
+                        .x(predictionPoints[i].position[1])
+                        .y(predictionPoints[i].position[0])
+                        .axis(AMOTION_EVENT_AXIS_PRESSURE, predictionPoints[i].pressure)
+                        .buildCoords();
+        predictionEvent.addSample(predictionPoints[i].targetTimestamp, &coords);
+    }
+    return predictionEvent;
+}
+
+// Creates a MotionEvent corresponding to a stylus lift (UP) ground truth event.
+MotionEvent makeLiftMotionEvent() {
+    return MotionEventBuilder(/*action=*/AMOTION_EVENT_ACTION_UP,
+                              /*source=*/AINPUT_SOURCE_CLASS_POINTER)
+            .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS))
+            .build();
+}
+
+TEST(MakeMotionEventTest, MakeGroundTruthMotionEvent) {
+    const GroundTruthPoint groundTruthPoint{{.position = Eigen::Vector2f(10.0f, 20.0f),
+                                             .pressure = 0.6f},
+                                            .timestamp = TEST_INITIAL_TIMESTAMP};
+    const MotionEvent groundTruthMotionEvent = makeMotionEvent(groundTruthPoint);
+
+    ASSERT_EQ(1u, groundTruthMotionEvent.getPointerCount());
+    // Note: a MotionEvent's "history size" is one less than its number of samples.
+    ASSERT_EQ(0u, groundTruthMotionEvent.getHistorySize());
+    EXPECT_EQ(groundTruthPoint.position[0], groundTruthMotionEvent.getRawPointerCoords(0)->getY());
+    EXPECT_EQ(groundTruthPoint.position[1], groundTruthMotionEvent.getRawPointerCoords(0)->getX());
+    EXPECT_EQ(groundTruthPoint.pressure,
+              groundTruthMotionEvent.getRawPointerCoords(0)->getAxisValue(
+                      AMOTION_EVENT_AXIS_PRESSURE));
+    EXPECT_EQ(AMOTION_EVENT_ACTION_MOVE, groundTruthMotionEvent.getAction());
+}
+
+TEST(MakeMotionEventTest, MakePredictionMotionEvent) {
+    const nsecs_t originTimestamp = TEST_INITIAL_TIMESTAMP;
+    const std::vector<PredictionPoint>
+            predictionPoints{{{.position = Eigen::Vector2f(10.0f, 20.0f), .pressure = 0.6f},
+                              .originTimestamp = originTimestamp,
+                              .targetTimestamp = originTimestamp + 5 * NANOS_PER_MILLIS},
+                             {{.position = Eigen::Vector2f(11.0f, 22.0f), .pressure = 0.5f},
+                              .originTimestamp = originTimestamp,
+                              .targetTimestamp = originTimestamp + 10 * NANOS_PER_MILLIS},
+                             {{.position = Eigen::Vector2f(12.0f, 24.0f), .pressure = 0.4f},
+                              .originTimestamp = originTimestamp,
+                              .targetTimestamp = originTimestamp + 15 * NANOS_PER_MILLIS}};
+    const MotionEvent predictionMotionEvent = makeMotionEvent(predictionPoints);
+
+    ASSERT_EQ(1u, predictionMotionEvent.getPointerCount());
+    // Note: a MotionEvent's "history size" is one less than its number of samples.
+    ASSERT_EQ(predictionPoints.size(), predictionMotionEvent.getHistorySize() + 1);
+    for (size_t i = 0; i < predictionPoints.size(); ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        const PointerCoords coords = *predictionMotionEvent.getHistoricalRawPointerCoords(
+                /*pointerIndex=*/0, /*historicalIndex=*/i);
+        EXPECT_EQ(predictionPoints[i].position[0], coords.getY());
+        EXPECT_EQ(predictionPoints[i].position[1], coords.getX());
+        EXPECT_EQ(predictionPoints[i].pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
+        // Note: originTimestamp is discarded when converting PredictionPoint to MotionEvent.
+        EXPECT_EQ(predictionPoints[i].targetTimestamp,
+                  predictionMotionEvent.getHistoricalEventTime(i));
+        EXPECT_EQ(AMOTION_EVENT_ACTION_MOVE, predictionMotionEvent.getAction());
+    }
+}
+
+TEST(MakeMotionEventTest, MakeLiftMotionEvent) {
+    const MotionEvent liftMotionEvent = makeLiftMotionEvent();
+    ASSERT_EQ(1u, liftMotionEvent.getPointerCount());
+    // Note: a MotionEvent's "history size" is one less than its number of samples.
+    ASSERT_EQ(0u, liftMotionEvent.getHistorySize());
+    EXPECT_EQ(AMOTION_EVENT_ACTION_UP, liftMotionEvent.getAction());
+}
+
+// --- Ground-truth-generation helper functions. ---
+
+std::vector<GroundTruthPoint> generateConstantGroundTruthPoints(
+        const GroundTruthPoint& groundTruthPoint, size_t numPoints) {
+    std::vector<GroundTruthPoint> groundTruthPoints;
+    nsecs_t timestamp = groundTruthPoint.timestamp;
+    for (size_t i = 0; i < numPoints; ++i) {
+        groundTruthPoints.emplace_back(groundTruthPoint);
+        groundTruthPoints.back().timestamp = timestamp;
+        timestamp += TEST_PREDICTION_INTERVAL_NANOS;
+    }
+    return groundTruthPoints;
+}
+
+// This function uses the coordinate system (y, x), with +y pointing downwards and +x pointing
+// rightwards. Angles are measured counterclockwise from down (+y).
+std::vector<GroundTruthPoint> generateCircularArcGroundTruthPoints(Eigen::Vector2f initialPosition,
+                                                                   float initialAngle,
+                                                                   float velocity,
+                                                                   float turningAngle,
+                                                                   size_t numPoints) {
+    std::vector<GroundTruthPoint> groundTruthPoints;
+    // Create first point.
+    if (numPoints > 0) {
+        groundTruthPoints.push_back({{.position = initialPosition, .pressure = 0.0f},
+                                     .timestamp = TEST_INITIAL_TIMESTAMP});
+    }
+    float trajectoryAngle = initialAngle; // measured counterclockwise from +y axis.
+    for (size_t i = 1; i < numPoints; ++i) {
+        const Eigen::Vector2f trajectory =
+                Eigen::Rotation2D(trajectoryAngle) * Eigen::Vector2f(1, 0);
+        groundTruthPoints.push_back(
+                {{.position = groundTruthPoints.back().position + velocity * trajectory,
+                  .pressure = 0.0f},
+                 .timestamp = groundTruthPoints.back().timestamp + TEST_PREDICTION_INTERVAL_NANOS});
+        trajectoryAngle += turningAngle;
+    }
+    return groundTruthPoints;
+}
+
+TEST(GenerateConstantGroundTruthPointsTest, BasicTest) {
+    const GroundTruthPoint groundTruthPoint{{.position = Eigen::Vector2f(10, 20), .pressure = 0.3f},
+                                            .timestamp = TEST_INITIAL_TIMESTAMP};
+    const std::vector<GroundTruthPoint> groundTruthPoints =
+            generateConstantGroundTruthPoints(groundTruthPoint, /*numPoints=*/3);
+
+    ASSERT_EQ(3u, groundTruthPoints.size());
+    // First point.
+    EXPECT_EQ(groundTruthPoints[0].position, groundTruthPoint.position);
+    EXPECT_EQ(groundTruthPoints[0].pressure, groundTruthPoint.pressure);
+    EXPECT_EQ(groundTruthPoints[0].timestamp, groundTruthPoint.timestamp);
+    // Second point.
+    EXPECT_EQ(groundTruthPoints[1].position, groundTruthPoint.position);
+    EXPECT_EQ(groundTruthPoints[1].pressure, groundTruthPoint.pressure);
+    EXPECT_GT(groundTruthPoints[1].timestamp, groundTruthPoints[0].timestamp);
+    // Third point.
+    EXPECT_EQ(groundTruthPoints[2].position, groundTruthPoint.position);
+    EXPECT_EQ(groundTruthPoints[2].pressure, groundTruthPoint.pressure);
+    EXPECT_GT(groundTruthPoints[2].timestamp, groundTruthPoints[1].timestamp);
+}
+
+TEST(GenerateCircularArcGroundTruthTest, StraightLineUpwards) {
+    const std::vector<GroundTruthPoint> groundTruthPoints = generateCircularArcGroundTruthPoints(
+            /*initialPosition=*/Eigen::Vector2f(0, 0),
+            /*initialAngle=*/M_PI,
+            /*velocity=*/1.0f,
+            /*turningAngle=*/0.0f,
+            /*numPoints=*/3);
+
+    ASSERT_EQ(3u, groundTruthPoints.size());
+    EXPECT_THAT(groundTruthPoints[0].position, Vector2fNear(Eigen::Vector2f(0, 0), 1e-6));
+    EXPECT_THAT(groundTruthPoints[1].position, Vector2fNear(Eigen::Vector2f(-1, 0), 1e-6));
+    EXPECT_THAT(groundTruthPoints[2].position, Vector2fNear(Eigen::Vector2f(-2, 0), 1e-6));
+    // Check that timestamps are increasing between consecutive ground truth points.
+    EXPECT_GT(groundTruthPoints[1].timestamp, groundTruthPoints[0].timestamp);
+    EXPECT_GT(groundTruthPoints[2].timestamp, groundTruthPoints[1].timestamp);
+}
+
+TEST(GenerateCircularArcGroundTruthTest, CounterclockwiseSquare) {
+    // Generate points in a counterclockwise unit square starting pointing right.
+    const std::vector<GroundTruthPoint> groundTruthPoints = generateCircularArcGroundTruthPoints(
+            /*initialPosition=*/Eigen::Vector2f(10, 100),
+            /*initialAngle=*/M_PI_2,
+            /*velocity=*/1.0f,
+            /*turningAngle=*/M_PI_2,
+            /*numPoints=*/5);
+
+    ASSERT_EQ(5u, groundTruthPoints.size());
+    EXPECT_THAT(groundTruthPoints[0].position, Vector2fNear(Eigen::Vector2f(10, 100), 1e-6));
+    EXPECT_THAT(groundTruthPoints[1].position, Vector2fNear(Eigen::Vector2f(10, 101), 1e-6));
+    EXPECT_THAT(groundTruthPoints[2].position, Vector2fNear(Eigen::Vector2f(9, 101), 1e-6));
+    EXPECT_THAT(groundTruthPoints[3].position, Vector2fNear(Eigen::Vector2f(9, 100), 1e-6));
+    EXPECT_THAT(groundTruthPoints[4].position, Vector2fNear(Eigen::Vector2f(10, 100), 1e-6));
+}
+
+// --- Prediction-generation helper functions. ---
+
+// Creates a sequence of predictions with values equal to those of the given GroundTruthPoint.
+std::vector<PredictionPoint> generateConstantPredictions(const GroundTruthPoint& groundTruthPoint) {
+    std::vector<PredictionPoint> predictions;
+    nsecs_t predictionTimestamp = groundTruthPoint.timestamp + TEST_PREDICTION_INTERVAL_NANOS;
+    for (size_t j = 0; j < TEST_MAX_NUM_PREDICTIONS; ++j) {
+        predictions.push_back(PredictionPoint{{.position = groundTruthPoint.position,
+                                               .pressure = groundTruthPoint.pressure},
+                                              .originTimestamp = groundTruthPoint.timestamp,
+                                              .targetTimestamp = predictionTimestamp});
+        predictionTimestamp += TEST_PREDICTION_INTERVAL_NANOS;
+    }
+    return predictions;
+}
+
+// Generates TEST_MAX_NUM_PREDICTIONS predictions from the given most recent two ground truth points
+// by linear extrapolation of position and pressure. The interval between consecutive predictions'
+// timestamps is TEST_PREDICTION_INTERVAL_NANOS.
+std::vector<PredictionPoint> generatePredictionsByLinearExtrapolation(
+        const GroundTruthPoint& firstGroundTruth, const GroundTruthPoint& secondGroundTruth) {
+    // Precompute deltas.
+    const Eigen::Vector2f trajectory = secondGroundTruth.position - firstGroundTruth.position;
+    const float deltaPressure = secondGroundTruth.pressure - firstGroundTruth.pressure;
+    // Compute predictions.
+    std::vector<PredictionPoint> predictions;
+    Eigen::Vector2f predictionPosition = secondGroundTruth.position;
+    float predictionPressure = secondGroundTruth.pressure;
+    nsecs_t predictionTargetTimestamp = secondGroundTruth.timestamp;
+    for (size_t i = 0; i < TEST_MAX_NUM_PREDICTIONS; ++i) {
+        predictionPosition += trajectory;
+        predictionPressure += deltaPressure;
+        predictionTargetTimestamp += TEST_PREDICTION_INTERVAL_NANOS;
+        predictions.push_back(
+                PredictionPoint{{.position = predictionPosition, .pressure = predictionPressure},
+                                .originTimestamp = secondGroundTruth.timestamp,
+                                .targetTimestamp = predictionTargetTimestamp});
+    }
+    return predictions;
+}
+
+TEST(GeneratePredictionsTest, GenerateConstantPredictions) {
+    const GroundTruthPoint groundTruthPoint{{.position = Eigen::Vector2f(10, 20), .pressure = 0.3f},
+                                            .timestamp = TEST_INITIAL_TIMESTAMP};
+    const std::vector<PredictionPoint> predictionPoints =
+            generateConstantPredictions(groundTruthPoint);
+
+    ASSERT_EQ(TEST_MAX_NUM_PREDICTIONS, predictionPoints.size());
+    for (size_t i = 0; i < predictionPoints.size(); ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        EXPECT_THAT(predictionPoints[i].position, Vector2fNear(groundTruthPoint.position, 1e-6));
+        EXPECT_THAT(predictionPoints[i].pressure, FloatNear(groundTruthPoint.pressure, 1e-6));
+        EXPECT_EQ(predictionPoints[i].originTimestamp, groundTruthPoint.timestamp);
+        EXPECT_EQ(predictionPoints[i].targetTimestamp,
+                  groundTruthPoint.timestamp +
+                          static_cast<nsecs_t>(i + 1) * TEST_PREDICTION_INTERVAL_NANOS);
+    }
+}
+
+TEST(GeneratePredictionsTest, LinearExtrapolationFromTwoPoints) {
+    const nsecs_t initialTimestamp = TEST_INITIAL_TIMESTAMP;
+    const std::vector<PredictionPoint> predictionPoints = generatePredictionsByLinearExtrapolation(
+            GroundTruthPoint{{.position = Eigen::Vector2f(100, 200), .pressure = 0.9f},
+                             .timestamp = initialTimestamp},
+            GroundTruthPoint{{.position = Eigen::Vector2f(105, 190), .pressure = 0.8f},
+                             .timestamp = initialTimestamp + TEST_PREDICTION_INTERVAL_NANOS});
+
+    ASSERT_EQ(TEST_MAX_NUM_PREDICTIONS, predictionPoints.size());
+    const nsecs_t originTimestamp = initialTimestamp + TEST_PREDICTION_INTERVAL_NANOS;
+    EXPECT_THAT(predictionPoints[0],
+                PredictionPointNear(PredictionPoint{{.position = Eigen::Vector2f(110, 180),
+                                                     .pressure = 0.7f},
+                                                    .originTimestamp = originTimestamp,
+                                                    .targetTimestamp = originTimestamp +
+                                                            TEST_PREDICTION_INTERVAL_NANOS},
+                                    0.001));
+    EXPECT_THAT(predictionPoints[1],
+                PredictionPointNear(PredictionPoint{{.position = Eigen::Vector2f(115, 170),
+                                                     .pressure = 0.6f},
+                                                    .originTimestamp = originTimestamp,
+                                                    .targetTimestamp = originTimestamp +
+                                                            2 * TEST_PREDICTION_INTERVAL_NANOS},
+                                    0.001));
+    EXPECT_THAT(predictionPoints[2],
+                PredictionPointNear(PredictionPoint{{.position = Eigen::Vector2f(120, 160),
+                                                     .pressure = 0.5f},
+                                                    .originTimestamp = originTimestamp,
+                                                    .targetTimestamp = originTimestamp +
+                                                            3 * TEST_PREDICTION_INTERVAL_NANOS},
+                                    0.001));
+    EXPECT_THAT(predictionPoints[3],
+                PredictionPointNear(PredictionPoint{{.position = Eigen::Vector2f(125, 150),
+                                                     .pressure = 0.4f},
+                                                    .originTimestamp = originTimestamp,
+                                                    .targetTimestamp = originTimestamp +
+                                                            4 * TEST_PREDICTION_INTERVAL_NANOS},
+                                    0.001));
+    EXPECT_THAT(predictionPoints[4],
+                PredictionPointNear(PredictionPoint{{.position = Eigen::Vector2f(130, 140),
+                                                     .pressure = 0.3f},
+                                                    .originTimestamp = originTimestamp,
+                                                    .targetTimestamp = originTimestamp +
+                                                            5 * TEST_PREDICTION_INTERVAL_NANOS},
+                                    0.001));
+}
+
+// Generates predictions by linear extrapolation for each consecutive pair of ground truth points
+// (see the comment for the above function for further explanation). Returns a vector of vectors of
+// prediction points, where the first index is the source ground truth index, and the second is the
+// prediction target index.
+//
+// The returned vector has size equal to the input vector, and the first element of the returned
+// vector is always empty.
+std::vector<std::vector<PredictionPoint>> generateAllPredictionsByLinearExtrapolation(
+        const std::vector<GroundTruthPoint>& groundTruthPoints) {
+    std::vector<std::vector<PredictionPoint>> allPredictions;
+    allPredictions.emplace_back();
+    for (size_t i = 1; i < groundTruthPoints.size(); ++i) {
+        allPredictions.push_back(generatePredictionsByLinearExtrapolation(groundTruthPoints[i - 1],
+                                                                          groundTruthPoints[i]));
+    }
+    return allPredictions;
+}
+
+TEST(GeneratePredictionsTest, GenerateAllPredictions) {
+    const nsecs_t initialTimestamp = TEST_INITIAL_TIMESTAMP;
+    std::vector<GroundTruthPoint>
+            groundTruthPoints{GroundTruthPoint{{.position = Eigen::Vector2f(0, 0),
+                                                .pressure = 0.5f},
+                                               .timestamp = initialTimestamp},
+                              GroundTruthPoint{{.position = Eigen::Vector2f(1, -1),
+                                                .pressure = 0.51f},
+                                               .timestamp = initialTimestamp +
+                                                       2 * TEST_PREDICTION_INTERVAL_NANOS},
+                              GroundTruthPoint{{.position = Eigen::Vector2f(2, -2),
+                                                .pressure = 0.52f},
+                                               .timestamp = initialTimestamp +
+                                                       3 * TEST_PREDICTION_INTERVAL_NANOS}};
+
+    const std::vector<std::vector<PredictionPoint>> allPredictions =
+            generateAllPredictionsByLinearExtrapolation(groundTruthPoints);
+
+    // Check format of allPredictions data.
+    ASSERT_EQ(groundTruthPoints.size(), allPredictions.size());
+    EXPECT_TRUE(allPredictions[0].empty());
+    EXPECT_EQ(TEST_MAX_NUM_PREDICTIONS, allPredictions[1].size());
+    EXPECT_EQ(TEST_MAX_NUM_PREDICTIONS, allPredictions[2].size());
+
+    // Check positions of predictions generated from first pair of ground truth points.
+    EXPECT_THAT(allPredictions[1][0].position, Vector2fNear(Eigen::Vector2f(2, -2), 1e-9));
+    EXPECT_THAT(allPredictions[1][1].position, Vector2fNear(Eigen::Vector2f(3, -3), 1e-9));
+    EXPECT_THAT(allPredictions[1][2].position, Vector2fNear(Eigen::Vector2f(4, -4), 1e-9));
+    EXPECT_THAT(allPredictions[1][3].position, Vector2fNear(Eigen::Vector2f(5, -5), 1e-9));
+    EXPECT_THAT(allPredictions[1][4].position, Vector2fNear(Eigen::Vector2f(6, -6), 1e-9));
+
+    // Check pressures of predictions generated from first pair of ground truth points.
+    EXPECT_FLOAT_EQ(0.52f, allPredictions[1][0].pressure);
+    EXPECT_FLOAT_EQ(0.53f, allPredictions[1][1].pressure);
+    EXPECT_FLOAT_EQ(0.54f, allPredictions[1][2].pressure);
+    EXPECT_FLOAT_EQ(0.55f, allPredictions[1][3].pressure);
+    EXPECT_FLOAT_EQ(0.56f, allPredictions[1][4].pressure);
+}
+
+// --- Prediction error helper functions. ---
+
+struct GeneralPositionErrors {
+    float alongTrajectoryErrorMean;
+    float alongTrajectoryErrorStd;
+    float offTrajectoryRmse;
+};
+
+// Inputs:
+//  • Vector of ground truth points
+//  • Vector of vectors of prediction points, where the first index is the source ground truth
+//    index, and the second is the prediction target index.
+//
+// Returns a vector of GeneralPositionErrors, indexed by prediction time delta bucket.
+std::vector<GeneralPositionErrors> computeGeneralPositionErrors(
+        const std::vector<GroundTruthPoint>& groundTruthPoints,
+        const std::vector<std::vector<PredictionPoint>>& predictionPoints) {
+    // Aggregate errors by time bucket (prediction target index).
+    std::vector<GeneralPositionErrors> generalPostitionErrors;
+    for (size_t predictionTargetIndex = 0; predictionTargetIndex < TEST_MAX_NUM_PREDICTIONS;
+         ++predictionTargetIndex) {
+        std::vector<float> alongTrajectoryErrors;
+        std::vector<float> alongTrajectorySquaredErrors;
+        std::vector<float> offTrajectoryErrors;
+        for (size_t sourceGroundTruthIndex = 1; sourceGroundTruthIndex < groundTruthPoints.size();
+             ++sourceGroundTruthIndex) {
+            const size_t targetGroundTruthIndex =
+                    sourceGroundTruthIndex + predictionTargetIndex + 1;
+            // Only include errors for points with a ground truth value.
+            if (targetGroundTruthIndex < groundTruthPoints.size()) {
+                const Eigen::Vector2f trajectory =
+                        (groundTruthPoints[targetGroundTruthIndex].position -
+                         groundTruthPoints[targetGroundTruthIndex - 1].position)
+                                .normalized();
+                const Eigen::Vector2f orthogonalTrajectory =
+                        Eigen::Rotation2Df(M_PI_2) * trajectory;
+                const Eigen::Vector2f positionError =
+                        predictionPoints[sourceGroundTruthIndex][predictionTargetIndex].position -
+                        groundTruthPoints[targetGroundTruthIndex].position;
+                alongTrajectoryErrors.push_back(positionError.dot(trajectory));
+                alongTrajectorySquaredErrors.push_back(alongTrajectoryErrors.back() *
+                                                       alongTrajectoryErrors.back());
+                offTrajectoryErrors.push_back(positionError.dot(orthogonalTrajectory));
+            }
+        }
+        generalPostitionErrors.push_back(
+                {.alongTrajectoryErrorMean = average(alongTrajectoryErrors),
+                 .alongTrajectoryErrorStd = standardDeviation(alongTrajectoryErrors),
+                 .offTrajectoryRmse = rmse(offTrajectoryErrors)});
+    }
+    return generalPostitionErrors;
+}
+
+// Inputs:
+//  • Vector of ground truth points
+//  • Vector of vectors of prediction points, where the first index is the source ground truth
+//    index, and the second is the prediction target index.
+//
+// Returns a vector of pressure RMSEs, indexed by prediction time delta bucket.
+std::vector<float> computePressureRmses(
+        const std::vector<GroundTruthPoint>& groundTruthPoints,
+        const std::vector<std::vector<PredictionPoint>>& predictionPoints) {
+    // Aggregate errors by time bucket (prediction target index).
+    std::vector<float> pressureRmses;
+    for (size_t predictionTargetIndex = 0; predictionTargetIndex < TEST_MAX_NUM_PREDICTIONS;
+         ++predictionTargetIndex) {
+        std::vector<float> pressureErrors;
+        for (size_t sourceGroundTruthIndex = 1; sourceGroundTruthIndex < groundTruthPoints.size();
+             ++sourceGroundTruthIndex) {
+            const size_t targetGroundTruthIndex =
+                    sourceGroundTruthIndex + predictionTargetIndex + 1;
+            // Only include errors for points with a ground truth value.
+            if (targetGroundTruthIndex < groundTruthPoints.size()) {
+                pressureErrors.push_back(
+                        predictionPoints[sourceGroundTruthIndex][predictionTargetIndex].pressure -
+                        groundTruthPoints[targetGroundTruthIndex].pressure);
+            }
+        }
+        pressureRmses.push_back(rmse(pressureErrors));
+    }
+    return pressureRmses;
+}
+
+TEST(ErrorComputationHelperTest, ComputeGeneralPositionErrorsSimpleTest) {
+    std::vector<GroundTruthPoint> groundTruthPoints =
+            generateConstantGroundTruthPoints(GroundTruthPoint{{.position = Eigen::Vector2f(0, 0),
+                                                                .pressure = 0.0f},
+                                                               .timestamp = TEST_INITIAL_TIMESTAMP},
+                                              /*numPoints=*/TEST_MAX_NUM_PREDICTIONS + 2);
+    groundTruthPoints[3].position = Eigen::Vector2f(1, 0);
+    groundTruthPoints[4].position = Eigen::Vector2f(1, 1);
+    groundTruthPoints[5].position = Eigen::Vector2f(1, 3);
+    groundTruthPoints[6].position = Eigen::Vector2f(2, 3);
+
+    std::vector<std::vector<PredictionPoint>> predictionPoints =
+            generateAllPredictionsByLinearExtrapolation(groundTruthPoints);
+
+    // The generated predictions look like:
+    //
+    // |    Source  |         Target Ground Truth Index          |
+    // |     Index  |   2    |   3    |   4    |   5    |   6    |
+    // |------------|--------|--------|--------|--------|--------|
+    // |          1 | (0, 0) | (0, 0) | (0, 0) | (0, 0) | (0, 0) |
+    // |          2 |        | (0, 0) | (0, 0) | (0, 0) | (0, 0) |
+    // |          3 |        |        | (2, 0) | (3, 0) | (4, 0) |
+    // |          4 |        |        |        | (1, 2) | (1, 3) |
+    // |          5 |        |        |        |        | (1, 5) |
+    // |---------------------------------------------------------|
+    // |               Actual Ground Truth Values                |
+    // |  Position  | (0, 0) | (1, 0) | (1, 1) | (1, 3) | (2, 3) |
+    // |  Previous  | (0, 0) | (0, 0) | (1, 0) | (1, 1) | (1, 3) |
+    //
+    // Note: this table organizes prediction targets by target ground truth index. Metrics are
+    // aggregated across points with the same prediction time bucket index, which is different.
+    // Each down-right diagonal from this table gives us points from a unique time bucket.
+
+    // Initialize expected prediction errors from the table above. The first time bucket corresponds
+    // to the long diagonal of the table, and subsequent time buckets step up-right from there.
+    const std::vector<std::vector<float>> expectedAlongTrajectoryErrors{{0, -1, -1, -1, -1},
+                                                                        {-1, -1, -3, -1},
+                                                                        {-1, -3, 2},
+                                                                        {-3, -2},
+                                                                        {-2}};
+    const std::vector<std::vector<float>> expectedOffTrajectoryErrors{{0, 0, 1, 0, 2},
+                                                                      {0, 1, 2, 0},
+                                                                      {1, 1, 3},
+                                                                      {1, 3},
+                                                                      {3}};
+
+    std::vector<GeneralPositionErrors> generalPositionErrors =
+            computeGeneralPositionErrors(groundTruthPoints, predictionPoints);
+
+    ASSERT_EQ(TEST_MAX_NUM_PREDICTIONS, generalPositionErrors.size());
+    for (size_t i = 0; i < generalPositionErrors.size(); ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        EXPECT_FLOAT_EQ(average(expectedAlongTrajectoryErrors[i]),
+                        generalPositionErrors[i].alongTrajectoryErrorMean);
+        EXPECT_FLOAT_EQ(standardDeviation(expectedAlongTrajectoryErrors[i]),
+                        generalPositionErrors[i].alongTrajectoryErrorStd);
+        EXPECT_FLOAT_EQ(rmse(expectedOffTrajectoryErrors[i]),
+                        generalPositionErrors[i].offTrajectoryRmse);
+    }
+}
+
+TEST(ErrorComputationHelperTest, ComputePressureRmsesSimpleTest) {
+    // Generate ground truth points with pressures {0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5}.
+    // (We need TEST_MAX_NUM_PREDICTIONS + 2 to test all prediction time buckets.)
+    std::vector<GroundTruthPoint> groundTruthPoints =
+            generateConstantGroundTruthPoints(GroundTruthPoint{{.position = Eigen::Vector2f(0, 0),
+                                                                .pressure = 0.0f},
+                                                               .timestamp = TEST_INITIAL_TIMESTAMP},
+                                              /*numPoints=*/TEST_MAX_NUM_PREDICTIONS + 2);
+    for (size_t i = 4; i < groundTruthPoints.size(); ++i) {
+        groundTruthPoints[i].pressure = 0.5f;
+    }
+
+    std::vector<std::vector<PredictionPoint>> predictionPoints =
+            generateAllPredictionsByLinearExtrapolation(groundTruthPoints);
+
+    std::vector<float> pressureRmses = computePressureRmses(groundTruthPoints, predictionPoints);
+
+    ASSERT_EQ(TEST_MAX_NUM_PREDICTIONS, pressureRmses.size());
+    EXPECT_FLOAT_EQ(rmse(std::vector<float>{0.0f, 0.0f, -0.5f, 0.5f, 0.0f}), pressureRmses[0]);
+    EXPECT_FLOAT_EQ(rmse(std::vector<float>{0.0f, -0.5f, -0.5f, 1.0f}), pressureRmses[1]);
+    EXPECT_FLOAT_EQ(rmse(std::vector<float>{-0.5f, -0.5f, -0.5f}), pressureRmses[2]);
+    EXPECT_FLOAT_EQ(rmse(std::vector<float>{-0.5f, -0.5f}), pressureRmses[3]);
+    EXPECT_FLOAT_EQ(rmse(std::vector<float>{-0.5f}), pressureRmses[4]);
+}
+
+// --- MotionPredictorMetricsManager tests. ---
+
+// Helper function that instantiates a MetricsManager with the given mock logged AtomFields. Takes
+// vectors of ground truth and prediction points of the same length, and passes these points to the
+// MetricsManager. The format of these vectors is expected to be:
+//  • groundTruthPoints: chronologically-ordered ground truth points, with at least 2 elements.
+//  • predictionPoints: the first index points to a vector of predictions corresponding to the
+//    source ground truth point with the same index.
+//     - The first element should be empty, because there are not expected to be predictions until
+//       we have received 2 ground truth points.
+//     - The last element may be empty, because there will be no future ground truth points to
+//       associate with those predictions (if not empty, it will be ignored).
+//     - To test all prediction buckets, there should be at least TEST_MAX_NUM_PREDICTIONS non-empty
+//       prediction sets (that is, excluding the first and last). Thus, groundTruthPoints and
+//       predictionPoints should have size at least TEST_MAX_NUM_PREDICTIONS + 2.
+//
+// The passed-in outAtomFields will contain the logged AtomFields when the function returns.
+//
+// This function returns void so that it can use test assertions.
+void runMetricsManager(const std::vector<GroundTruthPoint>& groundTruthPoints,
+                       const std::vector<std::vector<PredictionPoint>>& predictionPoints,
+                       std::vector<AtomFields>& outAtomFields) {
+    MotionPredictorMetricsManager metricsManager(TEST_PREDICTION_INTERVAL_NANOS,
+                                                 TEST_MAX_NUM_PREDICTIONS);
+    metricsManager.setMockLoggedAtomFields(&outAtomFields);
+
+    // Validate structure of groundTruthPoints and predictionPoints.
+    ASSERT_EQ(predictionPoints.size(), groundTruthPoints.size());
+    ASSERT_GE(groundTruthPoints.size(), 2u);
+    ASSERT_EQ(predictionPoints[0].size(), 0u);
+    for (size_t i = 1; i + 1 < predictionPoints.size(); ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        ASSERT_EQ(predictionPoints[i].size(), TEST_MAX_NUM_PREDICTIONS);
+    }
+
+    // Pass ground truth points and predictions (for all except first and last ground truth).
+    for (size_t i = 0; i < groundTruthPoints.size(); ++i) {
+        metricsManager.onRecord(makeMotionEvent(groundTruthPoints[i]));
+        if ((i > 0) && (i + 1 < predictionPoints.size())) {
+            metricsManager.onPredict(makeMotionEvent(predictionPoints[i]));
+        }
+    }
+    // Send a stroke-end event to trigger the logging call.
+    metricsManager.onRecord(makeLiftMotionEvent());
+}
+
+// Vacuous test:
+//  • Input: no prediction data.
+//  • Expectation: no metrics should be logged.
+TEST(MotionPredictorMetricsManagerTest, NoPredictions) {
+    std::vector<AtomFields> mockLoggedAtomFields;
+    MotionPredictorMetricsManager metricsManager(TEST_PREDICTION_INTERVAL_NANOS,
+                                                 TEST_MAX_NUM_PREDICTIONS);
+    metricsManager.setMockLoggedAtomFields(&mockLoggedAtomFields);
+
+    metricsManager.onRecord(makeMotionEvent(
+            GroundTruthPoint{{.position = Eigen::Vector2f(0, 0), .pressure = 0}, .timestamp = 0}));
+    metricsManager.onRecord(makeLiftMotionEvent());
+
+    // Check that mockLoggedAtomFields is still empty (as it was initialized empty), ensuring that
+    // no metrics were logged.
+    EXPECT_EQ(0u, mockLoggedAtomFields.size());
+}
+
+// Perfect predictions test:
+//  • Input: constant input events, perfect predictions matching the input events.
+//  • Expectation: all error metrics should be zero, or NO_DATA_SENTINEL for "unreported" metrics.
+//    (For example, scale-invariant errors are only reported for the final time bucket.)
+TEST(MotionPredictorMetricsManagerTest, ConstantGroundTruthPerfectPredictions) {
+    GroundTruthPoint groundTruthPoint{{.position = Eigen::Vector2f(10.0f, 20.0f), .pressure = 0.6f},
+                                      .timestamp = TEST_INITIAL_TIMESTAMP};
+
+    // Generate ground truth and prediction points as described by the runMetricsManager comment.
+    std::vector<GroundTruthPoint> groundTruthPoints;
+    std::vector<std::vector<PredictionPoint>> predictionPoints;
+    for (size_t i = 0; i < TEST_MAX_NUM_PREDICTIONS + 2; ++i) {
+        groundTruthPoints.push_back(groundTruthPoint);
+        predictionPoints.push_back(i > 0 ? generateConstantPredictions(groundTruthPoint)
+                                         : std::vector<PredictionPoint>{});
+        groundTruthPoint.timestamp += TEST_PREDICTION_INTERVAL_NANOS;
+    }
+
+    std::vector<AtomFields> atomFields;
+    runMetricsManager(groundTruthPoints, predictionPoints, atomFields);
+
+    ASSERT_EQ(TEST_MAX_NUM_PREDICTIONS, atomFields.size());
+    // Check that errors are all zero, or NO_DATA_SENTINEL for unreported metrics.
+    for (size_t i = 0; i < atomFields.size(); ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        const AtomFields& atom = atomFields[i];
+        const nsecs_t deltaTimeBucketNanos = TEST_PREDICTION_INTERVAL_NANOS * (i + 1);
+        EXPECT_EQ(deltaTimeBucketNanos / NANOS_PER_MILLIS, atom.deltaTimeBucketMilliseconds);
+        // General errors: reported for every time bucket.
+        EXPECT_EQ(0, atom.alongTrajectoryErrorMeanMillipixels);
+        EXPECT_EQ(0, atom.alongTrajectoryErrorStdMillipixels);
+        EXPECT_EQ(0, atom.offTrajectoryRmseMillipixels);
+        EXPECT_EQ(0, atom.pressureRmseMilliunits);
+        // High-velocity errors: reported only for the last two time buckets.
+        // However, this data has zero velocity, so these metrics should all be NO_DATA_SENTINEL.
+        EXPECT_EQ(NO_DATA_SENTINEL, atom.highVelocityAlongTrajectoryRmse);
+        EXPECT_EQ(NO_DATA_SENTINEL, atom.highVelocityOffTrajectoryRmse);
+        // Scale-invariant errors: reported only for the last time bucket.
+        if (i + 1 == atomFields.size()) {
+            EXPECT_EQ(0, atom.scaleInvariantAlongTrajectoryRmse);
+            EXPECT_EQ(0, atom.scaleInvariantOffTrajectoryRmse);
+        } else {
+            EXPECT_EQ(NO_DATA_SENTINEL, atom.scaleInvariantAlongTrajectoryRmse);
+            EXPECT_EQ(NO_DATA_SENTINEL, atom.scaleInvariantOffTrajectoryRmse);
+        }
+    }
+}
+
+TEST(MotionPredictorMetricsManagerTest, QuadraticPressureLinearPredictions) {
+    // Generate ground truth points.
+    //
+    // Ground truth pressures are a quadratically increasing function from some initial value.
+    const float initialPressure = 0.5f;
+    const float quadraticCoefficient = 0.01f;
+    std::vector<GroundTruthPoint> groundTruthPoints;
+    nsecs_t timestamp = TEST_INITIAL_TIMESTAMP;
+    // As described in the runMetricsManager comment, we should have TEST_MAX_NUM_PREDICTIONS + 2
+    // ground truth points.
+    for (size_t i = 0; i < TEST_MAX_NUM_PREDICTIONS + 2; ++i) {
+        const float pressure = initialPressure + quadraticCoefficient * static_cast<float>(i * i);
+        groundTruthPoints.push_back(
+                GroundTruthPoint{{.position = Eigen::Vector2f(0, 0), .pressure = pressure},
+                                 .timestamp = timestamp});
+        timestamp += TEST_PREDICTION_INTERVAL_NANOS;
+    }
+
+    // Note: the first index is the source ground truth index, and the second is the prediction
+    // target index.
+    std::vector<std::vector<PredictionPoint>> predictionPoints =
+            generateAllPredictionsByLinearExtrapolation(groundTruthPoints);
+
+    const std::vector<float> pressureErrors =
+            computePressureRmses(groundTruthPoints, predictionPoints);
+
+    // Run test.
+    std::vector<AtomFields> atomFields;
+    runMetricsManager(groundTruthPoints, predictionPoints, atomFields);
+
+    // Check logged metrics match expectations.
+    ASSERT_EQ(TEST_MAX_NUM_PREDICTIONS, atomFields.size());
+    for (size_t i = 0; i < atomFields.size(); ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        const AtomFields& atom = atomFields[i];
+        // Check time bucket delta matches expectation based on index and prediction interval.
+        const nsecs_t deltaTimeBucketNanos = TEST_PREDICTION_INTERVAL_NANOS * (i + 1);
+        EXPECT_EQ(deltaTimeBucketNanos / NANOS_PER_MILLIS, atom.deltaTimeBucketMilliseconds);
+        // Check pressure error matches expectation.
+        EXPECT_NEAR(static_cast<int>(1000 * pressureErrors[i]), atom.pressureRmseMilliunits, 1);
+    }
+}
+
+TEST(MotionPredictorMetricsManagerTest, QuadraticPositionLinearPredictionsGeneralErrors) {
+    // Generate ground truth points.
+    //
+    // Each component of the ground truth positions are an independent quadratically increasing
+    // function from some initial value.
+    const Eigen::Vector2f initialPosition(200, 300);
+    const Eigen::Vector2f quadraticCoefficients(-2, 3);
+    std::vector<GroundTruthPoint> groundTruthPoints;
+    nsecs_t timestamp = TEST_INITIAL_TIMESTAMP;
+    // As described in the runMetricsManager comment, we should have TEST_MAX_NUM_PREDICTIONS + 2
+    // ground truth points.
+    for (size_t i = 0; i < TEST_MAX_NUM_PREDICTIONS + 2; ++i) {
+        const Eigen::Vector2f position =
+                initialPosition + quadraticCoefficients * static_cast<float>(i * i);
+        groundTruthPoints.push_back(
+                GroundTruthPoint{{.position = position, .pressure = 0.5}, .timestamp = timestamp});
+        timestamp += TEST_PREDICTION_INTERVAL_NANOS;
+    }
+
+    // Note: the first index is the source ground truth index, and the second is the prediction
+    // target index.
+    std::vector<std::vector<PredictionPoint>> predictionPoints =
+            generateAllPredictionsByLinearExtrapolation(groundTruthPoints);
+
+    std::vector<GeneralPositionErrors> generalPositionErrors =
+            computeGeneralPositionErrors(groundTruthPoints, predictionPoints);
+
+    // Run test.
+    std::vector<AtomFields> atomFields;
+    runMetricsManager(groundTruthPoints, predictionPoints, atomFields);
+
+    // Check logged metrics match expectations.
+    ASSERT_EQ(TEST_MAX_NUM_PREDICTIONS, atomFields.size());
+    for (size_t i = 0; i < atomFields.size(); ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        const AtomFields& atom = atomFields[i];
+        // Check time bucket delta matches expectation based on index and prediction interval.
+        const nsecs_t deltaTimeBucketNanos = TEST_PREDICTION_INTERVAL_NANOS * (i + 1);
+        EXPECT_EQ(deltaTimeBucketNanos / NANOS_PER_MILLIS, atom.deltaTimeBucketMilliseconds);
+        // Check general position errors match expectation.
+        EXPECT_NEAR(static_cast<int>(1000 * generalPositionErrors[i].alongTrajectoryErrorMean),
+                    atom.alongTrajectoryErrorMeanMillipixels, 1);
+        EXPECT_NEAR(static_cast<int>(1000 * generalPositionErrors[i].alongTrajectoryErrorStd),
+                    atom.alongTrajectoryErrorStdMillipixels, 1);
+        EXPECT_NEAR(static_cast<int>(1000 * generalPositionErrors[i].offTrajectoryRmse),
+                    atom.offTrajectoryRmseMillipixels, 1);
+    }
+}
+
+// Counterclockwise regular octagonal section test:
+//  • Input – ground truth: constantly-spaced input events starting at a trajectory pointing exactly
+//    rightwards, and rotating by 45° counterclockwise after each input.
+//  • Input – predictions: simple linear extrapolations of previous two ground truth points.
+//
+// The code below uses the following terminology to distinguish references to ground truth events:
+//  • Source ground truth: the most recent ground truth point received at the time the prediction
+//    was made.
+//  • Target ground truth: the ground truth event that the prediction was attempting to match.
+TEST(MotionPredictorMetricsManagerTest, CounterclockwiseOctagonGroundTruthLinearPredictions) {
+    // Select a stroke velocity that exceeds the high-velocity threshold of 1100 px/sec.
+    // For an input rate of 240 hz, 1100 px/sec * (1/240) sec/input ≈ 4.58 pixels per input.
+    const float strokeVelocity = 10; // pixels per input
+
+    // As described in the runMetricsManager comment, we should have TEST_MAX_NUM_PREDICTIONS + 2
+    // ground truth points.
+    std::vector<GroundTruthPoint> groundTruthPoints = generateCircularArcGroundTruthPoints(
+            /*initialPosition=*/Eigen::Vector2f(100, 100),
+            /*initialAngle=*/M_PI_2,
+            /*velocity=*/strokeVelocity,
+            /*turningAngle=*/-M_PI_4,
+            /*numPoints=*/TEST_MAX_NUM_PREDICTIONS + 2);
+
+    std::vector<std::vector<PredictionPoint>> predictionPoints =
+            generateAllPredictionsByLinearExtrapolation(groundTruthPoints);
+
+    std::vector<GeneralPositionErrors> generalPositionErrors =
+            computeGeneralPositionErrors(groundTruthPoints, predictionPoints);
+
+    // Run test.
+    std::vector<AtomFields> atomFields;
+    runMetricsManager(groundTruthPoints, predictionPoints, atomFields);
+
+    // Check logged metrics match expectations.
+    ASSERT_EQ(TEST_MAX_NUM_PREDICTIONS, atomFields.size());
+    for (size_t i = 0; i < atomFields.size(); ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        const AtomFields& atom = atomFields[i];
+        const nsecs_t deltaTimeBucketNanos = TEST_PREDICTION_INTERVAL_NANOS * (i + 1);
+        EXPECT_EQ(deltaTimeBucketNanos / NANOS_PER_MILLIS, atom.deltaTimeBucketMilliseconds);
+
+        // General errors: reported for every time bucket.
+        EXPECT_NEAR(static_cast<int>(1000 * generalPositionErrors[i].alongTrajectoryErrorMean),
+                    atom.alongTrajectoryErrorMeanMillipixels, 1);
+        // We allow for some floating point error in standard deviation (0.02 pixels).
+        EXPECT_NEAR(1000 * generalPositionErrors[i].alongTrajectoryErrorStd,
+                    atom.alongTrajectoryErrorStdMillipixels, 20);
+        // All position errors are equal, so the standard deviation should be approximately zero.
+        EXPECT_NEAR(0, atom.alongTrajectoryErrorStdMillipixels, 20);
+        // Absolute value for RMSE, since it must be non-negative.
+        EXPECT_NEAR(static_cast<int>(1000 * generalPositionErrors[i].offTrajectoryRmse),
+                    atom.offTrajectoryRmseMillipixels, 1);
+
+        // High-velocity errors: reported only for the last two time buckets.
+        //
+        // Since our input stroke velocity is chosen to be above the high-velocity threshold, all
+        // data contributes to high-velocity errors, and thus high-velocity errors should be equal
+        // to general errors (where reported).
+        //
+        // As above, use absolute value for RMSE, since it must be non-negative.
+        if (i + 2 >= atomFields.size()) {
+            EXPECT_NEAR(static_cast<int>(
+                                1000 * std::abs(generalPositionErrors[i].alongTrajectoryErrorMean)),
+                        atom.highVelocityAlongTrajectoryRmse, 1);
+            EXPECT_NEAR(static_cast<int>(1000 *
+                                         std::abs(generalPositionErrors[i].offTrajectoryRmse)),
+                        atom.highVelocityOffTrajectoryRmse, 1);
+        } else {
+            EXPECT_EQ(NO_DATA_SENTINEL, atom.highVelocityAlongTrajectoryRmse);
+            EXPECT_EQ(NO_DATA_SENTINEL, atom.highVelocityOffTrajectoryRmse);
+        }
+
+        // Scale-invariant errors: reported only for the last time bucket, where the reported value
+        // is the aggregation across all time buckets.
+        //
+        // The MetricsManager stores mMaxNumPredictions recent ground truth segments. Our ground
+        // truth segments here all have a length of strokeVelocity, so we can convert general errors
+        // to scale-invariant errors by dividing by `strokeVelocty * TEST_MAX_NUM_PREDICTIONS`.
+        //
+        // As above, use absolute value for RMSE, since it must be non-negative.
+        if (i + 1 == atomFields.size()) {
+            const float pathLength = strokeVelocity * TEST_MAX_NUM_PREDICTIONS;
+            std::vector<float> alongTrajectoryAbsoluteErrors;
+            std::vector<float> offTrajectoryAbsoluteErrors;
+            for (size_t j = 0; j < TEST_MAX_NUM_PREDICTIONS; ++j) {
+                alongTrajectoryAbsoluteErrors.push_back(
+                        std::abs(generalPositionErrors[j].alongTrajectoryErrorMean));
+                offTrajectoryAbsoluteErrors.push_back(
+                        std::abs(generalPositionErrors[j].offTrajectoryRmse));
+            }
+            EXPECT_NEAR(static_cast<int>(1000 * average(alongTrajectoryAbsoluteErrors) /
+                                         pathLength),
+                        atom.scaleInvariantAlongTrajectoryRmse, 1);
+            EXPECT_NEAR(static_cast<int>(1000 * average(offTrajectoryAbsoluteErrors) / pathLength),
+                        atom.scaleInvariantOffTrajectoryRmse, 1);
+        } else {
+            EXPECT_EQ(NO_DATA_SENTINEL, atom.scaleInvariantAlongTrajectoryRmse);
+            EXPECT_EQ(NO_DATA_SENTINEL, atom.scaleInvariantOffTrajectoryRmse);
+        }
+    }
+}
+
+} // namespace
+} // namespace android
