Merge "Move Connection off of RefBase" into udc-dev
diff --git a/include/input/VirtualInputDevice.h b/include/input/VirtualInputDevice.h
index 13ffb58..21a2877 100644
--- a/include/input/VirtualInputDevice.h
+++ b/include/input/VirtualInputDevice.h
@@ -34,10 +34,12 @@
 
 protected:
     const android::base::unique_fd mFd;
-    bool writeInputEvent(uint16_t type, uint16_t code, int32_t value);
+    bool writeInputEvent(uint16_t type, uint16_t code, int32_t value,
+                         std::chrono::nanoseconds eventTime);
     bool writeEvKeyEvent(int32_t androidCode, int32_t androidAction,
                          const std::map<int, int>& evKeyCodeMapping,
-                         const std::map<int, UinputAction>& actionMapping);
+                         const std::map<int, UinputAction>& actionMapping,
+                         std::chrono::nanoseconds eventTime);
 };
 
 class VirtualKeyboard : public VirtualInputDevice {
@@ -47,7 +49,8 @@
     static const std::map<int, UinputAction> KEY_ACTION_MAPPING;
     VirtualKeyboard(android::base::unique_fd fd);
     virtual ~VirtualKeyboard() override;
-    bool writeKeyEvent(int32_t androidKeyCode, int32_t androidAction);
+    bool writeKeyEvent(int32_t androidKeyCode, int32_t androidAction,
+                       std::chrono::nanoseconds eventTime);
 };
 
 class VirtualDpad : public VirtualInputDevice {
@@ -55,17 +58,20 @@
     static const std::map<int, int> DPAD_KEY_CODE_MAPPING;
     VirtualDpad(android::base::unique_fd fd);
     virtual ~VirtualDpad() override;
-    bool writeDpadKeyEvent(int32_t androidKeyCode, int32_t androidAction);
+    bool writeDpadKeyEvent(int32_t androidKeyCode, int32_t androidAction,
+                           std::chrono::nanoseconds eventTime);
 };
 
 class VirtualMouse : public VirtualInputDevice {
 public:
     VirtualMouse(android::base::unique_fd fd);
     virtual ~VirtualMouse() override;
-    bool writeButtonEvent(int32_t androidButtonCode, int32_t androidAction);
+    bool writeButtonEvent(int32_t androidButtonCode, int32_t androidAction,
+                          std::chrono::nanoseconds eventTime);
     // TODO(b/259554911): changing float parameters to int32_t.
-    bool writeRelativeEvent(float relativeX, float relativeY);
-    bool writeScrollEvent(float xAxisMovement, float yAxisMovement);
+    bool writeRelativeEvent(float relativeX, float relativeY, std::chrono::nanoseconds eventTime);
+    bool writeScrollEvent(float xAxisMovement, float yAxisMovement,
+                          std::chrono::nanoseconds eventTime);
 
 private:
     static const std::map<int, UinputAction> BUTTON_ACTION_MAPPING;
@@ -78,7 +84,8 @@
     virtual ~VirtualTouchscreen() override;
     // TODO(b/259554911): changing float parameters to int32_t.
     bool writeTouchEvent(int32_t pointerId, int32_t toolType, int32_t action, float locationX,
-                         float locationY, float pressure, float majorAxisSize);
+                         float locationY, float pressure, float majorAxisSize,
+                         std::chrono::nanoseconds eventTime);
 
 private:
     static const std::map<int, UinputAction> TOUCH_ACTION_MAPPING;
@@ -91,7 +98,7 @@
      */
     std::bitset<MAX_POINTERS> mActivePointers{};
     bool isValidPointerId(int32_t pointerId, UinputAction uinputAction);
-    bool handleTouchDown(int32_t pointerId);
-    bool handleTouchUp(int32_t pointerId);
+    bool handleTouchDown(int32_t pointerId, std::chrono::nanoseconds eventTime);
+    bool handleTouchUp(int32_t pointerId, std::chrono::nanoseconds eventTime);
 };
 } // namespace android
diff --git a/libs/input/VirtualInputDevice.cpp b/libs/input/VirtualInputDevice.cpp
index 3c1f2b6..af9ce3a 100644
--- a/libs/input/VirtualInputDevice.cpp
+++ b/libs/input/VirtualInputDevice.cpp
@@ -44,15 +44,24 @@
     ioctl(mFd, UI_DEV_DESTROY);
 }
 
-bool VirtualInputDevice::writeInputEvent(uint16_t type, uint16_t code, int32_t value) {
-    struct input_event ev = {.type = type, .code = code, .value = value};
+bool VirtualInputDevice::writeInputEvent(uint16_t type, uint16_t code, int32_t value,
+                                         std::chrono::nanoseconds eventTime) {
+    std::chrono::seconds seconds = std::chrono::duration_cast<std::chrono::seconds>(eventTime);
+    std::chrono::microseconds microseconds =
+            std::chrono::duration_cast<std::chrono::microseconds>(eventTime - seconds);
+    struct input_event ev = {.type = type,
+                             .code = code,
+                             .value = value,
+                             .input_event_sec = static_cast<time_t>(seconds.count()),
+                             .input_event_usec = static_cast<suseconds_t>(microseconds.count())};
     return TEMP_FAILURE_RETRY(write(mFd, &ev, sizeof(struct input_event))) == sizeof(ev);
 }
 
 /** Utility method to write keyboard key events or mouse button events. */
 bool VirtualInputDevice::writeEvKeyEvent(int32_t androidCode, int32_t androidAction,
                                          const std::map<int, int>& evKeyCodeMapping,
-                                         const std::map<int, UinputAction>& actionMapping) {
+                                         const std::map<int, UinputAction>& actionMapping,
+                                         std::chrono::nanoseconds eventTime) {
     auto evKeyCodeIterator = evKeyCodeMapping.find(androidCode);
     if (evKeyCodeIterator == evKeyCodeMapping.end()) {
         ALOGE("Unsupported native EV keycode for android code %d", androidCode);
@@ -63,10 +72,10 @@
         return false;
     }
     if (!writeInputEvent(EV_KEY, static_cast<uint16_t>(evKeyCodeIterator->second),
-                         static_cast<int32_t>(actionIterator->second))) {
+                         static_cast<int32_t>(actionIterator->second), eventTime)) {
         return false;
     }
-    if (!writeInputEvent(EV_SYN, SYN_REPORT, 0)) {
+    if (!writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime)) {
         return false;
     }
     return true;
@@ -189,8 +198,10 @@
 VirtualKeyboard::VirtualKeyboard(unique_fd fd) : VirtualInputDevice(std::move(fd)) {}
 VirtualKeyboard::~VirtualKeyboard() {}
 
-bool VirtualKeyboard::writeKeyEvent(int32_t androidKeyCode, int32_t androidAction) {
-    return writeEvKeyEvent(androidKeyCode, androidAction, KEY_CODE_MAPPING, KEY_ACTION_MAPPING);
+bool VirtualKeyboard::writeKeyEvent(int32_t androidKeyCode, int32_t androidAction,
+                                    std::chrono::nanoseconds eventTime) {
+    return writeEvKeyEvent(androidKeyCode, androidAction, KEY_CODE_MAPPING, KEY_ACTION_MAPPING,
+                           eventTime);
 }
 
 // --- VirtualDpad ---
@@ -210,9 +221,10 @@
 
 VirtualDpad::~VirtualDpad() {}
 
-bool VirtualDpad::writeDpadKeyEvent(int32_t androidKeyCode, int32_t androidAction) {
+bool VirtualDpad::writeDpadKeyEvent(int32_t androidKeyCode, int32_t androidAction,
+                                    std::chrono::nanoseconds eventTime) {
     return writeEvKeyEvent(androidKeyCode, androidAction, DPAD_KEY_CODE_MAPPING,
-                           VirtualKeyboard::KEY_ACTION_MAPPING);
+                           VirtualKeyboard::KEY_ACTION_MAPPING, eventTime);
 }
 
 // --- VirtualMouse ---
@@ -236,20 +248,24 @@
 
 VirtualMouse::~VirtualMouse() {}
 
-bool VirtualMouse::writeButtonEvent(int32_t androidButtonCode, int32_t androidAction) {
+bool VirtualMouse::writeButtonEvent(int32_t androidButtonCode, int32_t androidAction,
+                                    std::chrono::nanoseconds eventTime) {
     return writeEvKeyEvent(androidButtonCode, androidAction, BUTTON_CODE_MAPPING,
-                           BUTTON_ACTION_MAPPING);
+                           BUTTON_ACTION_MAPPING, eventTime);
 }
 
-bool VirtualMouse::writeRelativeEvent(float relativeX, float relativeY) {
-    return writeInputEvent(EV_REL, REL_X, relativeX) && writeInputEvent(EV_REL, REL_Y, relativeY) &&
-            writeInputEvent(EV_SYN, SYN_REPORT, 0);
+bool VirtualMouse::writeRelativeEvent(float relativeX, float relativeY,
+                                      std::chrono::nanoseconds eventTime) {
+    return writeInputEvent(EV_REL, REL_X, relativeX, eventTime) &&
+            writeInputEvent(EV_REL, REL_Y, relativeY, eventTime) &&
+            writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
 }
 
-bool VirtualMouse::writeScrollEvent(float xAxisMovement, float yAxisMovement) {
-    return writeInputEvent(EV_REL, REL_HWHEEL, xAxisMovement) &&
-            writeInputEvent(EV_REL, REL_WHEEL, yAxisMovement) &&
-            writeInputEvent(EV_SYN, SYN_REPORT, 0);
+bool VirtualMouse::writeScrollEvent(float xAxisMovement, float yAxisMovement,
+                                    std::chrono::nanoseconds eventTime) {
+    return writeInputEvent(EV_REL, REL_HWHEEL, xAxisMovement, eventTime) &&
+            writeInputEvent(EV_REL, REL_WHEEL, yAxisMovement, eventTime) &&
+            writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
 }
 
 // --- VirtualTouchscreen ---
@@ -291,7 +307,7 @@
 
 bool VirtualTouchscreen::writeTouchEvent(int32_t pointerId, int32_t toolType, int32_t action,
                                          float locationX, float locationY, float pressure,
-                                         float majorAxisSize) {
+                                         float majorAxisSize, std::chrono::nanoseconds eventTime) {
     auto actionIterator = TOUCH_ACTION_MAPPING.find(action);
     if (actionIterator == TOUCH_ACTION_MAPPING.end()) {
         return false;
@@ -300,44 +316,44 @@
     if (!isValidPointerId(pointerId, uinputAction)) {
         return false;
     }
-    if (!writeInputEvent(EV_ABS, ABS_MT_SLOT, pointerId)) {
+    if (!writeInputEvent(EV_ABS, ABS_MT_SLOT, pointerId, eventTime)) {
         return false;
     }
     auto toolTypeIterator = TOOL_TYPE_MAPPING.find(toolType);
     if (toolTypeIterator == TOOL_TYPE_MAPPING.end()) {
         return false;
     }
-    if (!writeInputEvent(EV_ABS, ABS_MT_TOOL_TYPE,
-                         static_cast<int32_t>(toolTypeIterator->second))) {
+    if (!writeInputEvent(EV_ABS, ABS_MT_TOOL_TYPE, static_cast<int32_t>(toolTypeIterator->second),
+                         eventTime)) {
         return false;
     }
-    if (uinputAction == UinputAction::PRESS && !handleTouchDown(pointerId)) {
+    if (uinputAction == UinputAction::PRESS && !handleTouchDown(pointerId, eventTime)) {
         return false;
     }
-    if (uinputAction == UinputAction::RELEASE && !handleTouchUp(pointerId)) {
+    if (uinputAction == UinputAction::RELEASE && !handleTouchUp(pointerId, eventTime)) {
         return false;
     }
-    if (!writeInputEvent(EV_ABS, ABS_MT_POSITION_X, locationX)) {
+    if (!writeInputEvent(EV_ABS, ABS_MT_POSITION_X, locationX, eventTime)) {
         return false;
     }
-    if (!writeInputEvent(EV_ABS, ABS_MT_POSITION_Y, locationY)) {
+    if (!writeInputEvent(EV_ABS, ABS_MT_POSITION_Y, locationY, eventTime)) {
         return false;
     }
     if (!isnan(pressure)) {
-        if (!writeInputEvent(EV_ABS, ABS_MT_PRESSURE, pressure)) {
+        if (!writeInputEvent(EV_ABS, ABS_MT_PRESSURE, pressure, eventTime)) {
             return false;
         }
     }
     if (!isnan(majorAxisSize)) {
-        if (!writeInputEvent(EV_ABS, ABS_MT_TOUCH_MAJOR, majorAxisSize)) {
+        if (!writeInputEvent(EV_ABS, ABS_MT_TOUCH_MAJOR, majorAxisSize, eventTime)) {
             return false;
         }
     }
-    return writeInputEvent(EV_SYN, SYN_REPORT, 0);
+    return writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
 }
 
-bool VirtualTouchscreen::handleTouchUp(int32_t pointerId) {
-    if (!writeInputEvent(EV_ABS, ABS_MT_TRACKING_ID, static_cast<int32_t>(-1))) {
+bool VirtualTouchscreen::handleTouchUp(int32_t pointerId, std::chrono::nanoseconds eventTime) {
+    if (!writeInputEvent(EV_ABS, ABS_MT_TRACKING_ID, static_cast<int32_t>(-1), eventTime)) {
         return false;
     }
     // When a pointer is no longer in touch, remove the pointer id from the corresponding
@@ -347,7 +363,8 @@
 
     // Only sends the BTN UP event when there's no pointers on the touchscreen.
     if (mActivePointers.none()) {
-        if (!writeInputEvent(EV_KEY, BTN_TOUCH, static_cast<int32_t>(UinputAction::RELEASE))) {
+        if (!writeInputEvent(EV_KEY, BTN_TOUCH, static_cast<int32_t>(UinputAction::RELEASE),
+                             eventTime)) {
             return false;
         }
         ALOGD_IF(isDebug(), "No pointers on touchscreen %d, BTN UP event sent.", mFd.get());
@@ -355,12 +372,13 @@
     return true;
 }
 
-bool VirtualTouchscreen::handleTouchDown(int32_t pointerId) {
+bool VirtualTouchscreen::handleTouchDown(int32_t pointerId, std::chrono::nanoseconds eventTime) {
     // When a new pointer is down on the touchscreen, add the pointer id in the corresponding
     // entry in the unreleased touches map.
     if (mActivePointers.none()) {
         // Only sends the BTN Down event when the first pointer on the touchscreen is down.
-        if (!writeInputEvent(EV_KEY, BTN_TOUCH, static_cast<int32_t>(UinputAction::PRESS))) {
+        if (!writeInputEvent(EV_KEY, BTN_TOUCH, static_cast<int32_t>(UinputAction::PRESS),
+                             eventTime)) {
             return false;
         }
         ALOGD_IF(isDebug(), "First pointer %d down under touchscreen %d, BTN DOWN event sent",
@@ -369,7 +387,7 @@
 
     mActivePointers.set(pointerId);
     ALOGD_IF(isDebug(), "Added pointer %d under touchscreen %d in the map", pointerId, mFd.get());
-    if (!writeInputEvent(EV_ABS, ABS_MT_TRACKING_ID, static_cast<int32_t>(pointerId))) {
+    if (!writeInputEvent(EV_ABS, ABS_MT_TRACKING_ID, static_cast<int32_t>(pointerId), eventTime)) {
         return false;
     }
     return true;
diff --git a/libs/ultrahdr/include/ultrahdr/jpegrutils.h b/libs/ultrahdr/include/ultrahdr/jpegrutils.h
index ed38e07..4ab664e 100644
--- a/libs/ultrahdr/include/ultrahdr/jpegrutils.h
+++ b/libs/ultrahdr/include/ultrahdr/jpegrutils.h
@@ -102,7 +102,9 @@
  *     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  *     <rdf:Description
  *       xmlns:Container="http://ns.google.com/photos/1.0/container/"
- *       xmlns:Item="http://ns.google.com/photos/1.0/container/item/">
+ *       xmlns:Item="http://ns.google.com/photos/1.0/container/item/"
+ *       xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/"
+ *       hdrgm:Version="1">
  *       <Container:Directory>
  *         <rdf:Seq>
  *           <rdf:li
@@ -127,7 +129,8 @@
  * @param secondary_image_length length of secondary image
  * @return XMP metadata in type of string
  */
-std::string generateXmpForPrimaryImage(int secondary_image_length);
+std::string generateXmpForPrimaryImage(int secondary_image_length,
+                                       ultrahdr_metadata_struct& metadata);
 
 /*
  * This method generates XMP metadata for the recovery map image.
diff --git a/libs/ultrahdr/include/ultrahdr/ultrahdr.h b/libs/ultrahdr/include/ultrahdr/ultrahdr.h
index 302aeee..f970936 100644
--- a/libs/ultrahdr/include/ultrahdr/ultrahdr.h
+++ b/libs/ultrahdr/include/ultrahdr/ultrahdr.h
@@ -48,7 +48,7 @@
  */
 struct ultrahdr_metadata_struct {
   // Ultra HDR library version
-  uint32_t version;
+  const char* version;
   // Max Content Boost for the map
   float maxContentBoost;
   // Min Content Boost for the map
@@ -58,4 +58,4 @@
 
 }  // namespace android::ultrahdr
 
-#endif //ANDROID_ULTRAHDR_ULTRAHDR_H
\ No newline at end of file
+#endif //ANDROID_ULTRAHDR_ULTRAHDR_H
diff --git a/libs/ultrahdr/jpegr.cpp b/libs/ultrahdr/jpegr.cpp
index 5f55d1b..0f7aa27 100644
--- a/libs/ultrahdr/jpegr.cpp
+++ b/libs/ultrahdr/jpegr.cpp
@@ -61,7 +61,7 @@
   }
 
 // The current JPEGR version that we encode to
-static const uint32_t kJpegrVersion = 1;
+static const char* const kJpegrVersion = "1.0";
 
 // Map is quarter res / sixteenth size
 static const size_t kMapDimensionScaleFactor = 4;
@@ -943,7 +943,7 @@
                                  + xmp_secondary_length
                                  + compressed_gain_map->length;
   // primary image
-  const string xmp_primary = generateXmpForPrimaryImage(secondary_image_size);
+  const string xmp_primary = generateXmpForPrimaryImage(secondary_image_size, *metadata);
   // same as primary
   const int xmp_primary_length = 2 + nameSpaceLength + xmp_primary.size();
 
diff --git a/libs/ultrahdr/jpegrutils.cpp b/libs/ultrahdr/jpegrutils.cpp
index 9d07a6f..6430af1 100644
--- a/libs/ultrahdr/jpegrutils.cpp
+++ b/libs/ultrahdr/jpegrutils.cpp
@@ -302,7 +302,7 @@
     return true;
 }
 
-string generateXmpForPrimaryImage(int secondary_image_length) {
+string generateXmpForPrimaryImage(int secondary_image_length, ultrahdr_metadata_struct& metadata) {
   const vector<string> kConDirSeq({kConDirectory, string("rdf:Seq")});
   const vector<string> kLiItem({string("rdf:li"), kConItem});
 
@@ -316,6 +316,8 @@
   writer.StartWritingElement("rdf:Description");
   writer.WriteXmlns(kContainerPrefix, kContainerUri);
   writer.WriteXmlns(kItemPrefix, kItemUri);
+  writer.WriteXmlns(kGainMapPrefix, kGainMapUri);
+  writer.WriteAttributeNameAndValue(kMapVersion, metadata.version);
 
   writer.StartWritingElements(kConDirSeq);
 
diff --git a/libs/ultrahdr/tests/jpegr_test.cpp b/libs/ultrahdr/tests/jpegr_test.cpp
index ba3b4d0..58cd8f4 100644
--- a/libs/ultrahdr/tests/jpegr_test.cpp
+++ b/libs/ultrahdr/tests/jpegr_test.cpp
@@ -180,6 +180,7 @@
 
 TEST_F(JpegRTest, writeXmpThenRead) {
   ultrahdr_metadata_struct metadata_expected;
+  metadata_expected.version = "1.0";
   metadata_expected.maxContentBoost = 1.25;
   metadata_expected.minContentBoost = 0.75;
   const std::string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
@@ -538,7 +539,7 @@
 
   JpegRBenchmark benchmark;
 
-  ultrahdr_metadata_struct metadata = { .version = 1,
+  ultrahdr_metadata_struct metadata = { .version = "1.0",
                               .maxContentBoost = 8.0f,
                               .minContentBoost = 1.0f / 8.0f };
 
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index 73351c4..6303546 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -407,7 +407,7 @@
     inline const std::string getName() const { return mDevice.getName(); }
     inline const std::string getDescriptor() { return mDevice.getDescriptor(); }
     inline const std::string getLocation() { return mDevice.getLocation(); }
-    inline bool isExternal() { return mDevice.isExternal(); }
+    inline bool isExternal() const { return mDevice.isExternal(); }
     inline std::optional<uint8_t> getAssociatedDisplayPort() const {
         return mDevice.getAssociatedDisplayPort();
     }
@@ -424,7 +424,7 @@
         return mDevice.cancelTouch(when, readTime);
     }
     inline void bumpGeneration() { mDevice.bumpGeneration(); }
-    inline const PropertyMap& getConfiguration() { return mDevice.getConfiguration(); }
+    inline const PropertyMap& getConfiguration() const { return mDevice.getConfiguration(); }
 
 private:
     InputDevice& mDevice;
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 55b869a..c72a263 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -125,9 +125,8 @@
                                    const InputReaderConfiguration& readerConfig)
       : InputMapper(deviceContext, readerConfig),
         mTouchButtonAccumulator(deviceContext),
-        mSource(0),
-        mDeviceMode(DeviceMode::DISABLED),
-        mInputDeviceOrientation(ui::ROTATION_0) {}
+        mConfig(readerConfig),
+        mParameters(computeParameters(deviceContext)) {}
 
 TouchInputMapper::~TouchInputMapper() {}
 
@@ -300,7 +299,7 @@
     // various other parameters so should result in a reconfiguration.
     if (!changes.any() || changes.test(InputReaderConfiguration::Change::DEVICE_TYPE)) {
         // Configure basic parameters.
-        configureParameters();
+        mParameters = computeParameters(getDeviceContext());
 
         // Configure common accumulators.
         mCursorScrollAccumulator.configure(getDeviceContext());
@@ -361,112 +360,119 @@
     }
 }
 
-void TouchInputMapper::configureParameters() {
+TouchInputMapper::Parameters TouchInputMapper::computeParameters(
+        const InputDeviceContext& deviceContext) {
+    Parameters parameters;
     // Use the pointer presentation mode for devices that do not support distinct
     // multitouch.  The spot-based presentation relies on being able to accurately
     // locate two or more fingers on the touch pad.
-    mParameters.gestureMode = getDeviceContext().hasInputProperty(INPUT_PROP_SEMI_MT)
+    parameters.gestureMode = deviceContext.hasInputProperty(INPUT_PROP_SEMI_MT)
             ? Parameters::GestureMode::SINGLE_TOUCH
             : Parameters::GestureMode::MULTI_TOUCH;
 
-    const PropertyMap& config = getDeviceContext().getConfiguration();
+    const PropertyMap& config = deviceContext.getConfiguration();
     std::optional<std::string> gestureModeString = config.getString("touch.gestureMode");
     if (gestureModeString.has_value()) {
         if (*gestureModeString == "single-touch") {
-            mParameters.gestureMode = Parameters::GestureMode::SINGLE_TOUCH;
+            parameters.gestureMode = Parameters::GestureMode::SINGLE_TOUCH;
         } else if (*gestureModeString == "multi-touch") {
-            mParameters.gestureMode = Parameters::GestureMode::MULTI_TOUCH;
+            parameters.gestureMode = Parameters::GestureMode::MULTI_TOUCH;
         } else if (*gestureModeString != "default") {
             ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString->c_str());
         }
     }
 
-    configureDeviceType();
+    parameters.deviceType = computeDeviceType(deviceContext);
 
-    mParameters.hasButtonUnderPad = getDeviceContext().hasInputProperty(INPUT_PROP_BUTTONPAD);
+    parameters.hasButtonUnderPad = deviceContext.hasInputProperty(INPUT_PROP_BUTTONPAD);
 
-    mParameters.orientationAware =
+    parameters.orientationAware =
             config.getBool("touch.orientationAware")
-                    .value_or(mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN);
+                    .value_or(parameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN);
 
-    mParameters.orientation = ui::ROTATION_0;
+    parameters.orientation = ui::ROTATION_0;
     std::optional<std::string> orientationString = config.getString("touch.orientation");
     if (orientationString.has_value()) {
-        if (mParameters.deviceType != Parameters::DeviceType::TOUCH_SCREEN) {
+        if (parameters.deviceType != Parameters::DeviceType::TOUCH_SCREEN) {
             ALOGW("The configuration 'touch.orientation' is only supported for touchscreens.");
         } else if (*orientationString == "ORIENTATION_90") {
-            mParameters.orientation = ui::ROTATION_90;
+            parameters.orientation = ui::ROTATION_90;
         } else if (*orientationString == "ORIENTATION_180") {
-            mParameters.orientation = ui::ROTATION_180;
+            parameters.orientation = ui::ROTATION_180;
         } else if (*orientationString == "ORIENTATION_270") {
-            mParameters.orientation = ui::ROTATION_270;
+            parameters.orientation = ui::ROTATION_270;
         } else if (*orientationString != "ORIENTATION_0") {
             ALOGW("Invalid value for touch.orientation: '%s'", orientationString->c_str());
         }
     }
 
-    mParameters.hasAssociatedDisplay = false;
-    mParameters.associatedDisplayIsExternal = false;
-    if (mParameters.orientationAware ||
-        mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN ||
-        mParameters.deviceType == Parameters::DeviceType::POINTER ||
-        (mParameters.deviceType == Parameters::DeviceType::TOUCH_NAVIGATION &&
-         getDeviceContext().getAssociatedViewport())) {
-        mParameters.hasAssociatedDisplay = true;
-        if (mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN) {
-            mParameters.associatedDisplayIsExternal = getDeviceContext().isExternal();
-            mParameters.uniqueDisplayId = config.getString("touch.displayId").value_or("").c_str();
+    parameters.hasAssociatedDisplay = false;
+    parameters.associatedDisplayIsExternal = false;
+    if (parameters.orientationAware ||
+        parameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN ||
+        parameters.deviceType == Parameters::DeviceType::POINTER ||
+        (parameters.deviceType == Parameters::DeviceType::TOUCH_NAVIGATION &&
+         deviceContext.getAssociatedViewport())) {
+        parameters.hasAssociatedDisplay = true;
+        if (parameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN) {
+            parameters.associatedDisplayIsExternal = deviceContext.isExternal();
+            parameters.uniqueDisplayId = config.getString("touch.displayId").value_or("").c_str();
         }
     }
-    if (getDeviceContext().getAssociatedDisplayPort()) {
-        mParameters.hasAssociatedDisplay = true;
+    if (deviceContext.getAssociatedDisplayPort()) {
+        parameters.hasAssociatedDisplay = true;
     }
 
     // Initial downs on external touch devices should wake the device.
     // Normally we don't do this for internal touch screens to prevent them from waking
     // up in your pocket but you can enable it using the input device configuration.
-    mParameters.wake = config.getBool("touch.wake").value_or(getDeviceContext().isExternal());
+    parameters.wake = config.getBool("touch.wake").value_or(deviceContext.isExternal());
 
     std::optional<int32_t> usiVersionMajor = config.getInt("touch.usiVersionMajor");
     std::optional<int32_t> usiVersionMinor = config.getInt("touch.usiVersionMinor");
     if (usiVersionMajor.has_value() && usiVersionMinor.has_value()) {
-        mParameters.usiVersion = {
+        parameters.usiVersion = {
                 .majorVersion = *usiVersionMajor,
                 .minorVersion = *usiVersionMinor,
         };
     }
 
-    mParameters.enableForInactiveViewport =
+    parameters.enableForInactiveViewport =
             config.getBool("touch.enableForInactiveViewport").value_or(false);
+
+    return parameters;
 }
 
-void TouchInputMapper::configureDeviceType() {
-    if (getDeviceContext().hasInputProperty(INPUT_PROP_DIRECT)) {
+TouchInputMapper::Parameters::DeviceType TouchInputMapper::computeDeviceType(
+        const InputDeviceContext& deviceContext) {
+    Parameters::DeviceType deviceType;
+    if (deviceContext.hasInputProperty(INPUT_PROP_DIRECT)) {
         // The device is a touch screen.
-        mParameters.deviceType = Parameters::DeviceType::TOUCH_SCREEN;
-    } else if (getDeviceContext().hasInputProperty(INPUT_PROP_POINTER)) {
+        deviceType = Parameters::DeviceType::TOUCH_SCREEN;
+    } else if (deviceContext.hasInputProperty(INPUT_PROP_POINTER)) {
         // The device is a pointing device like a track pad.
-        mParameters.deviceType = Parameters::DeviceType::POINTER;
+        deviceType = Parameters::DeviceType::POINTER;
     } else {
         // The device is a touch pad of unknown purpose.
-        mParameters.deviceType = Parameters::DeviceType::POINTER;
+        deviceType = Parameters::DeviceType::POINTER;
     }
 
     // Type association takes precedence over the device type found in the idc file.
-    std::string deviceTypeString = getDeviceContext().getDeviceTypeAssociation().value_or("");
+    std::string deviceTypeString = deviceContext.getDeviceTypeAssociation().value_or("");
     if (deviceTypeString.empty()) {
         deviceTypeString =
-                getDeviceContext().getConfiguration().getString("touch.deviceType").value_or("");
+                deviceContext.getConfiguration().getString("touch.deviceType").value_or("");
     }
     if (deviceTypeString == "touchScreen") {
-        mParameters.deviceType = Parameters::DeviceType::TOUCH_SCREEN;
+        deviceType = Parameters::DeviceType::TOUCH_SCREEN;
     } else if (deviceTypeString == "touchNavigation") {
-        mParameters.deviceType = Parameters::DeviceType::TOUCH_NAVIGATION;
+        deviceType = Parameters::DeviceType::TOUCH_NAVIGATION;
     } else if (deviceTypeString == "pointer") {
-        mParameters.deviceType = Parameters::DeviceType::POINTER;
+        deviceType = Parameters::DeviceType::POINTER;
     } else if (deviceTypeString != "default" && deviceTypeString != "") {
         ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.c_str());
     }
+    return deviceType;
 }
 
 void TouchInputMapper::dumpParameters(std::string& dump) {
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index e023e90..7141924 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -192,7 +192,7 @@
     };
 
     // Input sources and device mode.
-    uint32_t mSource;
+    uint32_t mSource{0};
 
     enum class DeviceMode {
         DISABLED,   // input is disabled
@@ -203,7 +203,7 @@
 
         ftl_last = POINTER
     };
-    DeviceMode mDeviceMode;
+    DeviceMode mDeviceMode{DeviceMode::DISABLED};
 
     // The reader's configuration.
     InputReaderConfiguration mConfig;
@@ -377,7 +377,6 @@
 
     std::vector<VirtualKey> mVirtualKeys;
 
-    virtual void configureParameters();
     virtual void dumpParameters(std::string& dump);
     virtual void configureRawPointerAxes();
     virtual void dumpRawPointerAxes(std::string& dump);
@@ -413,7 +412,7 @@
     // The orientation of the input device relative to that of the display panel. It specifies
     // the rotation of the input device coordinates required to produce the display panel
     // orientation, so it will depend on whether the device is orientation aware.
-    ui::Rotation mInputDeviceOrientation;
+    ui::Rotation mInputDeviceOrientation{ui::ROTATION_0};
 
     // The transform that maps the input device's raw coordinate space to the un-rotated display's
     // coordinate space. InputReader generates events in the un-rotated display's coordinate space.
@@ -824,8 +823,8 @@
 
     // Compute input transforms for DIRECT and POINTER modes.
     void computeInputTransforms();
-
-    void configureDeviceType();
+    static Parameters::DeviceType computeDeviceType(const InputDeviceContext& deviceContext);
+    static Parameters computeParameters(const InputDeviceContext& deviceContext);
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 8ddcfa1..3e12db6 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -130,7 +130,7 @@
 
         pacesetterVsyncSchedule = promotePacesetterDisplayLocked();
     }
-    applyNewVsyncScheduleIfNonNull(std::move(pacesetterVsyncSchedule));
+    applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
 }
 
 void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) {
@@ -149,7 +149,7 @@
 
         pacesetterVsyncSchedule = promotePacesetterDisplayLocked();
     }
-    applyNewVsyncScheduleIfNonNull(std::move(pacesetterVsyncSchedule));
+    applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
 }
 
 void Scheduler::run() {
@@ -693,17 +693,16 @@
         pacesetterVsyncSchedule = promotePacesetterDisplayLocked(pacesetterIdOpt);
     }
 
-    applyNewVsyncScheduleIfNonNull(std::move(pacesetterVsyncSchedule));
+    applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
 }
 
 std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked(
         std::optional<PhysicalDisplayId> pacesetterIdOpt) {
     // TODO(b/241286431): Choose the pacesetter display.
-    const auto oldPacesetterDisplayIdOpt = mPacesetterDisplayId;
     mPacesetterDisplayId = pacesetterIdOpt.value_or(mRefreshRateSelectors.begin()->first);
     ALOGI("Display %s is the pacesetter", to_string(*mPacesetterDisplayId).c_str());
 
-    auto newVsyncSchedule = getVsyncScheduleLocked(*mPacesetterDisplayId);
+    auto vsyncSchedule = getVsyncScheduleLocked(*mPacesetterDisplayId);
     if (const auto pacesetterPtr = pacesetterSelectorPtrLocked()) {
         pacesetterPtr->setIdleTimerCallbacks(
                 {.platform = {.onReset = [this] { idleTimerCallback(TimerState::Reset); },
@@ -714,28 +713,15 @@
 
         pacesetterPtr->startIdleTimer();
 
-        // Track the new period, which may have changed due to switching to a
-        // new pacesetter or due to a hotplug event. In the former case, this
-        // is important so that VSYNC modulation does not get stuck in the
-        // initiated state if a transition started on the old pacesetter.
         const Fps refreshRate = pacesetterPtr->getActiveMode().modePtr->getFps();
-        newVsyncSchedule->startPeriodTransition(mSchedulerCallback, refreshRate.getPeriod(),
-                                                true /* force */);
+        vsyncSchedule->startPeriodTransition(mSchedulerCallback, refreshRate.getPeriod(),
+                                             true /* force */);
     }
-    if (oldPacesetterDisplayIdOpt == mPacesetterDisplayId) {
-        return nullptr;
-    }
-    return newVsyncSchedule;
+    return vsyncSchedule;
 }
 
-void Scheduler::applyNewVsyncScheduleIfNonNull(
-        std::shared_ptr<VsyncSchedule> pacesetterSchedulePtr) {
-    if (!pacesetterSchedulePtr) {
-        // The pacesetter has not changed, so there is no new VsyncSchedule to
-        // apply.
-        return;
-    }
-    onNewVsyncSchedule(pacesetterSchedulePtr->getDispatch());
+void Scheduler::applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule> vsyncSchedule) {
+    onNewVsyncSchedule(vsyncSchedule->getDispatch());
     std::vector<android::EventThread*> threads;
     {
         std::lock_guard<std::mutex> lock(mConnectionsLock);
@@ -745,7 +731,7 @@
         }
     }
     for (auto* thread : threads) {
-        thread->onNewVsyncSchedule(pacesetterSchedulePtr);
+        thread->onNewVsyncSchedule(vsyncSchedule);
     }
 }
 
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 4b2983b..1f6d378 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -330,12 +330,10 @@
     // MessageQueue and EventThread need to use the new pacesetter's
     // VsyncSchedule, and this must happen while mDisplayLock is *not* locked,
     // or else we may deadlock with EventThread.
-    // Returns the new pacesetter's VsyncSchedule, or null if the pacesetter is
-    // unchanged.
     std::shared_ptr<VsyncSchedule> promotePacesetterDisplayLocked(
             std::optional<PhysicalDisplayId> pacesetterIdOpt = std::nullopt)
             REQUIRES(kMainThreadContext, mDisplayLock);
-    void applyNewVsyncScheduleIfNonNull(std::shared_ptr<VsyncSchedule>) EXCLUDES(mDisplayLock);
+    void applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule>) EXCLUDES(mDisplayLock);
 
     // Blocks until the pacesetter's idle timer thread exits. `mDisplayLock` must not be locked by
     // the caller on the main thread to avoid deadlock, since the timer thread locks it before exit.
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 0c43831..dc76b4c 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -384,23 +384,4 @@
     }
 }
 
-TEST_F(SchedulerTest, changingPacesetterChangesVsyncSchedule) {
-    // Add a second display so we can change the pacesetter.
-    mScheduler->registerDisplay(kDisplayId2,
-                                std::make_shared<RefreshRateSelector>(kDisplay2Modes,
-                                                                      kDisplay2Mode60->getId()));
-    // Ensure that the pacesetter is the one we expect.
-    mScheduler->setPacesetterDisplay(kDisplayId1);
-
-    // Switching to the other will call onNewVsyncSchedule.
-    EXPECT_CALL(*mEventThread, onNewVsyncSchedule(mScheduler->getVsyncSchedule(kDisplayId2)))
-            .Times(1);
-    mScheduler->setPacesetterDisplay(kDisplayId2);
-}
-
-TEST_F(SchedulerTest, promotingSamePacesetterDoesNotChangeVsyncSchedule) {
-    EXPECT_CALL(*mEventThread, onNewVsyncSchedule(_)).Times(0);
-    mScheduler->setPacesetterDisplay(kDisplayId1);
-}
-
 } // namespace android::scheduler