Add hmac to InputEvent and scale to MotionEvent

We need to pass some additional data to the app to be able to construct
the MotionEvent.

For proper support of getRawX/getRawY, add the xScale and yScale to
MotionEvent.

For the verification of input events, add hmac to InputEvent.

Bug: 134977432
Bug: 140786233
Test: atest libinput_tests inputflinger_tests
Change-Id: Ia3400ebbd9698549aad4d97a3b789ab7e10f6b65
diff --git a/include/input/Input.h b/include/input/Input.h
index f871847..1cf58ef 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -31,6 +31,7 @@
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
 #include <utils/Vector.h>
+#include <array>
 #include <limits>
 #include <queue>
 
@@ -258,6 +259,11 @@
  */
 constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<float>::quiet_NaN();
 
+/**
+ * Invalid value of HMAC - SHA256. Any events with this HMAC value will be marked as not verified.
+ */
+constexpr std::array<uint8_t, 32> INVALID_HMAC = {0};
+
 /*
  * Pointer coordinate data.
  */
@@ -356,14 +362,17 @@
 
     inline void setDisplayId(int32_t displayId) { mDisplayId = displayId; }
 
+    inline std::array<uint8_t, 32> getHmac() const { return mHmac; }
 
 protected:
-    void initialize(int32_t deviceId, int32_t source, int32_t displayId);
+    void initialize(int32_t deviceId, int32_t source, int32_t displayId,
+                    std::array<uint8_t, 32> hmac);
     void initialize(const InputEvent& from);
 
     int32_t mDeviceId;
     int32_t mSource;
     int32_t mDisplayId;
+    std::array<uint8_t, 32> mHmac;
 };
 
 /*
@@ -396,18 +405,10 @@
     static const char* getLabel(int32_t keyCode);
     static int32_t getKeyCodeFromLabel(const char* label);
 
-    void initialize(
-            int32_t deviceId,
-            int32_t source,
-            int32_t displayId,
-            int32_t action,
-            int32_t flags,
-            int32_t keyCode,
-            int32_t scanCode,
-            int32_t metaState,
-            int32_t repeatCount,
-            nsecs_t downTime,
-            nsecs_t eventTime);
+    void initialize(int32_t deviceId, int32_t source, int32_t displayId,
+                    std::array<uint8_t, 32> hmac, int32_t action, int32_t flags, int32_t keyCode,
+                    int32_t scanCode, int32_t metaState, int32_t repeatCount, nsecs_t downTime,
+                    nsecs_t eventTime);
     void initialize(const KeyEvent& from);
 
 protected:
@@ -463,6 +464,10 @@
 
     inline void setActionButton(int32_t button) { mActionButton = button; }
 
+    inline float getXScale() const { return mXScale; }
+
+    inline float getYScale() const { return mYScale; }
+
     inline float getXOffset() const { return mXOffset; }
 
     inline float getYOffset() const { return mYOffset; }
@@ -624,9 +629,10 @@
 
     ssize_t findPointerIndex(int32_t pointerId) const;
 
-    void initialize(int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
-                    int32_t actionButton, int32_t flags, int32_t edgeFlags, int32_t metaState,
-                    int32_t buttonState, MotionClassification classification, float xOffset,
+    void initialize(int32_t deviceId, int32_t source, int32_t displayId,
+                    std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
+                    int32_t flags, int32_t edgeFlags, int32_t metaState, int32_t buttonState,
+                    MotionClassification classification, float xScale, float yScale, float xOffset,
                     float yOffset, float xPrecision, float yPrecision, float rawXCursorPosition,
                     float rawYCursorPosition, nsecs_t downTime, nsecs_t eventTime,
                     size_t pointerCount, const PointerProperties* pointerProperties,
@@ -676,6 +682,8 @@
     int32_t mMetaState;
     int32_t mButtonState;
     MotionClassification mClassification;
+    float mXScale;
+    float mYScale;
     float mXOffset;
     float mYOffset;
     float mXPrecision;
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index ae47438..06fd3bb 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -76,6 +76,9 @@
     } header;
 
     // Body *must* be 8 byte aligned.
+    // For keys and motions, rely on the fact that std::array takes up exactly as much space
+    // as the underlying data. This is not guaranteed by C++, but it simplifies the conversions.
+    static_assert(sizeof(std::array<uint8_t, 32>) == 32);
     union Body {
         struct Key {
             uint32_t seq;
@@ -84,6 +87,7 @@
             int32_t deviceId;
             int32_t source;
             int32_t displayId;
+            std::array<uint8_t, 32> hmac;
             int32_t action;
             int32_t flags;
             int32_t keyCode;
@@ -103,6 +107,7 @@
             int32_t deviceId;
             int32_t source;
             int32_t displayId;
+            std::array<uint8_t, 32> hmac;
             int32_t action;
             int32_t actionButton;
             int32_t flags;
@@ -112,6 +117,8 @@
             uint8_t empty2[3];                   // 3 bytes to fill gap created by classification
             int32_t edgeFlags;
             nsecs_t downTime __attribute__((aligned(8)));
+            float xScale;
+            float yScale;
             float xOffset;
             float yOffset;
             float xPrecision;
@@ -269,19 +276,10 @@
      * Returns BAD_VALUE if seq is 0.
      * Other errors probably indicate that the channel is broken.
      */
-    status_t publishKeyEvent(
-            uint32_t seq,
-            int32_t deviceId,
-            int32_t source,
-            int32_t displayId,
-            int32_t action,
-            int32_t flags,
-            int32_t keyCode,
-            int32_t scanCode,
-            int32_t metaState,
-            int32_t repeatCount,
-            nsecs_t downTime,
-            nsecs_t eventTime);
+    status_t publishKeyEvent(uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId,
+                             std::array<uint8_t, 32> hmac, int32_t action, int32_t flags,
+                             int32_t keyCode, int32_t scanCode, int32_t metaState,
+                             int32_t repeatCount, nsecs_t downTime, nsecs_t eventTime);
 
     /* Publishes a motion event to the input channel.
      *
@@ -292,9 +290,10 @@
      * Other errors probably indicate that the channel is broken.
      */
     status_t publishMotionEvent(uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId,
-                                int32_t action, int32_t actionButton, int32_t flags,
-                                int32_t edgeFlags, int32_t metaState, int32_t buttonState,
-                                MotionClassification classification, float xOffset, float yOffset,
+                                std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
+                                int32_t flags, int32_t edgeFlags, int32_t metaState,
+                                int32_t buttonState, MotionClassification classification,
+                                float xScale, float yScale, float xOffset, float yOffset,
                                 float xPrecision, float yPrecision, float xCursorPosition,
                                 float yCursorPosition, nsecs_t downTime, nsecs_t eventTime,
                                 uint32_t pointerCount, const PointerProperties* pointerProperties,
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 8ccbc7f..bff1b97 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -57,16 +57,19 @@
     return "UNKNOWN";
 }
 
-void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId) {
+void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId,
+                            std::array<uint8_t, 32> hmac) {
     mDeviceId = deviceId;
     mSource = source;
     mDisplayId = displayId;
+    mHmac = hmac;
 }
 
 void InputEvent::initialize(const InputEvent& from) {
     mDeviceId = from.mDeviceId;
     mSource = from.mSource;
     mDisplayId = from.mDisplayId;
+    mHmac = from.mHmac;
 }
 
 // --- KeyEvent ---
@@ -79,19 +82,11 @@
     return getKeyCodeByLabel(label);
 }
 
-void KeyEvent::initialize(
-        int32_t deviceId,
-        int32_t source,
-        int32_t displayId,
-        int32_t action,
-        int32_t flags,
-        int32_t keyCode,
-        int32_t scanCode,
-        int32_t metaState,
-        int32_t repeatCount,
-        nsecs_t downTime,
-        nsecs_t eventTime) {
-    InputEvent::initialize(deviceId, source, displayId);
+void KeyEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId,
+                          std::array<uint8_t, 32> hmac, int32_t action, int32_t flags,
+                          int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
+                          nsecs_t downTime, nsecs_t eventTime) {
+    InputEvent::initialize(deviceId, source, displayId, hmac);
     mAction = action;
     mFlags = flags;
     mKeyCode = keyCode;
@@ -250,15 +245,16 @@
 
 // --- MotionEvent ---
 
-void MotionEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
-                             int32_t actionButton, int32_t flags, int32_t edgeFlags,
-                             int32_t metaState, int32_t buttonState,
-                             MotionClassification classification, float xOffset, float yOffset,
-                             float xPrecision, float yPrecision, float rawXCursorPosition,
-                             float rawYCursorPosition, nsecs_t downTime, nsecs_t eventTime,
-                             size_t pointerCount, const PointerProperties* pointerProperties,
+void MotionEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId,
+                             std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
+                             int32_t flags, int32_t edgeFlags, int32_t metaState,
+                             int32_t buttonState, MotionClassification classification, float xScale,
+                             float yScale, float xOffset, float yOffset, float xPrecision,
+                             float yPrecision, float rawXCursorPosition, float rawYCursorPosition,
+                             nsecs_t downTime, nsecs_t eventTime, size_t pointerCount,
+                             const PointerProperties* pointerProperties,
                              const PointerCoords* pointerCoords) {
-    InputEvent::initialize(deviceId, source, displayId);
+    InputEvent::initialize(deviceId, source, displayId, hmac);
     mAction = action;
     mActionButton = actionButton;
     mFlags = flags;
@@ -266,6 +262,8 @@
     mMetaState = metaState;
     mButtonState = buttonState;
     mClassification = classification;
+    mXScale = xScale;
+    mYScale = yScale;
     mXOffset = xOffset;
     mYOffset = yOffset;
     mXPrecision = xPrecision;
@@ -281,7 +279,7 @@
 }
 
 void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
-    InputEvent::initialize(other->mDeviceId, other->mSource, other->mDisplayId);
+    InputEvent::initialize(other->mDeviceId, other->mSource, other->mDisplayId, other->mHmac);
     mAction = other->mAction;
     mActionButton = other->mActionButton;
     mFlags = other->mFlags;
@@ -289,6 +287,8 @@
     mMetaState = other->mMetaState;
     mButtonState = other->mButtonState;
     mClassification = other->mClassification;
+    mXScale = other->mXScale;
+    mYScale = other->mYScale;
     mXOffset = other->mXOffset;
     mYOffset = other->mYOffset;
     mXPrecision = other->mXPrecision;
@@ -490,6 +490,12 @@
     mDeviceId = parcel->readInt32();
     mSource = parcel->readInt32();
     mDisplayId = parcel->readInt32();
+    std::vector<uint8_t> hmac;
+    status_t result = parcel->readByteVector(&hmac);
+    if (result != OK || hmac.size() != 32) {
+        return BAD_VALUE;
+    }
+    std::move(hmac.begin(), hmac.begin() + hmac.size(), mHmac.begin());
     mAction = parcel->readInt32();
     mActionButton = parcel->readInt32();
     mFlags = parcel->readInt32();
@@ -497,6 +503,8 @@
     mMetaState = parcel->readInt32();
     mButtonState = parcel->readInt32();
     mClassification = static_cast<MotionClassification>(parcel->readByte());
+    mXScale = parcel->readFloat();
+    mYScale = parcel->readFloat();
     mXOffset = parcel->readFloat();
     mYOffset = parcel->readFloat();
     mXPrecision = parcel->readFloat();
@@ -543,6 +551,8 @@
     parcel->writeInt32(mDeviceId);
     parcel->writeInt32(mSource);
     parcel->writeInt32(mDisplayId);
+    std::vector<uint8_t> hmac(mHmac.begin(), mHmac.end());
+    parcel->writeByteVector(hmac);
     parcel->writeInt32(mAction);
     parcel->writeInt32(mActionButton);
     parcel->writeInt32(mFlags);
@@ -550,6 +560,8 @@
     parcel->writeInt32(mMetaState);
     parcel->writeInt32(mButtonState);
     parcel->writeByte(static_cast<int8_t>(mClassification));
+    parcel->writeFloat(mXScale);
+    parcel->writeFloat(mYScale);
     parcel->writeFloat(mXOffset);
     parcel->writeFloat(mYOffset);
     parcel->writeFloat(mXPrecision);
@@ -607,7 +619,7 @@
 
 void FocusEvent::initialize(bool hasFocus, bool inTouchMode) {
     InputEvent::initialize(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
-                           ADISPLAY_ID_NONE);
+                           ADISPLAY_ID_NONE, INVALID_HMAC);
     mHasFocus = hasFocus;
     mInTouchMode = inTouchMode;
 }
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index d53a557..d25a5cc 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -147,6 +147,8 @@
             msg->body.key.source = body.key.source;
             // int32_t displayId
             msg->body.key.displayId = body.key.displayId;
+            // std::array<uint8_t, 32> hmac
+            msg->body.key.hmac = body.key.hmac;
             // int32_t action
             msg->body.key.action = body.key.action;
             // int32_t flags
@@ -174,6 +176,8 @@
             msg->body.motion.source = body.motion.source;
             // int32_t displayId
             msg->body.motion.displayId = body.motion.displayId;
+            // std::array<uint8_t, 32> hmac
+            msg->body.motion.hmac = body.motion.hmac;
             // int32_t action
             msg->body.motion.action = body.motion.action;
             // int32_t actionButton
@@ -190,6 +194,10 @@
             msg->body.motion.edgeFlags = body.motion.edgeFlags;
             // nsecs_t downTime
             msg->body.motion.downTime = body.motion.downTime;
+            // float xScale
+            msg->body.motion.xScale = body.motion.xScale;
+            // float yScale
+            msg->body.motion.yScale = body.motion.yScale;
             // float xOffset
             msg->body.motion.xOffset = body.motion.xOffset;
             // float yOffset
@@ -424,19 +432,11 @@
 InputPublisher::~InputPublisher() {
 }
 
-status_t InputPublisher::publishKeyEvent(
-        uint32_t seq,
-        int32_t deviceId,
-        int32_t source,
-        int32_t displayId,
-        int32_t action,
-        int32_t flags,
-        int32_t keyCode,
-        int32_t scanCode,
-        int32_t metaState,
-        int32_t repeatCount,
-        nsecs_t downTime,
-        nsecs_t eventTime) {
+status_t InputPublisher::publishKeyEvent(uint32_t seq, int32_t deviceId, int32_t source,
+                                         int32_t displayId, std::array<uint8_t, 32> hmac,
+                                         int32_t action, int32_t flags, int32_t keyCode,
+                                         int32_t scanCode, int32_t metaState, int32_t repeatCount,
+                                         nsecs_t downTime, nsecs_t eventTime) {
     if (ATRACE_ENABLED()) {
         std::string message = StringPrintf("publishKeyEvent(inputChannel=%s, keyCode=%" PRId32 ")",
                 mChannel->getName().c_str(), keyCode);
@@ -461,6 +461,7 @@
     msg.body.key.deviceId = deviceId;
     msg.body.key.source = source;
     msg.body.key.displayId = displayId;
+    msg.body.key.hmac = hmac;
     msg.body.key.action = action;
     msg.body.key.flags = flags;
     msg.body.key.keyCode = keyCode;
@@ -473,11 +474,12 @@
 }
 
 status_t InputPublisher::publishMotionEvent(
-        uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
-        int32_t actionButton, int32_t flags, int32_t edgeFlags, int32_t metaState,
-        int32_t buttonState, MotionClassification classification, float xOffset, float yOffset,
-        float xPrecision, float yPrecision, float xCursorPosition, float yCursorPosition,
-        nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
+        uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId,
+        std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton, int32_t flags,
+        int32_t edgeFlags, int32_t metaState, int32_t buttonState,
+        MotionClassification classification, float xScale, float yScale, float xOffset,
+        float yOffset, float xPrecision, float yPrecision, float xCursorPosition,
+        float yCursorPosition, nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
         const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
     if (ATRACE_ENABLED()) {
         std::string message = StringPrintf(
@@ -489,13 +491,14 @@
         ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
               "displayId=%" PRId32 ", "
               "action=0x%x, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, "
-              "metaState=0x%x, buttonState=0x%x, classification=%s, xOffset=%f, yOffset=%f, "
+              "metaState=0x%x, buttonState=0x%x, classification=%s, xScale=%.1f, yScale=%.1f, "
+              "xOffset=%.1f, yOffset=%.1f, "
               "xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", "
               "pointerCount=%" PRIu32,
               mChannel->getName().c_str(), seq, deviceId, source, displayId, action, actionButton,
               flags, edgeFlags, metaState, buttonState,
-              motionClassificationToString(classification), xOffset, yOffset, xPrecision,
-              yPrecision, downTime, eventTime, pointerCount);
+              motionClassificationToString(classification), xScale, yScale, xOffset, yOffset,
+              xPrecision, yPrecision, downTime, eventTime, pointerCount);
     }
 
     if (!seq) {
@@ -515,6 +518,7 @@
     msg.body.motion.deviceId = deviceId;
     msg.body.motion.source = source;
     msg.body.motion.displayId = displayId;
+    msg.body.motion.hmac = hmac;
     msg.body.motion.action = action;
     msg.body.motion.actionButton = actionButton;
     msg.body.motion.flags = flags;
@@ -522,6 +526,8 @@
     msg.body.motion.metaState = metaState;
     msg.body.motion.buttonState = buttonState;
     msg.body.motion.classification = classification;
+    msg.body.motion.xScale = xScale;
+    msg.body.motion.yScale = yScale;
     msg.body.motion.xOffset = xOffset;
     msg.body.motion.yOffset = yOffset;
     msg.body.motion.xPrecision = xPrecision;
@@ -1136,18 +1142,10 @@
 }
 
 void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
-    event->initialize(
-            msg->body.key.deviceId,
-            msg->body.key.source,
-            msg->body.key.displayId,
-            msg->body.key.action,
-            msg->body.key.flags,
-            msg->body.key.keyCode,
-            msg->body.key.scanCode,
-            msg->body.key.metaState,
-            msg->body.key.repeatCount,
-            msg->body.key.downTime,
-            msg->body.key.eventTime);
+    event->initialize(msg->body.key.deviceId, msg->body.key.source, msg->body.key.displayId,
+                      msg->body.key.hmac, msg->body.key.action, msg->body.key.flags,
+                      msg->body.key.keyCode, msg->body.key.scanCode, msg->body.key.metaState,
+                      msg->body.key.repeatCount, msg->body.key.downTime, msg->body.key.eventTime);
 }
 
 void InputConsumer::initializeFocusEvent(FocusEvent* event, const InputMessage* msg) {
@@ -1164,15 +1162,15 @@
     }
 
     event->initialize(msg->body.motion.deviceId, msg->body.motion.source,
-                      msg->body.motion.displayId, msg->body.motion.action,
+                      msg->body.motion.displayId, msg->body.motion.hmac, msg->body.motion.action,
                       msg->body.motion.actionButton, msg->body.motion.flags,
                       msg->body.motion.edgeFlags, msg->body.motion.metaState,
                       msg->body.motion.buttonState, msg->body.motion.classification,
-                      msg->body.motion.xOffset, msg->body.motion.yOffset,
-                      msg->body.motion.xPrecision, msg->body.motion.yPrecision,
-                      msg->body.motion.xCursorPosition, msg->body.motion.yCursorPosition,
-                      msg->body.motion.downTime, msg->body.motion.eventTime, pointerCount,
-                      pointerProperties, pointerCoords);
+                      msg->body.motion.xScale, msg->body.motion.yScale, msg->body.motion.xOffset,
+                      msg->body.motion.yOffset, msg->body.motion.xPrecision,
+                      msg->body.motion.yPrecision, msg->body.motion.xCursorPosition,
+                      msg->body.motion.yCursorPosition, msg->body.motion.downTime,
+                      msg->body.motion.eventTime, pointerCount, pointerProperties, pointerCoords);
 }
 
 void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index e189d20..6f9b162 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -487,9 +487,9 @@
         int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time) {
     outEvents.push();
     KeyEvent& event = outEvents.editTop();
-    event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
-            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
-            0, keyCode, 0, metaState, 0, time, time);
+    event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE, INVALID_HMAC,
+                     down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, 0, keyCode, 0, metaState,
+                     0, time, time);
 }
 
 void KeyCharacterMap::addMetaKeys(Vector<KeyEvent>& outEvents,
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index b90857c..8c6890f 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -26,7 +26,12 @@
 // Default display id.
 static constexpr int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
 
-class BaseTest : public testing::Test { };
+class BaseTest : public testing::Test {
+protected:
+    static constexpr std::array<uint8_t, 32> HMAC = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
+                                                     11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+                                                     22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
+};
 
 // --- PointerCoordsTest ---
 
@@ -176,16 +181,17 @@
     KeyEvent event;
 
     // Initialize and get properties.
-    const nsecs_t ARBITRARY_DOWN_TIME = 1;
-    const nsecs_t ARBITRARY_EVENT_TIME = 2;
-    event.initialize(2, AINPUT_SOURCE_GAMEPAD, DISPLAY_ID, AKEY_EVENT_ACTION_DOWN,
-            AKEY_EVENT_FLAG_FROM_SYSTEM, AKEYCODE_BUTTON_X, 121,
-            AMETA_ALT_ON, 1, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME);
+    constexpr nsecs_t ARBITRARY_DOWN_TIME = 1;
+    constexpr nsecs_t ARBITRARY_EVENT_TIME = 2;
+    event.initialize(2, AINPUT_SOURCE_GAMEPAD, DISPLAY_ID, HMAC, AKEY_EVENT_ACTION_DOWN,
+                     AKEY_EVENT_FLAG_FROM_SYSTEM, AKEYCODE_BUTTON_X, 121, AMETA_ALT_ON, 1,
+                     ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME);
 
     ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event.getType());
     ASSERT_EQ(2, event.getDeviceId());
     ASSERT_EQ(static_cast<int>(AINPUT_SOURCE_GAMEPAD), event.getSource());
     ASSERT_EQ(DISPLAY_ID, event.getDisplayId());
+    EXPECT_EQ(HMAC, event.getHmac());
     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, event.getAction());
     ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, event.getFlags());
     ASSERT_EQ(AKEYCODE_BUTTON_X, event.getKeyCode());
@@ -210,19 +216,17 @@
 
 class MotionEventTest : public BaseTest {
 protected:
-    static const nsecs_t ARBITRARY_DOWN_TIME;
-    static const nsecs_t ARBITRARY_EVENT_TIME;
-    static const float X_OFFSET;
-    static const float Y_OFFSET;
+    static constexpr nsecs_t ARBITRARY_DOWN_TIME = 1;
+    static constexpr nsecs_t ARBITRARY_EVENT_TIME = 2;
+    static constexpr float X_SCALE = 2.0;
+    static constexpr float Y_SCALE = 3.0;
+    static constexpr float X_OFFSET = 1;
+    static constexpr float Y_OFFSET = 1.1;
 
     void initializeEventWithHistory(MotionEvent* event);
     void assertEqualsEventWithHistory(const MotionEvent* event);
 };
 
-const nsecs_t MotionEventTest::ARBITRARY_DOWN_TIME = 1;
-const nsecs_t MotionEventTest::ARBITRARY_EVENT_TIME = 2;
-const float MotionEventTest::X_OFFSET = 1.0f;
-const float MotionEventTest::Y_OFFSET = 1.1f;
 
 void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
     PointerProperties pointerProperties[2];
@@ -254,12 +258,13 @@
     pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 26);
     pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
     pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
-    event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, AMOTION_EVENT_ACTION_MOVE, 0,
+    event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, HMAC, AMOTION_EVENT_ACTION_MOVE, 0,
                       AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, AMOTION_EVENT_EDGE_FLAG_TOP,
                       AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY, MotionClassification::NONE,
-                      X_OFFSET, Y_OFFSET, 2.0f, 2.1f, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                      AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_DOWN_TIME,
-                      ARBITRARY_EVENT_TIME, 2, pointerProperties, pointerCoords);
+                      X_SCALE, Y_SCALE, X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
+                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                      ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2, pointerProperties,
+                      pointerCoords);
 
     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
@@ -308,12 +313,15 @@
     ASSERT_EQ(2, event->getDeviceId());
     ASSERT_EQ(static_cast<int>(AINPUT_SOURCE_TOUCHSCREEN), event->getSource());
     ASSERT_EQ(DISPLAY_ID, event->getDisplayId());
+    EXPECT_EQ(HMAC, event->getHmac());
     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
     ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
     ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
     ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
     ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, event->getButtonState());
     ASSERT_EQ(MotionClassification::NONE, event->getClassification());
+    EXPECT_EQ(X_SCALE, event->getXScale());
+    EXPECT_EQ(Y_SCALE, event->getYScale());
     ASSERT_EQ(X_OFFSET, event->getXOffset());
     ASSERT_EQ(Y_OFFSET, event->getYOffset());
     ASSERT_EQ(2.0f, event->getXPrecision());
@@ -570,12 +578,13 @@
         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
     }
     MotionEvent event;
-    event.initialize(0 /*deviceId*/, AINPUT_SOURCE_UNKNOWN, DISPLAY_ID, AMOTION_EVENT_ACTION_MOVE,
-                     0 /*actionButton*/, 0 /*flags*/, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE,
-                     0 /*buttonState*/, MotionClassification::NONE, 0 /*xOffset*/, 0 /*yOffset*/,
-                     0 /*xPrecision*/, 0 /*yPrecision*/, 3 + RADIUS /*xCursorPosition*/,
-                     2 /*yCursorPosition*/, 0 /*downTime*/, 0 /*eventTime*/, pointerCount,
-                     pointerProperties, pointerCoords);
+    event.initialize(0 /*deviceId*/, AINPUT_SOURCE_UNKNOWN, DISPLAY_ID, INVALID_HMAC,
+                     AMOTION_EVENT_ACTION_MOVE, 0 /*actionButton*/, 0 /*flags*/,
+                     AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
+                     MotionClassification::NONE, 1 /*xScale*/, 1 /*yScale*/, 0 /*xOffset*/,
+                     0 /*yOffset*/, 0 /*xPrecision*/, 0 /*yPrecision*/,
+                     3 + RADIUS /*xCursorPosition*/, 2 /*yCursorPosition*/, 0 /*downTime*/,
+                     0 /*eventTime*/, pointerCount, pointerProperties, pointerCoords);
     float originalRawX = 0 + 3;
     float originalRawY = -RADIUS + 2;
 
@@ -634,9 +643,10 @@
     }
 
     for (MotionClassification classification : classifications) {
-        event.initialize(0 /*deviceId*/, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
+        event.initialize(0 /*deviceId*/, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, INVALID_HMAC,
                          AMOTION_EVENT_ACTION_DOWN, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE,
-                         0, classification, 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                         0, classification, 1 /*xScale*/, 1 /*yScale*/, 0, 0, 0, 0,
+                         AMOTION_EVENT_INVALID_CURSOR_POSITION,
                          AMOTION_EVENT_INVALID_CURSOR_POSITION, 0 /*downTime*/, 0 /*eventTime*/,
                          pointerCount, pointerProperties, pointerCoords);
         ASSERT_EQ(classification, event.getClassification());
@@ -654,9 +664,10 @@
         pointerCoords[i].clear();
     }
 
-    event.initialize(0 /*deviceId*/, AINPUT_SOURCE_MOUSE, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0,
-                     0, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0, MotionClassification::NONE, 0,
-                     0, 0, 0, 280 /*xCursorPosition*/, 540 /*yCursorPosition*/, 0 /*downTime*/,
+    event.initialize(0 /*deviceId*/, AINPUT_SOURCE_MOUSE, DISPLAY_ID, INVALID_HMAC,
+                     AMOTION_EVENT_ACTION_DOWN, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0,
+                     MotionClassification::NONE, 1 /*xScale*/, 1 /*yScale*/, 0, 0, 0, 0,
+                     280 /*xCursorPosition*/, 540 /*yCursorPosition*/, 0 /*downTime*/,
                      0 /*eventTime*/, pointerCount, pointerProperties, pointerCoords);
     event.offsetLocation(20, 60);
     ASSERT_EQ(280, event.getRawXCursorPosition());
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index 2fc77e9..1e51ea8 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -75,6 +75,9 @@
     constexpr int32_t deviceId = 1;
     constexpr int32_t source = AINPUT_SOURCE_KEYBOARD;
     constexpr int32_t displayId = ADISPLAY_ID_DEFAULT;
+    constexpr std::array<uint8_t, 32> hmac = {31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21,
+                                              20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,
+                                              9,  8,  7,  6,  5,  4,  3,  2,  1,  0};
     constexpr int32_t action = AKEY_EVENT_ACTION_DOWN;
     constexpr int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
     constexpr int32_t keyCode = AKEYCODE_ENTER;
@@ -84,8 +87,9 @@
     constexpr nsecs_t downTime = 3;
     constexpr nsecs_t eventTime = 4;
 
-    status = mPublisher->publishKeyEvent(seq, deviceId, source, displayId, action, flags,
-            keyCode, scanCode, metaState, repeatCount, downTime, eventTime);
+    status = mPublisher->publishKeyEvent(seq, deviceId, source, displayId, hmac, action, flags,
+                                         keyCode, scanCode, metaState, repeatCount, downTime,
+                                         eventTime);
     ASSERT_EQ(OK, status)
             << "publisher publishKeyEvent should return OK";
 
@@ -105,6 +109,7 @@
     EXPECT_EQ(deviceId, keyEvent->getDeviceId());
     EXPECT_EQ(source, keyEvent->getSource());
     EXPECT_EQ(displayId, keyEvent->getDisplayId());
+    EXPECT_EQ(hmac, keyEvent->getHmac());
     EXPECT_EQ(action, keyEvent->getAction());
     EXPECT_EQ(flags, keyEvent->getFlags());
     EXPECT_EQ(keyCode, keyEvent->getKeyCode());
@@ -136,6 +141,9 @@
     constexpr int32_t deviceId = 1;
     constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
     constexpr int32_t displayId = ADISPLAY_ID_DEFAULT;
+    constexpr std::array<uint8_t, 32> hmac = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
+                                              11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+                                              22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
     constexpr int32_t action = AMOTION_EVENT_ACTION_MOVE;
     constexpr int32_t actionButton = 0;
     constexpr int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
@@ -143,6 +151,8 @@
     constexpr int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
     constexpr int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
     constexpr MotionClassification classification = MotionClassification::AMBIGUOUS_GESTURE;
+    constexpr float xScale = 2;
+    constexpr float yScale = 3;
     constexpr float xOffset = -10;
     constexpr float yOffset = -20;
     constexpr float xPrecision = 0.25;
@@ -171,12 +181,12 @@
         pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
     }
 
-    status =
-            mPublisher->publishMotionEvent(seq, deviceId, source, displayId, action, actionButton,
-                                           flags, edgeFlags, metaState, buttonState, classification,
-                                           xOffset, yOffset, xPrecision, yPrecision,
-                                           xCursorPosition, yCursorPosition, downTime, eventTime,
-                                           pointerCount, pointerProperties, pointerCoords);
+    status = mPublisher->publishMotionEvent(seq, deviceId, source, displayId, hmac, action,
+                                            actionButton, flags, edgeFlags, metaState, buttonState,
+                                            classification, xScale, yScale, xOffset, yOffset,
+                                            xPrecision, yPrecision, xCursorPosition,
+                                            yCursorPosition, downTime, eventTime, pointerCount,
+                                            pointerProperties, pointerCoords);
     ASSERT_EQ(OK, status)
             << "publisher publishMotionEvent should return OK";
 
@@ -196,12 +206,17 @@
     EXPECT_EQ(deviceId, motionEvent->getDeviceId());
     EXPECT_EQ(source, motionEvent->getSource());
     EXPECT_EQ(displayId, motionEvent->getDisplayId());
+    EXPECT_EQ(hmac, motionEvent->getHmac());
     EXPECT_EQ(action, motionEvent->getAction());
     EXPECT_EQ(flags, motionEvent->getFlags());
     EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
     EXPECT_EQ(metaState, motionEvent->getMetaState());
     EXPECT_EQ(buttonState, motionEvent->getButtonState());
     EXPECT_EQ(classification, motionEvent->getClassification());
+    EXPECT_EQ(xScale, motionEvent->getXScale());
+    EXPECT_EQ(yScale, motionEvent->getYScale());
+    EXPECT_EQ(xOffset, motionEvent->getXOffset());
+    EXPECT_EQ(yOffset, motionEvent->getYOffset());
     EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
     EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
     EXPECT_EQ(xCursorPosition, motionEvent->getRawXCursorPosition());
@@ -316,11 +331,12 @@
         pointerCoords[i].clear();
     }
 
-    status =
-            mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MotionClassification::NONE,
-                                           0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                                           AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
-                                           pointerCount, pointerProperties, pointerCoords);
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, INVALID_HMAC, 0, 0, 0, 0, 0, 0,
+                                            MotionClassification::NONE, 1 /* xScale */,
+                                            1 /* yScale */, 0, 0, 0, 0,
+                                            AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                                            AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
+                                            pointerCount, pointerProperties, pointerCoords);
     ASSERT_EQ(BAD_VALUE, status)
             << "publisher publishMotionEvent should return BAD_VALUE";
 }
@@ -331,11 +347,12 @@
     PointerProperties pointerProperties[pointerCount];
     PointerCoords pointerCoords[pointerCount];
 
-    status =
-            mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, MotionClassification::NONE,
-                                           0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                                           AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
-                                           pointerCount, pointerProperties, pointerCoords);
+    status = mPublisher->publishMotionEvent(1, 0, 0, 0, INVALID_HMAC, 0, 0, 0, 0, 0, 0,
+                                            MotionClassification::NONE, 1 /* xScale */,
+                                            1 /* yScale */, 0, 0, 0, 0,
+                                            AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                                            AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
+                                            pointerCount, pointerProperties, pointerCoords);
     ASSERT_EQ(BAD_VALUE, status)
             << "publisher publishMotionEvent should return BAD_VALUE";
 }
@@ -351,11 +368,12 @@
         pointerCoords[i].clear();
     }
 
-    status =
-            mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, MotionClassification::NONE,
-                                           0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                                           AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
-                                           pointerCount, pointerProperties, pointerCoords);
+    status = mPublisher->publishMotionEvent(1, 0, 0, 0, INVALID_HMAC, 0, 0, 0, 0, 0, 0,
+                                            MotionClassification::NONE, 1 /* xScale */,
+                                            1 /* yScale */, 0, 0, 0, 0,
+                                            AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                                            AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
+                                            pointerCount, pointerProperties, pointerCoords);
     ASSERT_EQ(BAD_VALUE, status)
             << "publisher publishMotionEvent should return BAD_VALUE";
 }
diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp
index 9ab0dba..aa8a2d4 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -39,35 +39,39 @@
   CHECK_OFFSET(InputMessage::Body::Key, deviceId, 16);
   CHECK_OFFSET(InputMessage::Body::Key, source, 20);
   CHECK_OFFSET(InputMessage::Body::Key, displayId, 24);
-  CHECK_OFFSET(InputMessage::Body::Key, action, 28);
-  CHECK_OFFSET(InputMessage::Body::Key, flags, 32);
-  CHECK_OFFSET(InputMessage::Body::Key, keyCode, 36);
-  CHECK_OFFSET(InputMessage::Body::Key, scanCode, 40);
-  CHECK_OFFSET(InputMessage::Body::Key, metaState, 44);
-  CHECK_OFFSET(InputMessage::Body::Key, repeatCount, 48);
-  CHECK_OFFSET(InputMessage::Body::Key, downTime, 56);
+  CHECK_OFFSET(InputMessage::Body::Key, hmac, 28);
+  CHECK_OFFSET(InputMessage::Body::Key, action, 60);
+  CHECK_OFFSET(InputMessage::Body::Key, flags, 64);
+  CHECK_OFFSET(InputMessage::Body::Key, keyCode, 68);
+  CHECK_OFFSET(InputMessage::Body::Key, scanCode, 72);
+  CHECK_OFFSET(InputMessage::Body::Key, metaState, 76);
+  CHECK_OFFSET(InputMessage::Body::Key, repeatCount, 80);
+  CHECK_OFFSET(InputMessage::Body::Key, downTime, 88);
 
   CHECK_OFFSET(InputMessage::Body::Motion, seq, 0);
   CHECK_OFFSET(InputMessage::Body::Motion, eventTime, 8);
   CHECK_OFFSET(InputMessage::Body::Motion, deviceId, 16);
   CHECK_OFFSET(InputMessage::Body::Motion, source, 20);
   CHECK_OFFSET(InputMessage::Body::Motion, displayId, 24);
-  CHECK_OFFSET(InputMessage::Body::Motion, action, 28);
-  CHECK_OFFSET(InputMessage::Body::Motion, actionButton, 32);
-  CHECK_OFFSET(InputMessage::Body::Motion, flags, 36);
-  CHECK_OFFSET(InputMessage::Body::Motion, metaState, 40);
-  CHECK_OFFSET(InputMessage::Body::Motion, buttonState, 44);
-  CHECK_OFFSET(InputMessage::Body::Motion, classification, 48);
-  CHECK_OFFSET(InputMessage::Body::Motion, edgeFlags, 52);
-  CHECK_OFFSET(InputMessage::Body::Motion, downTime, 56);
-  CHECK_OFFSET(InputMessage::Body::Motion, xOffset, 64);
-  CHECK_OFFSET(InputMessage::Body::Motion, yOffset, 68);
-  CHECK_OFFSET(InputMessage::Body::Motion, xPrecision, 72);
-  CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 76);
-  CHECK_OFFSET(InputMessage::Body::Motion, xCursorPosition, 80);
-  CHECK_OFFSET(InputMessage::Body::Motion, yCursorPosition, 84);
-  CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 88);
-  CHECK_OFFSET(InputMessage::Body::Motion, pointers, 96);
+  CHECK_OFFSET(InputMessage::Body::Motion, hmac, 28);
+  CHECK_OFFSET(InputMessage::Body::Motion, action, 60);
+  CHECK_OFFSET(InputMessage::Body::Motion, actionButton, 64);
+  CHECK_OFFSET(InputMessage::Body::Motion, flags, 68);
+  CHECK_OFFSET(InputMessage::Body::Motion, metaState, 72);
+  CHECK_OFFSET(InputMessage::Body::Motion, buttonState, 76);
+  CHECK_OFFSET(InputMessage::Body::Motion, classification, 80);
+  CHECK_OFFSET(InputMessage::Body::Motion, edgeFlags, 84);
+  CHECK_OFFSET(InputMessage::Body::Motion, downTime, 88);
+  CHECK_OFFSET(InputMessage::Body::Motion, xScale, 96);
+  CHECK_OFFSET(InputMessage::Body::Motion, yScale, 100);
+  CHECK_OFFSET(InputMessage::Body::Motion, xOffset, 104);
+  CHECK_OFFSET(InputMessage::Body::Motion, yOffset, 108);
+  CHECK_OFFSET(InputMessage::Body::Motion, xPrecision, 112);
+  CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 116);
+  CHECK_OFFSET(InputMessage::Body::Motion, xCursorPosition, 120);
+  CHECK_OFFSET(InputMessage::Body::Motion, yCursorPosition, 124);
+  CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 128);
+  CHECK_OFFSET(InputMessage::Body::Motion, pointers, 136);
 
   CHECK_OFFSET(InputMessage::Body::Focus, seq, 0);
   CHECK_OFFSET(InputMessage::Body::Focus, hasFocus, 4);
@@ -86,7 +90,7 @@
  * the Motion type, where "pointerCount" variable affects the size and can change at runtime.
  */
 void TestBodySize() {
-    static_assert(sizeof(InputMessage::Body::Key) == 64);
+    static_assert(sizeof(InputMessage::Body::Key) == 96);
     static_assert(sizeof(InputMessage::Body::Motion) ==
                   offsetof(InputMessage::Body::Motion, pointers) +
                           sizeof(InputMessage::Body::Motion::Pointer) * MAX_POINTERS);
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index 968e2fa..731eb6a 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -176,11 +176,11 @@
         EXPECT_EQ(pointerIndex, pointerCount);
 
         MotionEvent event;
-        event.initialize(0 /*deviceId*/, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, action,
-                         0 /*actionButton*/, 0 /*flags*/, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE,
-                         0 /*buttonState*/, MotionClassification::NONE, 0 /*xOffset*/,
-                         0 /*yOffset*/, 0 /*xPrecision*/, 0 /*yPrecision*/,
-                         AMOTION_EVENT_INVALID_CURSOR_POSITION,
+        event.initialize(0 /*deviceId*/, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, INVALID_HMAC,
+                         action, 0 /*actionButton*/, 0 /*flags*/, AMOTION_EVENT_EDGE_FLAG_NONE,
+                         AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE, 1 /*xScale*/,
+                         1 /*yScale*/, 0 /*xOffset*/, 0 /*yOffset*/, 0 /*xPrecision*/,
+                         0 /*yPrecision*/, AMOTION_EVENT_INVALID_CURSOR_POSITION,
                          AMOTION_EVENT_INVALID_CURSOR_POSITION, 0 /*downTime*/,
                          entry.eventTime.count(), pointerCount, properties, coords);
 
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index 246e735..9a6ef21 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -203,9 +203,10 @@
     const nsecs_t currentTime = now();
 
     MotionEvent event;
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, /* actionButton */ 0, /* flags */ 0,
                      /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
+                     1 /* xScale */, 1 /* yScale */,
                      /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
                      /* yPrecision */ 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, currentTime,
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 30fdf90..d8e91cc 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2410,7 +2410,7 @@
                 status = connection->inputPublisher
                                  .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
                                                   keyEntry->source, keyEntry->displayId,
-                                                  dispatchEntry->resolvedAction,
+                                                  INVALID_HMAC, dispatchEntry->resolvedAction,
                                                   dispatchEntry->resolvedFlags, keyEntry->keyCode,
                                                   keyEntry->scanCode, keyEntry->metaState,
                                                   keyEntry->repeatCount, keyEntry->downTime,
@@ -2457,12 +2457,14 @@
                 status = connection->inputPublisher
                                  .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
                                                      motionEntry->source, motionEntry->displayId,
-                                                     dispatchEntry->resolvedAction,
+                                                     INVALID_HMAC, dispatchEntry->resolvedAction,
                                                      motionEntry->actionButton,
                                                      dispatchEntry->resolvedFlags,
                                                      motionEntry->edgeFlags, motionEntry->metaState,
                                                      motionEntry->buttonState,
-                                                     motionEntry->classification, xOffset, yOffset,
+                                                     motionEntry->classification,
+                                                     dispatchEntry->windowXScale,
+                                                     dispatchEntry->windowYScale, xOffset, yOffset,
                                                      motionEntry->xPrecision,
                                                      motionEntry->yPrecision,
                                                      motionEntry->xCursorPosition,
@@ -2930,8 +2932,9 @@
     accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
 
     KeyEvent event;
-    event.initialize(args->deviceId, args->source, args->displayId, args->action, flags, keyCode,
-                     args->scanCode, metaState, repeatCount, args->downTime, args->eventTime);
+    event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC, args->action,
+                     flags, keyCode, args->scanCode, metaState, repeatCount, args->downTime,
+                     args->eventTime);
 
     android::base::Timer t;
     mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
@@ -3024,9 +3027,10 @@
             mLock.unlock();
 
             MotionEvent event;
-            event.initialize(args->deviceId, args->source, args->displayId, args->action,
-                             args->actionButton, args->flags, args->edgeFlags, args->metaState,
-                             args->buttonState, args->classification, 0, 0, args->xPrecision,
+            event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC,
+                             args->action, args->actionButton, args->flags, args->edgeFlags,
+                             args->metaState, args->buttonState, args->classification, 1 /*xScale*/,
+                             1 /*yScale*/, 0 /* xOffset */, 0 /* yOffset */, args->xPrecision,
                              args->yPrecision, args->xCursorPosition, args->yCursorPosition,
                              args->downTime, args->eventTime, args->pointerCount,
                              args->pointerProperties, args->pointerCoords);
@@ -3126,7 +3130,7 @@
             accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
                                     /*byref*/ keyCode, /*byref*/ metaState);
             keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(),
-                                keyEvent.getDisplayId(), action, flags, keyCode,
+                                keyEvent.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
                                 keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
                                 keyEvent.getDownTime(), keyEvent.getEventTime());
 
@@ -4682,8 +4686,8 @@
 
 KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
     KeyEvent event;
-    event.initialize(entry.deviceId, entry.source, entry.displayId, entry.action, entry.flags,
-                     entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
+    event.initialize(entry.deviceId, entry.source, entry.displayId, INVALID_HMAC, entry.action,
+                     entry.flags, entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
                      entry.downTime, entry.eventTime);
     return event;
 }
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 98ebf50..094452a 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -225,18 +225,18 @@
     KeyEvent event;
 
     // Rejects undefined key actions.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
-            /*action*/ -1, 0,
-            AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE, INVALID_HMAC,
+                     /*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME,
+                     ARBITRARY_TIME);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
             << "Should reject key events with undefined action.";
 
     // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
-            AKEY_EVENT_ACTION_MULTIPLE, 0,
-            AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE, INVALID_HMAC,
+                     AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
+                     ARBITRARY_TIME, ARBITRARY_TIME);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
@@ -260,10 +260,10 @@
     constexpr MotionClassification classification = MotionClassification::NONE;
 
     // Rejects undefined motion actions.
-    event.initialize(DEVICE_ID, source, DISPLAY_ID,
-                     /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
+                     /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */,
+                     1 /* yScale */, 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
@@ -271,24 +271,24 @@
             << "Should reject motion events with undefined action.";
 
     // Rejects pointer down with invalid index.
-    event.initialize(DEVICE_ID, source, DISPLAY_ID,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_POINTER_DOWN |
                              (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-                     0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+                     0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */,
+                     0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
             << "Should reject motion events with pointer down index too large.";
 
-    event.initialize(DEVICE_ID, source, DISPLAY_ID,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_POINTER_DOWN |
                              (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-                     0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+                     0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */,
+                     0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
@@ -296,24 +296,24 @@
             << "Should reject motion events with pointer down index too small.";
 
     // Rejects pointer up with invalid index.
-    event.initialize(DEVICE_ID, source, DISPLAY_ID,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_POINTER_UP |
                              (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-                     0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+                     0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */,
+                     0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
             << "Should reject motion events with pointer up index too large.";
 
-    event.initialize(DEVICE_ID, source, DISPLAY_ID,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_POINTER_UP |
                              (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-                     0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+                     0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */,
+                     0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
@@ -321,20 +321,20 @@
             << "Should reject motion events with pointer up index too small.";
 
     // Rejects motion events with invalid number of pointers.
-    event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
-                     metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
+                     edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */, 0, 0,
+                     0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 0, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
             << "Should reject motion events with 0 pointers.";
 
-    event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
-                     metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
+                     edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */, 0, 0,
+                     0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
@@ -343,10 +343,10 @@
 
     // Rejects motion events with invalid pointer ids.
     pointerProperties[0].id = -1;
-    event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
-                     metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
+                     edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */, 0, 0,
+                     0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
@@ -354,10 +354,10 @@
             << "Should reject motion events with pointer ids less than 0.";
 
     pointerProperties[0].id = MAX_POINTER_ID + 1;
-    event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
-                     metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
+                     edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */, 0, 0,
+                     0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
@@ -367,10 +367,10 @@
     // Rejects motion events with duplicate pointer ids.
     pointerProperties[0].id = 1;
     pointerProperties[1].id = 1;
-    event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
-                     metaState, 0, classification, 0, 0, 0, 0,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+    event.initialize(DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
+                     edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */, 0, 0,
+                     0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 2, pointerProperties, pointerCoords);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
             &event,
@@ -645,9 +645,9 @@
     nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
     // Define a valid key down event.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
-            AKEY_EVENT_ACTION_DOWN, /* flags */ 0,
-            AKEYCODE_A, KEY_A, AMETA_NONE, /* repeatCount */ 0, currentTime, currentTime);
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId, INVALID_HMAC,
+                     AKEY_EVENT_ACTION_DOWN, /* flags */ 0, AKEYCODE_A, KEY_A, AMETA_NONE,
+                     /* repeatCount */ 0, currentTime, currentTime);
 
     // Inject event until dispatch out.
     return dispatcher->injectInputEvent(
@@ -674,10 +674,12 @@
 
     nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
     // Define a valid motion down event.
-    event.initialize(DEVICE_ID, source, displayId, action, /* actionButton */ 0, /* flags */ 0,
+    event.initialize(DEVICE_ID, source, displayId, INVALID_HMAC, action, /* actionButton */ 0,
+                     /* flags */ 0,
                      /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
-                     /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
-                     /* yPrecision */ 0, xCursorPosition, yCursorPosition, currentTime, currentTime,
+                     /* xScale */ 1, /* yScale */ 1, /* xOffset */ 0, /* yOffset */ 0,
+                     /* xPrecision */ 0, /* yPrecision */ 0, xCursorPosition, yCursorPosition,
+                     currentTime, currentTime,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
 
     // Inject event until dispatch out.