Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8a42794 authored by Harry Cutts's avatar Harry Cutts Committed by Android (Google) Code Review
Browse files

Merge "Support touchpad gesture properties in IDC files" into udc-dev

parents 31769c20 3ca39d03
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@

#include <android-base/result.h>
#include <utils/Tokenizer.h>

#include <string>
#include <unordered_map>
#include <unordered_set>

namespace android {

@@ -57,6 +60,9 @@ public:
     */
    void addProperty(const std::string& key, const std::string& value);

    /* Returns a set of all property keys starting with the given prefix. */
    std::unordered_set<std::string> getKeysWithPrefix(const std::string& prefix) const;

    /* Gets the value of a property and parses it.
     * Returns true and sets outValue if the key was found and its value was parsed successfully.
     * Otherwise returns false and does not modify outValue.  (Also logs a warning.)
@@ -65,6 +71,7 @@ public:
    bool tryGetProperty(const std::string& key, bool& outValue) const;
    bool tryGetProperty(const std::string& key, int32_t& outValue) const;
    bool tryGetProperty(const std::string& key, float& outValue) const;
    bool tryGetProperty(const std::string& key, double& outValue) const;

    /* Adds all values from the specified property map. */
    void addAll(const PropertyMap* map);
+1 −0
Original line number Diff line number Diff line
@@ -167,6 +167,7 @@ cc_library {

cc_defaults {
    name: "libinput_fuzz_defaults",
    cpp_std: "c++20",
    host_supported: true,
    shared_libs: [
        "libutils",
+29 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

#define LOG_TAG "PropertyMap"

#include <cstdlib>

#include <input/PropertyMap.h>
#include <log/log.h>

@@ -44,6 +46,16 @@ void PropertyMap::addProperty(const std::string& key, const std::string& value)
    mProperties.emplace(key, value);
}

std::unordered_set<std::string> PropertyMap::getKeysWithPrefix(const std::string& prefix) const {
    std::unordered_set<std::string> keys;
    for (const auto& [key, _] : mProperties) {
        if (key.starts_with(prefix)) {
            keys.insert(key);
        }
    }
    return keys;
}

bool PropertyMap::hasProperty(const std::string& key) const {
    return mProperties.find(key) != mProperties.end();
}
@@ -102,6 +114,23 @@ bool PropertyMap::tryGetProperty(const std::string& key, float& outValue) const
    return true;
}

bool PropertyMap::tryGetProperty(const std::string& key, double& outValue) const {
    std::string stringValue;
    if (!tryGetProperty(key, stringValue) || stringValue.length() == 0) {
        return false;
    }

    char* end;
    double value = strtod(stringValue.c_str(), &end);
    if (*end != '\0') {
        ALOGW("Property key '%s' has invalid value '%s'.  Expected a double.", key.c_str(),
              stringValue.c_str());
        return false;
    }
    outValue = value;
    return true;
}

void PropertyMap::addAll(const PropertyMap* map) {
    for (const auto& [key, value] : map->mProperties) {
        mProperties.emplace(key, value);
+6 −0
Original line number Diff line number Diff line
@@ -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 @@ void TouchpadInputMapper::dump(std::string& dump) {
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;
+76 −0
Original line number Diff line number Diff line
@@ -84,6 +84,29 @@ std::string PropertyProvider::dump() const {
    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 @@ void GesturesProp::setRealValues(const std::vector<double>& values) {
    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) {
Loading