diff --git a/light/Light.cpp b/light/Light.cpp index d8776c4e..0dd112cb 100644 --- a/light/Light.cpp +++ b/light/Light.cpp @@ -17,31 +17,35 @@ #define LOG_TAG "android.hardware.light@2.0-service.xiaomi_sdm660" #include - +#include #include "Light.h" -#include +namespace android { +namespace hardware { +namespace light { +namespace V2_0 { +namespace implementation { -#define LEDS "/sys/class/leds/" +#define LEDS "/sys/class/leds/" +#define LCD_LED LEDS "lcd-backlight/" +#define BRIGHTNESS "brightness" +#define WHITE LEDS "white/" +#define BLINK "blink" +#define DUTY_PCTS "duty_pcts" +#define PAUSE_HI "pause_hi" +#define PAUSE_LO "pause_lo" +#define RAMP_STEP_MS "ramp_step_ms" +#define START_IDX "start_idx" -#define LCD_LED LEDS "lcd-backlight/" -#define WHITE_LED LEDS "white/" - -#define BLINK "blink" -#define BRIGHTNESS "brightness" -#define MAX_BRIGHTNESS "max_brightness" -#define DUTY_PCTS "duty_pcts" -#define PAUSE_HI "pause_hi" -#define PAUSE_LO "pause_lo" -#define RAMP_STEP_MS "ramp_step_ms" -#define START_IDX "start_idx" +#define MAX_LED_BRIGHTNESS 255 +#define MAX_LCD_BRIGHTNESS 4095 /* - * 15 duty percent steps. + * 8 duty percent steps. */ #define RAMP_STEPS 15 /* - * Each step will stay on for 150ms by default. + * Each step will stay on for 50ms by default. */ #define RAMP_STEP_DURATION 150 /* @@ -49,44 +53,25 @@ */ static int32_t BRIGHTNESS_RAMP[RAMP_STEPS] = {0, 12, 25, 37, 50, 72, 85, 100, 85, 72, 50, 37, 25, 12, 0}; -namespace { /* * Write value to path and close file. */ static void set(std::string path, std::string value) { std::ofstream file(path); - - if (!file.is_open()) { - ALOGW("failed to write %s to %s", value.c_str(), path.c_str()); + /* Only write brightness value if stream is open, alive & well */ + if (file.is_open()) { + file << value; + } else { + /* Fire a warning a bail out */ + ALOGE("failed to write %s to %s", value.c_str(), path.c_str()); return; } - - file << value; } static void set(std::string path, int value) { set(path, std::to_string(value)); } -static int get(std::string path) { - std::ifstream file(path); - int value; - - if (!file.is_open()) { - ALOGW("failed to read from %s", path.c_str()); - return 0; - } - - file >> value; - return value; -} - -static int getMaxBrightness(std::string path) { - int value = get(path); - ALOGW("Got max brightness %d", value); - return value; -} - static uint32_t getBrightness(const LightState& state) { uint32_t alpha, red, green, blue; @@ -110,19 +95,6 @@ static uint32_t getBrightness(const LightState& state) { return (77 * red + 150 * green + 29 * blue) >> 8; } -static inline uint32_t scaleBrightness(uint32_t brightness, uint32_t maxBrightness) { - return brightness * maxBrightness / 0xFF; -} - -static inline uint32_t getScaledBrightness(const LightState& state, uint32_t maxBrightness) { - return scaleBrightness(getBrightness(state), maxBrightness); -} - -static void handleBacklight(const LightState& state) { - uint32_t brightness = getScaledBrightness(state, getMaxBrightness(LCD_LED MAX_BRIGHTNESS)); - set(LCD_LED BRIGHTNESS, brightness); -} - /* * Scale each value of the brightness ramp according to the * brightness of the color. @@ -138,38 +110,48 @@ static std::string getScaledRamp(uint32_t brightness) { return ramp; } -static void handleNotification(const LightState& state) { - uint32_t whiteBrightness = getScaledBrightness(state, getMaxBrightness(WHITE_LED MAX_BRIGHTNESS)); +static inline uint32_t scaleBrightness(uint32_t brightness, uint32_t maxBrightness) { + return brightness * maxBrightness / 0xFF; +} - /* Disable blinking */ - set(WHITE_LED BLINK, 0); +static inline uint32_t getScaledBrightness(const LightState& state, uint32_t maxBrightness) { + return scaleBrightness(getBrightness(state), maxBrightness); +} + +static void handleXiaomiBacklight(Type /*type*/, const LightState& state) { + uint32_t brightness = getScaledBrightness(state, MAX_LCD_BRIGHTNESS); + set(LCD_LED BRIGHTNESS, brightness); +} + +static void setNotification(const LightState& state) { + uint32_t whiteBrightness = getScaledBrightness(state, MAX_LED_BRIGHTNESS); + + /* Turn off the leds (initially) */ + set(WHITE BLINK, 0); if (state.flashMode == Flash::TIMED) { /* * If the flashOnMs duration is not long enough to fit ramping up * and down at the default step duration, step duration is modified * to fit. - */ + */ int32_t stepDuration = RAMP_STEP_DURATION; int32_t pauseHi = state.flashOnMs - (stepDuration * RAMP_STEPS * 2); int32_t pauseLo = state.flashOffMs; if (pauseHi < 0) { - //stepDuration = state.flashOnMs / (RAMP_STEPS * 2); pauseHi = 0; } /* White */ - set(WHITE_LED START_IDX, 0 * RAMP_STEPS); - set(WHITE_LED DUTY_PCTS, getScaledRamp(whiteBrightness)); - set(WHITE_LED PAUSE_LO, pauseLo); - set(WHITE_LED PAUSE_HI, pauseHi); - set(WHITE_LED RAMP_STEP_MS, stepDuration); - - /* Enable blinking */ - set(WHITE_LED BLINK, 1); + set(WHITE BLINK, 1); + set(WHITE START_IDX, 0 * RAMP_STEPS); + set(WHITE DUTY_PCTS, getScaledRamp(whiteBrightness)); + set(WHITE PAUSE_LO, pauseLo); + set(WHITE PAUSE_HI, pauseHi); + set(WHITE RAMP_STEP_MS, stepDuration); } else { - set(WHITE_LED BRIGHTNESS, whiteBrightness); + set(WHITE BRIGHTNESS, whiteBrightness); } } @@ -177,61 +159,60 @@ static inline bool isLit(const LightState& state) { return state.color & 0x00ffffff; } -/* Keep sorted in the order of importance. */ -static std::vector backends = { - { Type::ATTENTION, handleNotification }, - { Type::NOTIFICATIONS, handleNotification }, - { Type::BATTERY, handleNotification }, - { Type::BACKLIGHT, handleBacklight }, +/* + * Keep sorted in the order of importance. + */ +static const LightState offState = {}; +static std::vector> notificationStates = { + { Type::ATTENTION, offState }, + { Type::NOTIFICATIONS, offState }, + { Type::BATTERY, offState }, }; -} // anonymous namespace +static void handleXiaomiNotification(Type type, const LightState& state) { + for(auto it : notificationStates) { + if (it.first == type) { + it.second = state; + } -namespace android { -namespace hardware { -namespace light { -namespace V2_0 { -namespace implementation { - -Return Light::setLight(Type type, const LightState& state) { - LightStateHandler handler = nullptr; - - /* Lock global mutex until light state is updated. */ - std::lock_guard lock(globalLock); - - /* Update the cached state value for the current type. */ - for (LightBackend& backend : backends) { - if (backend.type == type) { - backend.state = state; - handler = backend.handler; + if (isLit(it.second)) { + setNotification(it.second); + return; } } - /* If no handler has been found, then the type is not supported. */ - if (!handler) { + setNotification(offState); +} + +static std::map> lights = { + {Type::BACKLIGHT, handleXiaomiBacklight}, + {Type::NOTIFICATIONS, handleXiaomiNotification}, + {Type::BATTERY, handleXiaomiNotification}, + {Type::ATTENTION, handleXiaomiNotification}, +}; + +Light::Light() {} + +Return Light::setLight(Type type, const LightState& state) { + auto it = lights.find(type); + + if (it == lights.end()) { return Status::LIGHT_NOT_SUPPORTED; } - /* Light up the type with the highest priority that matches the current handler. */ - for (LightBackend& backend : backends) { - if (handler == backend.handler && isLit(backend.state)) { - handler(backend.state); - return Status::SUCCESS; - } - } - - /* If no type has been lit up, then turn off the hardware. */ - handler(state); + /* + * Lock global mutex until light state is updated. + */ + std::lock_guard lock(globalLock); + it->second(type, state); return Status::SUCCESS; } Return Light::getSupportedTypes(getSupportedTypes_cb _hidl_cb) { std::vector types; - for (const LightBackend& backend : backends) { - types.push_back(backend.type); - } + for (auto const& light : lights) types.push_back(light.first); _hidl_cb(types); diff --git a/light/Light.h b/light/Light.h index f8026818..311b7ded 100644 --- a/light/Light.h +++ b/light/Light.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Xiaomi-SDM660 Project + * Copyright (C) 2017 The LineageOS Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H #define ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H @@ -22,27 +21,6 @@ #include #include #include -#include - -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::light::V2_0::Flash; -using ::android::hardware::light::V2_0::ILight; -using ::android::hardware::light::V2_0::LightState; -using ::android::hardware::light::V2_0::Status; -using ::android::hardware::light::V2_0::Type; - -typedef void (*LightStateHandler)(const LightState&); - -struct LightBackend { - Type type; - LightState state; - LightStateHandler handler; - - LightBackend(Type type, LightStateHandler handler) : type(type), handler(handler) { - this->state.color = 0xff000000; - } -}; namespace android { namespace hardware { @@ -50,13 +28,23 @@ namespace light { namespace V2_0 { namespace implementation { -class Light : public ILight { - public: - Return setLight(Type type, const LightState& state) override; - Return getSupportedTypes(getSupportedTypes_cb _hidl_cb) override; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::light::V2_0::ILight; +using ::android::hardware::light::V2_0::LightState; +using ::android::hardware::light::V2_0::Status; +using ::android::hardware::light::V2_0::Type; - private: - std::mutex globalLock; +class Light : public ILight { + public: + Light(); + + Return setLight(Type type, const LightState& state) override; + Return getSupportedTypes(getSupportedTypes_cb _hidl_cb) override; + + private: + std::mutex globalLock; }; } // namespace implementation @@ -65,4 +53,4 @@ class Light : public ILight { } // namespace hardware } // namespace android -#endif // ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H \ No newline at end of file +#endif // ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H diff --git a/light/service.cpp b/light/service.cpp index b8e699f0..8f6fa889 100644 --- a/light/service.cpp +++ b/light/service.cpp @@ -31,7 +31,7 @@ using android::sp; using android::status_t; int main() { - sp service = new Light(); + android::sp service = new Light(); configureRpcThreadpool(1, true);