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

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

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

parents 5c82ee16 2b67ff1b
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