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

Commit 16c24197 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari
Browse files

Read IDC file to check custom keyboard backlight levels

Test: atest inputflinger_tests
Bug: 280797494
Change-Id: Ia5d862c1fefceeb2a7fc09a86336198543b13b29
parent b2262b9d
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -18,8 +18,10 @@

#include <android/sensor.h>
#include <ftl/flags.h>
#include <ftl/mixins.h>
#include <input/Input.h>
#include <input/KeyCharacterMap.h>
#include <set>
#include <unordered_map>
#include <vector>

@@ -179,11 +181,24 @@ struct InputDeviceSensorInfo {
    int32_t id;
};

struct BrightnessLevel : ftl::DefaultConstructible<BrightnessLevel, std::uint8_t>,
                         ftl::Equatable<BrightnessLevel>,
                         ftl::Orderable<BrightnessLevel>,
                         ftl::Addable<BrightnessLevel> {
    using DefaultConstructible::DefaultConstructible;
};

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), capabilityFlags(capabilityFlags), ordinal(ordinal) {}
                                  int32_t ordinal,
                                  std::set<BrightnessLevel> preferredBrightnessLevels)
          : name(name),
            id(id),
            type(type),
            capabilityFlags(capabilityFlags),
            ordinal(ordinal),
            preferredBrightnessLevels(std::move(preferredBrightnessLevels)) {}
    // Name string of the light.
    std::string name;
    // Light id
@@ -194,6 +209,8 @@ struct InputDeviceLightInfo {
    ftl::Flags<InputDeviceLightCapability> capabilityFlags;
    // Ordinal of the light
    int32_t ordinal;
    // Custom brightness levels for the light
    std::set<BrightnessLevel> preferredBrightnessLevels;
};

struct InputDeviceBatteryInfo {
+40 −3
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

#include <locale>
#include <regex>
#include <set>
#include <sstream>
#include <string>

#include <android/sysprop/InputProperties.sysprop.h>
#include <ftl/enum.h>

#include "../Macros.h"
@@ -45,6 +47,10 @@ static inline int32_t toArgb(int32_t brightness, int32_t red, int32_t green, int
    return (brightness & 0xff) << 24 | (red & 0xff) << 16 | (green & 0xff) << 8 | (blue & 0xff);
}

static inline bool isKeyboardBacklightCustomLevelsEnabled() {
    return sysprop::InputProperties::enable_keyboard_backlight_custom_levels().value_or(true);
}

/**
 * Input controller owned by InputReader device, implements the native API for querying input
 * lights, getting and setting the lights brightness and color, by interacting with EventHub
@@ -272,11 +278,43 @@ 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, light->capabilityFlags,
                                       /*ordinal=*/1);
                                       /*ordinal=*/1, getPreferredBrightnessLevels(light.get()));
        deviceInfo->addLightInfo(lightInfo);
    }
}

// TODO(b/281822656): Move to constructor and add as a parameter to avoid parsing repeatedly.
// Need to change lifecycle of Peripheral controller so that Input device configuration map is
// available at construction time before moving this logic to constructor.
std::set<BrightnessLevel> PeripheralController::getPreferredBrightnessLevels(
        const Light* light) const {
    std::set<BrightnessLevel> levels;
    if (!isKeyboardBacklightCustomLevelsEnabled() ||
        light->type != InputDeviceLightType::KEYBOARD_BACKLIGHT) {
        return levels;
    }
    std::optional<std::string> keyboardBacklightLevels =
            mDeviceContext.getConfiguration().getString("keyboard.backlight.brightnessLevels");
    if (!keyboardBacklightLevels) {
        return levels;
    }
    std::stringstream ss(*keyboardBacklightLevels);
    while (ss.good()) {
        std::string substr;
        std::getline(ss, substr, ',');
        char* end;
        int32_t value = static_cast<int32_t>(strtol(substr.c_str(), &end, 10));
        if (*end != '\0' || value < 0 || value > 255) {
            ALOGE("Error parsing keyboard backlight brightness levels, provided levels = %s",
                  keyboardBacklightLevels->c_str());
            levels.clear();
            break;
        }
        levels.insert(BrightnessLevel(value));
    }
    return levels;
}

void PeripheralController::dump(std::string& dump) {
    dump += INDENT2 "Input Controller:\n";
    if (!mLights.empty()) {
@@ -550,5 +588,4 @@ std::optional<int32_t> PeripheralController::getLightPlayerId(int32_t lightId) {
int32_t PeripheralController::getEventHubId() const {
    return getDeviceContext().getEventHubId();
}

} // namespace android
+3 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ private:

        virtual void dump(std::string& dump) {}

        void configureSuggestedBrightnessLevels();
        std::optional<std::int32_t> getRawLightBrightness(int32_t rawLightId);
        void setRawLightBrightness(int32_t rawLightId, int32_t brightness);
    };
@@ -152,6 +153,8 @@ private:

    // Battery map from battery ID to battery
    std::unordered_map<int32_t, std::unique_ptr<Battery>> mBatteries;

    std::set<BrightnessLevel> getPreferredBrightnessLevels(const Light* light) const;
};

} // namespace android
+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ public:
    }
    inline bool hasMic() const { return mHasMic; }

    inline bool isIgnored() { return !getMapperCount(); }
    inline bool isIgnored() { return !getMapperCount() && !mController; }

    bool isEnabled();
    [[nodiscard]] std::list<NotifyArgs> setEnabled(bool enabled, nsecs_t when);
+95 −0
Original line number Diff line number Diff line
@@ -11070,6 +11070,101 @@ TEST_F(LightControllerTest, MonoKeyboardBacklight) {
    ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
}
TEST_F(LightControllerTest, Ignore_MonoLight_WithPreferredBacklightLevels) {
    RawLightInfo infoMono = {.id = 1,
                             .name = "mono_light",
                             .maxBrightness = 255,
                             .flags = InputLightClass::BRIGHTNESS,
                             .path = ""};
    mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
    mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
                                            "0,100,200");
    PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
    std::list<NotifyArgs> unused =
            mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
                               /*changes=*/{});
    InputDeviceInfo info;
    controller.populateDeviceInfo(&info);
    std::vector<InputDeviceLightInfo> lights = info.getLights();
    ASSERT_EQ(1U, lights.size());
    ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
}
TEST_F(LightControllerTest, KeyboardBacklight_WithNoPreferredBacklightLevels) {
    RawLightInfo infoMono = {.id = 1,
                             .name = "mono_keyboard_backlight",
                             .maxBrightness = 255,
                             .flags = InputLightClass::BRIGHTNESS |
                                     InputLightClass::KEYBOARD_BACKLIGHT,
                             .path = ""};
    mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
    PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
    std::list<NotifyArgs> unused =
            mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
                               /*changes=*/{});
    InputDeviceInfo info;
    controller.populateDeviceInfo(&info);
    std::vector<InputDeviceLightInfo> lights = info.getLights();
    ASSERT_EQ(1U, lights.size());
    ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
}
TEST_F(LightControllerTest, KeyboardBacklight_WithPreferredBacklightLevels) {
    RawLightInfo infoMono = {.id = 1,
                             .name = "mono_keyboard_backlight",
                             .maxBrightness = 255,
                             .flags = InputLightClass::BRIGHTNESS |
                                     InputLightClass::KEYBOARD_BACKLIGHT,
                             .path = ""};
    mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
    mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
                                            "0,100,200");
    PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
    std::list<NotifyArgs> unused =
            mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
                               /*changes=*/{});
    InputDeviceInfo info;
    controller.populateDeviceInfo(&info);
    std::vector<InputDeviceLightInfo> lights = info.getLights();
    ASSERT_EQ(1U, lights.size());
    ASSERT_EQ(3U, lights[0].preferredBrightnessLevels.size());
    std::set<BrightnessLevel>::iterator it = lights[0].preferredBrightnessLevels.begin();
    ASSERT_EQ(BrightnessLevel(0), *it);
    std::advance(it, 1);
    ASSERT_EQ(BrightnessLevel(100), *it);
    std::advance(it, 1);
    ASSERT_EQ(BrightnessLevel(200), *it);
}
TEST_F(LightControllerTest, KeyboardBacklight_WithWrongPreferredBacklightLevels) {
    RawLightInfo infoMono = {.id = 1,
                             .name = "mono_keyboard_backlight",
                             .maxBrightness = 255,
                             .flags = InputLightClass::BRIGHTNESS |
                                     InputLightClass::KEYBOARD_BACKLIGHT,
                             .path = ""};
    mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
    mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
                                            "0,100,200,300,400,500");
    PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
    std::list<NotifyArgs> unused =
            mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
                               /*changes=*/{});
    InputDeviceInfo info;
    controller.populateDeviceInfo(&info);
    std::vector<InputDeviceLightInfo> lights = info.getLights();
    ASSERT_EQ(1U, lights.size());
    ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
}
TEST_F(LightControllerTest, RGBLight) {
    RawLightInfo infoRed = {.id = 1,
                            .name = "red",