diff options
author | Cody Heiner <codyheiner@google.com> | 2023-11-14 14:47:10 -0800 |
---|---|---|
committer | Cody Heiner <codyheiner@google.com> | 2023-12-07 17:59:27 -0800 |
commit | 7b26dbea1d677b8d783f64ac1be23274898547ec (patch) | |
tree | 277cc4d130d720b752978f404f40d4d0535a0515 /include | |
parent | 192968f908e22a8c086481805382c438703c5f68 (diff) | |
download | native-7b26dbea1d677b8d783f64ac1be23274898547ec.tar.gz |
Pass all input events to MetricsManager
The MetricsManager needs to receive UP/CANCEL events to trigger
atom reporting. I must have moved these lines around during the
refactor and overlooked this mistake.
This change also modifies MotionPredictor and MetricsManager to
hold a "ReportAtomFunction" to facilitate testing.
Test: `statsd_testdrive 718` shows atoms reported with `adb shell setenforce 0`.
Test: `atest frameworks/native/libs/input/tests/MotionPredictor_test.cpp -c` passes.
Test: `atest frameworks/native/libs/input/tests/MotionPredictorMetricsManager_test.cpp -c` passes.
Bug: 311066949
Change-Id: Icbb709bbb7cf548512e0d9aa062783d554b857e3
Diffstat (limited to 'include')
-rw-r--r-- | include/input/MotionPredictor.h | 16 | ||||
-rw-r--r-- | include/input/MotionPredictorMetricsManager.h | 47 |
2 files changed, 35 insertions, 28 deletions
diff --git a/include/input/MotionPredictor.h b/include/input/MotionPredictor.h index 8797962886..3b6e40183f 100644 --- a/include/input/MotionPredictor.h +++ b/include/input/MotionPredictor.h @@ -19,6 +19,7 @@ #include <cstdint> #include <memory> #include <mutex> +#include <optional> #include <string> #include <unordered_map> @@ -57,20 +58,23 @@ static inline bool isMotionPredictionEnabled() { */ class MotionPredictor { public: + using ReportAtomFunction = MotionPredictorMetricsManager::ReportAtomFunction; + /** * Parameters: * predictionTimestampOffsetNanos: additional, constant shift to apply to the target * prediction time. The prediction will target the time t=(prediction time + * predictionTimestampOffsetNanos). * - * modelPath: filesystem path to a TfLiteMotionPredictorModel flatbuffer, or nullptr to use the - * default model path. - * - * checkEnableMotionPredition: the function to check whether the prediction should run. Used to + * checkEnableMotionPrediction: the function to check whether the prediction should run. Used to * provide an additional way of turning prediction on and off. Can be toggled at runtime. + * + * reportAtomFunction: the function that will be called to report prediction metrics. If + * omitted, the implementation will choose a default metrics reporting mechanism. */ MotionPredictor(nsecs_t predictionTimestampOffsetNanos, - std::function<bool()> checkEnableMotionPrediction = isMotionPredictionEnabled); + std::function<bool()> checkEnableMotionPrediction = isMotionPredictionEnabled, + ReportAtomFunction reportAtomFunction = {}); /** * Record the actual motion received by the view. This event will be used for calculating the @@ -95,6 +99,8 @@ private: std::optional<MotionEvent> mLastEvent; std::optional<MotionPredictorMetricsManager> mMetricsManager; + + const ReportAtomFunction mReportAtomFunction; }; } // namespace android diff --git a/include/input/MotionPredictorMetricsManager.h b/include/input/MotionPredictorMetricsManager.h index 12e50ba3b4..38472d8df7 100644 --- a/include/input/MotionPredictorMetricsManager.h +++ b/include/input/MotionPredictorMetricsManager.h @@ -18,7 +18,6 @@ #include <cstdint> #include <functional> #include <limits> -#include <optional> #include <vector> #include <input/Input.h> // for MotionEvent @@ -37,15 +36,33 @@ namespace android { * * This class stores AggregatedStrokeMetrics, updating them as new MotionEvents are passed in. When * onRecord receives an UP or CANCEL event, this indicates the end of the stroke, and the final - * AtomFields are computed and reported to the stats library. + * AtomFields are computed and reported to the stats library. The number of atoms reported is equal + * to the value of `maxNumPredictions` passed to the constructor. Each atom corresponds to one + * "prediction time bucket" — the amount of time into the future being predicted. * * If mMockLoggedAtomFields is set, the batch of AtomFields that are reported to the stats library * for one stroke are also stored in mMockLoggedAtomFields at the time they're reported. */ class MotionPredictorMetricsManager { public: - // Note: the MetricsManager assumes that the input interval equals the prediction interval. - MotionPredictorMetricsManager(nsecs_t predictionInterval, size_t maxNumPredictions); + struct AtomFields; + + using ReportAtomFunction = std::function<void(const AtomFields&)>; + + static void defaultReportAtomFunction(const AtomFields& atomFields); + + // Parameters: + // • predictionInterval: the time interval between successive prediction target timestamps. + // Note: the MetricsManager assumes that the input interval equals the prediction interval. + // • maxNumPredictions: the maximum number of distinct target timestamps the prediction model + // will generate predictions for. The MetricsManager reports this many atoms per stroke. + // • [Optional] reportAtomFunction: the function that will be called to report metrics. If + // omitted (or if an empty function is given), the `stats_write(…)` function from the Android + // stats library will be used. + MotionPredictorMetricsManager( + nsecs_t predictionInterval, + size_t maxNumPredictions, + ReportAtomFunction reportAtomFunction = defaultReportAtomFunction); // This method should be called once for each call to MotionPredictor::record, receiving the // forwarded MotionEvent argument. @@ -121,7 +138,7 @@ public: // magnitude makes it unobtainable in practice.) static const int NO_DATA_SENTINEL = std::numeric_limits<int32_t>::min(); - // Final metrics reported in the atom. + // Final metric values reported in the atom. struct AtomFields { int deltaTimeBucketMilliseconds = 0; @@ -140,15 +157,6 @@ public: int scaleInvariantOffTrajectoryRmse = NO_DATA_SENTINEL; // millipixels }; - // Allow tests to pass in a mock AtomFields pointer. - // - // When metrics are reported to the stats library on stroke end, they will also be written to - // mockLoggedAtomFields, overwriting existing data. The size of mockLoggedAtomFields will equal - // the number of calls to stats_write for that stroke. - void setMockLoggedAtomFields(std::vector<AtomFields>* mockLoggedAtomFields) { - mMockLoggedAtomFields = mockLoggedAtomFields; - } - private: // The interval between consecutive predictions' target timestamps. We assume that the input // interval also equals this value. @@ -172,11 +180,7 @@ private: std::vector<AggregatedStrokeMetrics> mAggregatedMetrics; std::vector<AtomFields> mAtomFields; - // Non-owning pointer to the location of mock AtomFields. If present, will be filled with the - // values reported to stats_write on each batch of reported metrics. - // - // This pointer must remain valid as long as the MotionPredictorMetricsManager exists. - std::vector<AtomFields>* mMockLoggedAtomFields = nullptr; + const ReportAtomFunction mReportAtomFunction; // Helper methods for the implementation of onRecord and onPredict. @@ -196,10 +200,7 @@ private: // Computes the atom fields to mAtomFields from the values in mAggregatedMetrics. void computeAtomFields(); - // Reports the metrics given by the current data in mAtomFields: - // • If on an Android device, reports the metrics to stats_write. - // • If mMockLoggedAtomFields is present, it will be overwritten with logged metrics, with one - // AtomFields element per call to stats_write. + // Reports the current data in mAtomFields by calling mReportAtomFunction. void reportMetrics(); }; |