Revert^2 "Support touchpad gesture properties in IDC files"

a53cb97af2b4cbb247094d6be93583712dbee3c4

Change-Id: I5463f938665212362b8780e1c646a4b2bf8ad10a
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
index d3af402..3309767 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
@@ -20,6 +20,7 @@
 #include <optional>
 
 #include <android/input.h>
+#include <ftl/enum.h>
 #include <input/PrintTools.h>
 #include <linux/input-event-codes.h>
 #include <log/log_main.h>
@@ -216,6 +217,11 @@
 std::list<NotifyArgs> TouchpadInputMapper::configure(nsecs_t when,
                                                      const InputReaderConfiguration* config,
                                                      uint32_t changes) {
+    if (!changes) {
+        // First time configuration
+        mPropertyProvider.loadPropertiesFromIdcFile(getDeviceContext().getConfiguration());
+    }
+
     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
         std::optional<int32_t> displayId = mPointerController->getDisplayId();
         ui::Rotation orientation = ui::ROTATION_0;
diff --git a/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp b/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp
index 089f45a..3d88338 100644
--- a/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp
+++ b/services/inputflinger/reader/mapper/gestures/PropertyProvider.cpp
@@ -84,6 +84,29 @@
     return dump;
 }
 
+void PropertyProvider::loadPropertiesFromIdcFile(const PropertyMap& idcProperties) {
+    // For compatibility with the configuration file syntax, gesture property names in IDC files are
+    // prefixed with "gestureProp." and have spaces replaced by underscores. So, for example, the
+    // configuration key "gestureProp.Palm_Width" refers to the "Palm Width" property.
+    const std::string gesturePropPrefix = "gestureProp.";
+    for (const std::string key : idcProperties.getKeysWithPrefix(gesturePropPrefix)) {
+        std::string propertyName = key.substr(gesturePropPrefix.length());
+        for (size_t i = 0; i < propertyName.length(); i++) {
+            if (propertyName[i] == '_') {
+                propertyName[i] = ' ';
+            }
+        }
+
+        auto it = mProperties.find(propertyName);
+        if (it != mProperties.end()) {
+            it->second.trySetFromIdcProperty(idcProperties, key);
+        } else {
+            ALOGE("Gesture property \"%s\" specified in IDC file does not exist for this device.",
+                  propertyName.c_str());
+        }
+    }
+}
+
 GesturesProp* PropertyProvider::createIntArrayProperty(const std::string& name, int* loc,
                                                        size_t count, const int* init) {
     const auto [it, inserted] =
@@ -211,6 +234,59 @@
     setValues(std::get<double*>(mDataPointer), values);
 }
 
+namespace {
+
+// Helper to std::visit with lambdas.
+template <typename... V>
+struct Visitor : V... {};
+// explicit deduction guide (not needed as of C++20)
+template <typename... V>
+Visitor(V...) -> Visitor<V...>;
+
+} // namespace
+
+void GesturesProp::trySetFromIdcProperty(const android::PropertyMap& idcProperties,
+                                         const std::string& propertyName) {
+    if (mCount != 1) {
+        ALOGE("Gesture property \"%s\" is an array, and so cannot be set in an IDC file.",
+              mName.c_str());
+        return;
+    }
+    bool parsedSuccessfully = false;
+    Visitor setVisitor{
+            [&](int*) {
+                int32_t value;
+                parsedSuccessfully = idcProperties.tryGetProperty(propertyName, value);
+                if (parsedSuccessfully) {
+                    setIntValues({value});
+                }
+            },
+            [&](GesturesPropBool*) {
+                bool value;
+                parsedSuccessfully = idcProperties.tryGetProperty(propertyName, value);
+                if (parsedSuccessfully) {
+                    setBoolValues({value});
+                }
+            },
+            [&](double*) {
+                double value;
+                parsedSuccessfully = idcProperties.tryGetProperty(propertyName, value);
+                if (parsedSuccessfully) {
+                    setRealValues({value});
+                }
+            },
+            [&](const char**) {
+                ALOGE("Gesture property \"%s\" is a string, and so cannot be set in an IDC file.",
+                      mName.c_str());
+            },
+    };
+    std::visit(setVisitor, mDataPointer);
+
+    ALOGE_IF(!parsedSuccessfully, "Gesture property \"%s\" could set due to a type mismatch.",
+             mName.c_str());
+    return;
+}
+
 template <typename T, typename U>
 const std::vector<T> GesturesProp::getValues(U* dataPointer) const {
     if (mGetter != nullptr) {
diff --git a/services/inputflinger/reader/mapper/gestures/PropertyProvider.h b/services/inputflinger/reader/mapper/gestures/PropertyProvider.h
index 50451a3..c7e0858 100644
--- a/services/inputflinger/reader/mapper/gestures/PropertyProvider.h
+++ b/services/inputflinger/reader/mapper/gestures/PropertyProvider.h
@@ -22,6 +22,7 @@
 #include <vector>
 
 #include "include/gestures.h"
+#include "input/PropertyMap.h"
 
 namespace android {
 
@@ -35,6 +36,8 @@
     GesturesProp& getProperty(const std::string& name);
     std::string dump() const;
 
+    void loadPropertiesFromIdcFile(const PropertyMap& idcProperties);
+
     // Methods to be called by the gestures library:
     GesturesProp* createIntArrayProperty(const std::string& name, int* loc, size_t count,
                                          const int* init);
@@ -83,6 +86,9 @@
     // Setting string values isn't supported since we don't have a use case yet and the memory
     // management adds additional complexity.
 
+    void trySetFromIdcProperty(const android::PropertyMap& idcProperties,
+                               const std::string& propertyName);
+
 private:
     // Two type parameters are required for these methods, rather than one, due to the gestures
     // library using its own bool type.