Use vector instead of VLA in solveLeastSquares

For simpler tracking of the sizes of the arrays, use vector instead of
VLA. Also, VLA is not part of c++ standard. It's also being removed from
the kernel code.

Bug: 167946721
Test: atest libinput_tests
Change-Id: I03e5ad934bc3d9f451c76d0415c6a1254ec0053a
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index be1a33d..a44f0b7 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -416,13 +416,15 @@
  * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares
  * http://en.wikipedia.org/wiki/Gram-Schmidt
  */
-static bool solveLeastSquares(const float* x, const float* y,
-        const float* w, uint32_t m, uint32_t n, float* outB, float* outDet) {
+static bool solveLeastSquares(const std::vector<float>& x, const std::vector<float>& y,
+                              const std::vector<float>& w, uint32_t n, float* outB, float* outDet) {
+    const size_t m = x.size();
 #if DEBUG_STRATEGY
     ALOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s, w=%s", int(m), int(n),
             vectorToString(x, m).c_str(), vectorToString(y, m).c_str(),
             vectorToString(w, m).c_str());
 #endif
+    LOG_ALWAYS_FATAL_IF(m != y.size() || m != w.size(), "Mismatched vector sizes");
 
     // Expand the X vector to a matrix A, pre-multiplied by the weights.
     float a[n][m]; // column-major order
@@ -539,7 +541,9 @@
  * the default implementation
  */
 static std::optional<std::array<float, 3>> solveUnweightedLeastSquaresDeg2(
-        const float* x, const float* y, size_t count) {
+        const std::vector<float>& x, const std::vector<float>& y) {
+    const size_t count = x.size();
+    LOG_ALWAYS_FATAL_IF(count != y.size(), "Mismatching array sizes");
     // Solving y = a*x^2 + b*x + c
     float sxi = 0, sxiyi = 0, syi = 0, sxi2 = 0, sxi3 = 0, sxi2yi = 0, sxi4 = 0;
 
@@ -591,11 +595,11 @@
     outEstimator->clear();
 
     // Iterate over movement samples in reverse time order and collect samples.
-    float x[HISTORY_SIZE];
-    float y[HISTORY_SIZE];
-    float w[HISTORY_SIZE];
-    float time[HISTORY_SIZE];
-    uint32_t m = 0;
+    std::vector<float> x;
+    std::vector<float> y;
+    std::vector<float> w;
+    std::vector<float> time;
+
     uint32_t index = mIndex;
     const Movement& newestMovement = mMovements[mIndex];
     do {
@@ -610,13 +614,14 @@
         }
 
         const VelocityTracker::Position& position = movement.getPosition(id);
-        x[m] = position.x;
-        y[m] = position.y;
-        w[m] = chooseWeight(index);
-        time[m] = -age * 0.000000001f;
+        x.push_back(position.x);
+        y.push_back(position.y);
+        w.push_back(chooseWeight(index));
+        time.push_back(-age * 0.000000001f);
         index = (index == 0 ? HISTORY_SIZE : index) - 1;
-    } while (++m < HISTORY_SIZE);
+    } while (x.size() < HISTORY_SIZE);
 
+    const size_t m = x.size();
     if (m == 0) {
         return false; // no data
     }
@@ -629,8 +634,8 @@
 
     if (degree == 2 && mWeighting == WEIGHTING_NONE) {
         // Optimize unweighted, quadratic polynomial fit
-        std::optional<std::array<float, 3>> xCoeff = solveUnweightedLeastSquaresDeg2(time, x, m);
-        std::optional<std::array<float, 3>> yCoeff = solveUnweightedLeastSquaresDeg2(time, y, m);
+        std::optional<std::array<float, 3>> xCoeff = solveUnweightedLeastSquaresDeg2(time, x);
+        std::optional<std::array<float, 3>> yCoeff = solveUnweightedLeastSquaresDeg2(time, y);
         if (xCoeff && yCoeff) {
             outEstimator->time = newestMovement.eventTime;
             outEstimator->degree = 2;
@@ -645,8 +650,8 @@
         // General case for an Nth degree polynomial fit
         float xdet, ydet;
         uint32_t n = degree + 1;
-        if (solveLeastSquares(time, x, w, m, n, outEstimator->xCoeff, &xdet)
-                && solveLeastSquares(time, y, w, m, n, outEstimator->yCoeff, &ydet)) {
+        if (solveLeastSquares(time, x, w, n, outEstimator->xCoeff, &xdet) &&
+            solveLeastSquares(time, y, w, n, outEstimator->yCoeff, &ydet)) {
             outEstimator->time = newestMovement.eventTime;
             outEstimator->degree = degree;
             outEstimator->confidence = xdet * ydet;