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

Commit 6f8b77e3 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari Committed by Android (Google) Code Review
Browse files

Merge "Add support for detecting Keyboard backlight using sysfs node"

parents 77d20867 82b37d6e
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#pragma once

#include <android/sensor.h>
#include <ftl/flags.h>
#include <input/Input.h>
#include <input/KeyCharacterMap.h>
#include <unordered_map>
@@ -105,12 +106,18 @@ enum class InputDeviceSensorReportingMode : int32_t {
};

enum class InputDeviceLightType : int32_t {
    MONO = 0,
    INPUT = 0,
    PLAYER_ID = 1,
    RGB = 2,
    MULTI_COLOR = 3,
    KEYBOARD_BACKLIGHT = 2,

    ftl_last = MULTI_COLOR
    ftl_last = KEYBOARD_BACKLIGHT
};

enum class InputDeviceLightCapability : uint32_t {
    /** Capability to change brightness of the light */
    BRIGHTNESS = 0x00000001,
    /** Capability to change color of the light */
    RGB = 0x00000002,
};

struct InputDeviceSensorInfo {
@@ -171,14 +178,17 @@ struct InputDeviceSensorInfo {

struct InputDeviceLightInfo {
    explicit InputDeviceLightInfo(std::string name, int32_t id, InputDeviceLightType type,
                                  ftl::Flags<InputDeviceLightCapability> capabilityFlags,
                                  int32_t ordinal)
          : name(name), id(id), type(type), ordinal(ordinal) {}
          : name(name), id(id), type(type), capabilityFlags(capabilityFlags), ordinal(ordinal) {}
    // Name string of the light.
    std::string name;
    // Light id
    int32_t id;
    // Type of the light.
    InputDeviceLightType type;
    // Light capabilities.
    ftl::Flags<InputDeviceLightCapability> capabilityFlags;
    // Ordinal of the light
    int32_t ordinal;
};
+21 −9
Original line number Diff line number Diff line
@@ -117,7 +117,8 @@ static const std::unordered_map<std::string, InputLightClass> LIGHT_CLASSES =
         {"brightness", InputLightClass::BRIGHTNESS},
         {"multi_index", InputLightClass::MULTI_INDEX},
         {"multi_intensity", InputLightClass::MULTI_INTENSITY},
         {"max_brightness", InputLightClass::MAX_BRIGHTNESS}};
         {"max_brightness", InputLightClass::MAX_BRIGHTNESS},
         {"kbd_backlight", InputLightClass::KEYBOARD_BACKLIGHT}};

// Mapping for input multicolor led class node names.
// https://www.kernel.org/doc/html/latest/leds/leds-class-multicolor.html
@@ -365,16 +366,27 @@ static std::unordered_map<int32_t /*lightId*/, RawLightInfo> readLightsConfigura
        info.path = nodePath;
        info.name = nodePath.filename();
        info.maxBrightness = std::nullopt;
        size_t nameStart = info.name.rfind(":");
        if (nameStart != std::string::npos) {
            // Trim the name to color name
            info.name = info.name.substr(nameStart + 1);
            // Set InputLightClass flag for colors
            const auto it = LIGHT_CLASSES.find(info.name);

        // Light name should follow the naming pattern <name>:<color>:<function>
        // Refer kernel docs /leds/leds-class.html for valid supported LED names.
        std::regex indexPattern("([a-zA-Z0-9_.:]*:)?([a-zA-Z0-9_.]*):([a-zA-Z0-9_.]*)");
        std::smatch results;

        if (std::regex_match(info.name, results, indexPattern)) {
            // regex_match will return full match at index 0 and <name> at index 1. For RawLightInfo
            // we only care about sections <color> and <function> which will be at index 2 and 3.
            for (int i = 2; i <= 3; i++) {
                const auto it = LIGHT_CLASSES.find(results.str(i));
                if (it != LIGHT_CLASSES.end()) {
                    info.flags |= it->second;
                }
            }

            // Set name of the raw light to <function> which represents playerIDs for LEDs that
            // turn on/off based on the current player ID (Refer to PeripheralController.cpp for
            // player ID logic)
            info.name = results.str(3);
        }
        // Scan the path for all the files
        // Refer to https://www.kernel.org/doc/Documentation/leds/leds-class.txt
        const auto& files = allFilesInPath(nodePath);
+33 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include <locale>
#include <regex>
#include <set>

#include <ftl/enum.h>

@@ -70,7 +71,7 @@ std::optional<std::int32_t> PeripheralController::Light::getRawLightBrightness(i

    // If the light node doesn't have max brightness, use the default max brightness.
    int rawMaxBrightness = rawInfoOpt->maxBrightness.value_or(MAX_BRIGHTNESS);
    float ratio = MAX_BRIGHTNESS / rawMaxBrightness;
    float ratio = static_cast<float>(MAX_BRIGHTNESS) / rawMaxBrightness;
    // Scale the returned brightness in [0, rawMaxBrightness] to [0, 255]
    if (rawMaxBrightness != MAX_BRIGHTNESS) {
        brightness = brightness * ratio;
@@ -89,7 +90,7 @@ void PeripheralController::Light::setRawLightBrightness(int32_t rawLightId, int3
    }
    // If the light node doesn't have max brightness, use the default max brightness.
    int rawMaxBrightness = rawInfo->maxBrightness.value_or(MAX_BRIGHTNESS);
    float ratio = MAX_BRIGHTNESS / rawMaxBrightness;
    float ratio = static_cast<float>(MAX_BRIGHTNESS) / rawMaxBrightness;
    // Scale the requested brightness in [0, 255] to [0, rawMaxBrightness]
    if (rawMaxBrightness != MAX_BRIGHTNESS) {
        brightness = ceil(brightness / ratio);
@@ -271,7 +272,8 @@ void PeripheralController::populateDeviceInfo(InputDeviceInfo* deviceInfo) {

    for (const auto& [lightId, light] : mLights) {
        // Input device light doesn't support ordinal, always pass 1.
        InputDeviceLightInfo lightInfo(light->name, light->id, light->type, 1 /* ordinal */);
        InputDeviceLightInfo lightInfo(light->name, light->id, light->type, light->capabilityFlags,
                                       1 /* ordinal */);
        deviceInfo->addLightInfo(lightInfo);
    }
}
@@ -284,6 +286,8 @@ void PeripheralController::dump(std::string& dump) {
            dump += StringPrintf(INDENT4 "Id: %d", lightId);
            dump += StringPrintf(INDENT4 "Name: %s", light->name.c_str());
            dump += StringPrintf(INDENT4 "Type: %s", ftl::enum_string(light->type).c_str());
            dump += StringPrintf(INDENT4 "Capability flags: %s",
                                 light->capabilityFlags.string().c_str());
            light->dump(dump);
        }
    }
@@ -363,6 +367,8 @@ void PeripheralController::configureLights() {
    std::unordered_map<LightColor, int32_t /* rawLightId */> rawRgbIds;
    // Map from player Id to raw light Id
    std::unordered_map<int32_t, int32_t> playerIdLightIds;
    // Set of Keyboard backlights
    std::set<int32_t> keyboardBacklightIds;

    // Check raw lights
    const std::vector<int32_t> rawLightIds = getDeviceContext().getRawLightIds();
@@ -391,6 +397,10 @@ void PeripheralController::configureLights() {
                }
            }
        }
        // Check if this is a Keyboard backlight
        if (rawInfo->flags.test(InputLightClass::KEYBOARD_BACKLIGHT)) {
            keyboardBacklightIds.insert(rawId);
        }
        // Check if this is an LED of RGB light
        if (rawInfo->flags.test(InputLightClass::RED)) {
            hasRedLed = true;
@@ -431,8 +441,21 @@ void PeripheralController::configureLights() {
            ALOGD("Rgb light ids [%d, %d, %d] \n", rawRgbIds.at(LightColor::RED),
                  rawRgbIds.at(LightColor::GREEN), rawRgbIds.at(LightColor::BLUE));
        }
        bool isKeyboardBacklight = keyboardBacklightIds.find(rawRgbIds.at(LightColor::RED)) !=
                        keyboardBacklightIds.end() &&
                keyboardBacklightIds.find(rawRgbIds.at(LightColor::GREEN)) !=
                        keyboardBacklightIds.end() &&
                keyboardBacklightIds.find(rawRgbIds.at(LightColor::BLUE)) !=
                        keyboardBacklightIds.end() &&
                (!rawGlobalId.has_value() ||
                 keyboardBacklightIds.find(rawGlobalId.value()) != keyboardBacklightIds.end());

        std::unique_ptr<Light> light =
                std::make_unique<RgbLight>(getDeviceContext(), ++mNextId, rawRgbIds, rawGlobalId);
                std::make_unique<RgbLight>(getDeviceContext(), ++mNextId,
                                           isKeyboardBacklight
                                                   ? InputDeviceLightType::KEYBOARD_BACKLIGHT
                                                   : InputDeviceLightType::INPUT,
                                           rawRgbIds, rawGlobalId);
        mLights.insert_or_assign(light->id, std::move(light));
        // Remove from raw light info as they've been composed a RBG light.
        rawInfos.erase(rawRgbIds.at(LightColor::RED));
@@ -445,6 +468,10 @@ void PeripheralController::configureLights() {

    // Check the rest of raw light infos
    for (const auto& [rawId, rawInfo] : rawInfos) {
        InputDeviceLightType type = keyboardBacklightIds.find(rawId) != keyboardBacklightIds.end()
                ? InputDeviceLightType::KEYBOARD_BACKLIGHT
                : InputDeviceLightType::INPUT;

        // If the node is multi-color led, construct a MULTI_COLOR light
        if (rawInfo.flags.test(InputLightClass::MULTI_INDEX) &&
            rawInfo.flags.test(InputLightClass::MULTI_INTENSITY)) {
@@ -453,7 +480,7 @@ void PeripheralController::configureLights() {
            }
            std::unique_ptr<Light> light =
                    std::make_unique<MultiColorLight>(getDeviceContext(), rawInfo.name, ++mNextId,
                                                      rawInfo.id);
                                                      type, rawInfo.id);
            mLights.insert_or_assign(light->id, std::move(light));
            continue;
        }
@@ -462,7 +489,7 @@ void PeripheralController::configureLights() {
            ALOGD("Mono light Id %d name %s \n", rawInfo.id, rawInfo.name.c_str());
        }
        std::unique_ptr<Light> light = std::make_unique<MonoLight>(getDeviceContext(), rawInfo.name,
                                                                   ++mNextId, rawInfo.id);
                                                                   ++mNextId, type, rawInfo.id);

        mLights.insert_or_assign(light->id, std::move(light));
    }
+15 −9
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ private:
        std::string name;
        int32_t id;
        InputDeviceLightType type;
        ftl::Flags<InputDeviceLightCapability> capabilityFlags;

        virtual bool setLightColor(int32_t color) { return false; }
        virtual std::optional<int32_t> getLightColor() { return std::nullopt; }
@@ -81,8 +82,10 @@ private:

    struct MonoLight : public Light {
        explicit MonoLight(InputDeviceContext& context, const std::string& name, int32_t id,
                           int32_t rawId)
              : Light(context, name, id, InputDeviceLightType::MONO), rawId(rawId) {}
                           InputDeviceLightType type, int32_t rawId)
              : Light(context, name, id, type), rawId(rawId) {
            capabilityFlags |= InputDeviceLightCapability::BRIGHTNESS;
        }
        int32_t rawId;

        bool setLightColor(int32_t color) override;
@@ -91,15 +94,15 @@ private:
    };

    struct RgbLight : public Light {
        explicit RgbLight(InputDeviceContext& context, int32_t id,
        explicit RgbLight(InputDeviceContext& context, int32_t id, InputDeviceLightType type,
                          const std::unordered_map<LightColor, int32_t>& rawRgbIds,
                          std::optional<int32_t> rawGlobalId)
              : Light(context, "RGB", id, InputDeviceLightType::RGB),
                rawRgbIds(rawRgbIds),
                rawGlobalId(rawGlobalId) {
              : Light(context, "RGB", id, type), rawRgbIds(rawRgbIds), rawGlobalId(rawGlobalId) {
            brightness = rawGlobalId.has_value()
                    ? getRawLightBrightness(rawGlobalId.value()).value_or(MAX_BRIGHTNESS)
                    : MAX_BRIGHTNESS;
            capabilityFlags |= InputDeviceLightCapability::BRIGHTNESS;
            capabilityFlags |= InputDeviceLightCapability::RGB;
        }
        // Map from color to raw light id.
        std::unordered_map<LightColor, int32_t /* rawLightId */> rawRgbIds;
@@ -114,8 +117,11 @@ private:

    struct MultiColorLight : public Light {
        explicit MultiColorLight(InputDeviceContext& context, const std::string& name, int32_t id,
                                 int32_t rawId)
              : Light(context, name, id, InputDeviceLightType::MULTI_COLOR), rawId(rawId) {}
                                 InputDeviceLightType type, int32_t rawId)
              : Light(context, name, id, type), rawId(rawId) {
            capabilityFlags |= InputDeviceLightCapability::BRIGHTNESS;
            capabilityFlags |= InputDeviceLightCapability::RGB;
        }
        int32_t rawId;

        bool setLightColor(int32_t color) override;
@@ -131,7 +137,7 @@ private:
        // Map from player Id to raw light Id
        std::unordered_map<int32_t, int32_t> rawLightIds;

        bool setLightPlayerId(int32_t palyerId) override;
        bool setLightPlayerId(int32_t playerId) override;
        std::optional<int32_t> getLightPlayerId() override;
        void dump(std::string& dump) override;
    };
+2 −0
Original line number Diff line number Diff line
@@ -174,6 +174,8 @@ enum class InputLightClass : uint32_t {
    MULTI_INTENSITY = 0x00000040,
    /* The input light has max brightness node. */
    MAX_BRIGHTNESS = 0x00000080,
    /* The input light has kbd_backlight name */
    KEYBOARD_BACKLIGHT = 0x00000100,
};

enum class InputBatteryClass : uint32_t {
Loading