Store pointers in vector inside MotionEntry

For better support of arbitrary number of pointers, and for easier
interfacing with the rest of the system, convert MotionEntry to use
std::vector for PointerCoords and PointerProperties.

Bug: 211379801
Test: TEST=inputflinger_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST
Change-Id: I91b4a88ec5df3f017ade8a6e55be3d3c1281de75
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index fa8f548..30e6802 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -215,8 +215,8 @@
                          int32_t buttonState, MotionClassification classification,
                          int32_t edgeFlags, float xPrecision, float yPrecision,
                          float xCursorPosition, float yCursorPosition, nsecs_t downTime,
-                         uint32_t pointerCount, const PointerProperties* pointerProperties,
-                         const PointerCoords* pointerCoords)
+                         const std::vector<PointerProperties>& pointerProperties,
+                         const std::vector<PointerCoords>& pointerCoords)
       : EventEntry(id, Type::MOTION, eventTime, policyFlags),
         deviceId(deviceId),
         source(source),
@@ -233,12 +233,8 @@
         xCursorPosition(xCursorPosition),
         yCursorPosition(yCursorPosition),
         downTime(downTime),
-        pointerCount(pointerCount) {
-    for (uint32_t i = 0; i < pointerCount; i++) {
-        this->pointerProperties[i] = pointerProperties[i];
-        this->pointerCoords[i] = pointerCoords[i];
-    }
-}
+        pointerProperties(pointerProperties),
+        pointerCoords(pointerCoords) {}
 
 MotionEntry::~MotionEntry() {}
 
@@ -258,7 +254,7 @@
                         buttonState, motionClassificationToString(classification), edgeFlags,
                         xPrecision, yPrecision, xCursorPosition, yCursorPosition);
 
-    for (uint32_t i = 0; i < pointerCount; i++) {
+    for (uint32_t i = 0; i < getPointerCount(); i++) {
         if (i) {
             msg += ", ";
         }
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 98e2507..b341784 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -175,16 +175,18 @@
     float xCursorPosition;
     float yCursorPosition;
     nsecs_t downTime;
-    uint32_t pointerCount;
-    PointerProperties pointerProperties[MAX_POINTERS];
-    PointerCoords pointerCoords[MAX_POINTERS];
+    std::vector<PointerProperties> pointerProperties;
+    std::vector<PointerCoords> pointerCoords;
+
+    size_t getPointerCount() const { return pointerProperties.size(); }
 
     MotionEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
                 uint32_t policyFlags, int32_t action, int32_t actionButton, int32_t flags,
                 int32_t metaState, int32_t buttonState, MotionClassification classification,
                 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
-                float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
-                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
+                float yCursorPosition, nsecs_t downTime,
+                const std::vector<PointerProperties>& pointerProperties,
+                const std::vector<PointerCoords>& pointerCoords);
     std::string getDescription() const override;
 
     ~MotionEntry() override;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index d0a72ee..45649dd 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -365,7 +365,7 @@
     const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
 
     std::vector<PointerCoords> pointerCoords;
-    pointerCoords.resize(motionEntry.pointerCount);
+    pointerCoords.resize(motionEntry.getPointerCount());
 
     // Use the first pointer information to normalize all other pointers. This could be any pointer
     // as long as all other pointers are normalized to the same value and the final DispatchEntry
@@ -375,7 +375,7 @@
     ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
 
     // Iterate through all pointers in the event to normalize against the first.
-    for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
+    for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount(); pointerIndex++) {
         const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
         uint32_t pointerId = uint32_t(pointerProperties.id);
         const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
@@ -399,8 +399,7 @@
                                           motionEntry.edgeFlags, motionEntry.xPrecision,
                                           motionEntry.yPrecision, motionEntry.xCursorPosition,
                                           motionEntry.yCursorPosition, motionEntry.downTime,
-                                          motionEntry.pointerCount, motionEntry.pointerProperties,
-                                          pointerCoords.data());
+                                          motionEntry.pointerProperties, pointerCoords);
 
     if (motionEntry.injectionState) {
         combinedMotionEntry->injectionState = motionEntry.injectionState;
@@ -2000,7 +1999,7 @@
               entry.metaState, entry.buttonState, entry.edgeFlags, entry.xPrecision,
               entry.yPrecision, entry.downTime);
 
-        for (uint32_t i = 0; i < entry.pointerCount; i++) {
+        for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
             ALOGD("  Pointer %d: id=%d, toolType=%s, "
                   "x=%f, y=%f, pressure=%f, size=%f, "
                   "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
@@ -2514,7 +2513,7 @@
         addDragEventLocked(entry);
 
         // Check whether touches should slip outside of the current foreground window.
-        if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
+        if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 &&
             tempTouchState.isSlippery()) {
             const auto [x, y] = resolveTouchedPosition(entry);
             const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0);
@@ -2793,14 +2792,14 @@
 
     // Find the pointer index by id.
     int32_t pointerIndex = 0;
-    for (; static_cast<uint32_t>(pointerIndex) < entry.pointerCount; pointerIndex++) {
+    for (; static_cast<uint32_t>(pointerIndex) < entry.getPointerCount(); pointerIndex++) {
         const PointerProperties& pointerProperties = entry.pointerProperties[pointerIndex];
         if (pointerProperties.id == mDragState->pointerId) {
             break;
         }
     }
 
-    if (uint32_t(pointerIndex) == entry.pointerCount) {
+    if (uint32_t(pointerIndex) == entry.getPointerCount()) {
         LOG_ALWAYS_FATAL("Should find a valid pointer index by id %d", mDragState->pointerId);
     }
 
@@ -3225,7 +3224,7 @@
                             ftl::enum_string(eventEntry->type).c_str());
 
         const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
-        if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
+        if (inputTarget.pointerIds.count() != originalMotionEntry.getPointerCount()) {
             if (!inputTarget.firstDownTimeInTarget.has_value()) {
                 logDispatchStateLocked();
                 LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
@@ -3537,14 +3536,14 @@
     const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
 
     PointerCoords scaledCoords[MAX_POINTERS];
-    const PointerCoords* usingCoords = motionEntry.pointerCoords;
+    const PointerCoords* usingCoords = motionEntry.pointerCoords.data();
 
     // Set the X and Y offset and X and Y scale depending on the input source.
     if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
         !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
         float globalScaleFactor = dispatchEntry.globalScaleFactor;
         if (globalScaleFactor != 1.0f) {
-            for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
+            for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
                 scaledCoords[i] = motionEntry.pointerCoords[i];
                 // Don't apply window scale here since we don't want scale to affect raw
                 // coordinates. The scale will be sent back to the client and applied
@@ -3555,7 +3554,7 @@
         }
     } else if (dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS)) {
         // We don't want the dispatch target to know the coordinates
-        for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
+        for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
             scaledCoords[i].clear();
         }
         usingCoords = scaledCoords;
@@ -3575,7 +3574,7 @@
                                 motionEntry.yPrecision, motionEntry.xCursorPosition,
                                 motionEntry.yCursorPosition, dispatchEntry.rawTransform,
                                 motionEntry.downTime, motionEntry.eventTime,
-                                motionEntry.pointerCount, motionEntry.pointerProperties,
+                                motionEntry.getPointerCount(), motionEntry.pointerProperties.data(),
                                 usingCoords);
 }
 
@@ -3991,7 +3990,7 @@
                         : std::nullopt;
                 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
                     std::bitset<MAX_POINTER_ID + 1> pointerIds;
-                    for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount;
+                    for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
                          pointerIndex++) {
                         pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
                     }
@@ -4066,7 +4065,7 @@
                 const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry);
                 if (windowHandle != nullptr) {
                     std::bitset<MAX_POINTER_ID + 1> pointerIds;
-                    for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount;
+                    for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
                          pointerIndex++) {
                         pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
                     }
@@ -4127,10 +4126,10 @@
     ALOG_ASSERT(pointerIds.any());
 
     uint32_t splitPointerIndexMap[MAX_POINTERS];
-    PointerProperties splitPointerProperties[MAX_POINTERS];
-    PointerCoords splitPointerCoords[MAX_POINTERS];
+    std::vector<PointerProperties> splitPointerProperties;
+    std::vector<PointerCoords> splitPointerCoords;
 
-    uint32_t originalPointerCount = originalMotionEntry.pointerCount;
+    uint32_t originalPointerCount = originalMotionEntry.getPointerCount();
     uint32_t splitPointerCount = 0;
 
     for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
@@ -4140,9 +4139,8 @@
         uint32_t pointerId = uint32_t(pointerProperties.id);
         if (pointerIds.test(pointerId)) {
             splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
-            splitPointerProperties[splitPointerCount] = pointerProperties;
-            splitPointerCoords[splitPointerCount] =
-                    originalMotionEntry.pointerCoords[originalPointerIndex];
+            splitPointerProperties.push_back(pointerProperties);
+            splitPointerCoords.push_back(originalMotionEntry.pointerCoords[originalPointerIndex]);
             splitPointerCount += 1;
         }
     }
@@ -4217,8 +4215,7 @@
                                           originalMotionEntry.yPrecision,
                                           originalMotionEntry.xCursorPosition,
                                           originalMotionEntry.yCursorPosition, splitDownTime,
-                                          splitPointerCount, splitPointerProperties,
-                                          splitPointerCoords);
+                                          splitPointerProperties, splitPointerCoords);
 
     if (originalMotionEntry.injectionState) {
         splitMotionEntry->injectionState = originalMotionEntry.injectionState;
@@ -4437,9 +4434,8 @@
                                               args.buttonState, args.classification, args.edgeFlags,
                                               args.xPrecision, args.yPrecision,
                                               args.xCursorPosition, args.yCursorPosition,
-                                              args.downTime, args.getPointerCount(),
-                                              args.pointerProperties.data(),
-                                              args.pointerCoords.data());
+                                              args.downTime, args.pointerProperties,
+                                              args.pointerCoords);
 
         if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
             IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
@@ -4653,6 +4649,11 @@
 
             mLock.lock();
             const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
+            const size_t pointerCount = motionEvent.getPointerCount();
+            const std::vector<PointerProperties>
+                    pointerProperties(motionEvent.getPointerProperties(),
+                                      motionEvent.getPointerProperties() + pointerCount);
+
             const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
             std::unique_ptr<MotionEntry> injectedEntry =
                     std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
@@ -4667,33 +4668,28 @@
                                                   motionEvent.getYPrecision(),
                                                   motionEvent.getRawXCursorPosition(),
                                                   motionEvent.getRawYCursorPosition(),
-                                                  motionEvent.getDownTime(),
-                                                  motionEvent.getPointerCount(),
-                                                  motionEvent.getPointerProperties(),
-                                                  samplePointerCoords);
+                                                  motionEvent.getDownTime(), pointerProperties,
+                                                  std::vector<PointerCoords>(samplePointerCoords,
+                                                                             samplePointerCoords +
+                                                                                     pointerCount));
             transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
             injectedEntries.push(std::move(injectedEntry));
             for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
                 sampleEventTimes += 1;
                 samplePointerCoords += motionEvent.getPointerCount();
-                std::unique_ptr<MotionEntry> nextInjectedEntry =
-                        std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
-                                                      resolvedDeviceId, motionEvent.getSource(),
-                                                      displayId, policyFlags,
-                                                      motionEvent.getAction(),
-                                                      motionEvent.getActionButton(), flags,
-                                                      motionEvent.getMetaState(),
-                                                      motionEvent.getButtonState(),
-                                                      motionEvent.getClassification(),
-                                                      motionEvent.getEdgeFlags(),
-                                                      motionEvent.getXPrecision(),
-                                                      motionEvent.getYPrecision(),
-                                                      motionEvent.getRawXCursorPosition(),
-                                                      motionEvent.getRawYCursorPosition(),
-                                                      motionEvent.getDownTime(),
-                                                      motionEvent.getPointerCount(),
-                                                      motionEvent.getPointerProperties(),
-                                                      samplePointerCoords);
+                std::unique_ptr<MotionEntry> nextInjectedEntry = std::make_unique<
+                        MotionEntry>(motionEvent.getId(), *sampleEventTimes, resolvedDeviceId,
+                                     motionEvent.getSource(), displayId, policyFlags,
+                                     motionEvent.getAction(), motionEvent.getActionButton(), flags,
+                                     motionEvent.getMetaState(), motionEvent.getButtonState(),
+                                     motionEvent.getClassification(), motionEvent.getEdgeFlags(),
+                                     motionEvent.getXPrecision(), motionEvent.getYPrecision(),
+                                     motionEvent.getRawXCursorPosition(),
+                                     motionEvent.getRawYCursorPosition(), motionEvent.getDownTime(),
+                                     pointerProperties,
+                                     std::vector<PointerCoords>(samplePointerCoords,
+                                                                samplePointerCoords +
+                                                                        pointerCount));
                 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
                                                        motionEvent.getTransform());
                 injectedEntries.push(std::move(nextInjectedEntry));
@@ -4872,7 +4868,7 @@
         entry.xCursorPosition = cursor.x;
         entry.yCursorPosition = cursor.y;
     }
-    for (uint32_t i = 0; i < entry.pointerCount; i++) {
+    for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
         entry.pointerCoords[i] =
                 MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
                                                         entry.pointerCoords[i]);
diff --git a/services/inputflinger/dispatcher/InputState.cpp b/services/inputflinger/dispatcher/InputState.cpp
index 57a6336..b348808 100644
--- a/services/inputflinger/dispatcher/InputState.cpp
+++ b/services/inputflinger/dispatcher/InputState.cpp
@@ -238,7 +238,7 @@
     pointerProperties.clear();
     pointerCoords.clear();
 
-    for (uint32_t i = 0; i < entry.pointerCount; i++) {
+    for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
         if (MotionEvent::getActionMasked(entry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
             // In POINTER_UP events, the pointer is leaving. Since the action is not stored,
             // this departing pointer should not be recorded.
@@ -300,9 +300,8 @@
                                                       memento.xPrecision, memento.yPrecision,
                                                       memento.xCursorPosition,
                                                       memento.yCursorPosition, memento.downTime,
-                                                      memento.getPointerCount(),
-                                                      memento.pointerProperties.data(),
-                                                      memento.pointerCoords.data()));
+                                                      memento.pointerProperties,
+                                                      memento.pointerCoords));
             } else {
                 std::vector<std::unique_ptr<MotionEntry>> pointerCancelEvents =
                         synthesizeCancelationEventsForPointers(memento, options.pointerIds.value(),
@@ -327,23 +326,22 @@
             continue;
         }
 
-        uint32_t pointerCount = 0;
-        PointerProperties pointerProperties[MAX_POINTERS];
-        PointerCoords pointerCoords[MAX_POINTERS];
+        std::vector<PointerProperties> pointerProperties;
+        std::vector<PointerCoords> pointerCoords;
 
         // We will deliver all pointers the target already knows about
         for (uint32_t i = 0; i < static_cast<uint32_t>(memento.firstNewPointerIdx); i++) {
-            pointerProperties[i] = memento.pointerProperties[i];
-            pointerCoords[i] = memento.pointerCoords[i];
-            pointerCount++;
+            pointerProperties.push_back(memento.pointerProperties[i]);
+            pointerCoords.push_back(memento.pointerCoords[i]);
         }
 
         // We will send explicit events for all pointers the target doesn't know about
         for (uint32_t i = static_cast<uint32_t>(memento.firstNewPointerIdx);
              i < memento.getPointerCount(); i++) {
-            pointerProperties[i] = memento.pointerProperties[i];
-            pointerCoords[i] = memento.pointerCoords[i];
-            pointerCount++;
+            pointerProperties.push_back(memento.pointerProperties[i]);
+            pointerCoords.push_back(memento.pointerCoords[i]);
+
+            const size_t pointerCount = pointerProperties.size();
 
             // Down only if the first pointer, pointer down otherwise
             const int32_t action = (pointerCount <= 1)
@@ -360,7 +358,7 @@
                                                   AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
                                                   memento.yPrecision, memento.xCursorPosition,
                                                   memento.yCursorPosition, memento.downTime,
-                                                  pointerCount, pointerProperties, pointerCoords));
+                                                  pointerProperties, pointerCoords));
         }
 
         memento.firstNewPointerIdx = INVALID_POINTER_INDEX;
@@ -401,9 +399,7 @@
                                               AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
                                               memento.yPrecision, memento.xCursorPosition,
                                               memento.yCursorPosition, memento.downTime,
-                                              memento.getPointerCount(),
-                                              memento.pointerProperties.data(),
-                                              memento.pointerCoords.data()));
+                                              memento.pointerProperties, memento.pointerCoords));
     } else {
         // If we aren't canceling all pointers, we need to generate ACTION_POINTER_UP with
         // FLAG_CANCELED for each of the canceled pointers. For each event, we must remove the
@@ -430,8 +426,7 @@
                                                   AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
                                                   memento.yPrecision, memento.xCursorPosition,
                                                   memento.yCursorPosition, memento.downTime,
-                                                  pointerCount, pointerProperties.data(),
-                                                  pointerCoords.data()));
+                                                  pointerProperties, pointerCoords));
 
             // Cleanup pointer information
             pointerProperties.erase(pointerProperties.begin() + pointerIdx);