From 3e94ffe9a3d1fa6773364973074d461106fd16fc Mon Sep 17 00:00:00 2001 From: Demon000 Date: Tue, 14 May 2019 19:32:11 +0000 Subject: [PATCH] davinci: light: Import HAL from Xiaomi msm8998-common Change-Id: Ieee4277f15927b4522deaec9a709809cf6db6fea --- device.mk | 4 + light/Android.bp | 35 ++++ light/Light.cpp | 176 ++++++++++++++++++ light/Light.h | 68 +++++++ ...roid.hardware.light@2.0-service.davinci.rc | 18 ++ light/service.cpp | 50 +++++ 6 files changed, 351 insertions(+) create mode 100644 light/Android.bp create mode 100644 light/Light.cpp create mode 100644 light/Light.h create mode 100644 light/android.hardware.light@2.0-service.davinci.rc create mode 100644 light/service.cpp diff --git a/device.mk b/device.mk index 4474d9a..1084881 100644 --- a/device.mk +++ b/device.mk @@ -74,6 +74,10 @@ PRODUCT_PACKAGES += \ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/configs/security/sec_config:$(TARGET_COPY_OUT_VENDOR)/etc/sec_config +# Lights +PRODUCT_PACKAGES += \ + android.hardware.light@2.0-service.davinci + # Media PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/configs/security/mediacodec.policy:$(TARGET_COPY_OUT_VENDOR)/etc/seccomp_policy/mediacodec.policy diff --git a/light/Android.bp b/light/Android.bp new file mode 100644 index 0000000..d088339 --- /dev/null +++ b/light/Android.bp @@ -0,0 +1,35 @@ +// Copyright (C) 2019 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cc_binary { + relative_install_path: "hw", + defaults: ["hidl_defaults"], + name: "android.hardware.light@2.0-service.davinci", + init_rc: ["android.hardware.light@2.0-service.davinci.rc"], + srcs: [ + "service.cpp", + "Light.cpp", + ], + vendor: true, + shared_libs: [ + "android.hardware.light@2.0", + "libbase", + "libhardware", + "libhidlbase", + "libhidltransport", + "libhwbinder", + "liblog", + "libutils", + ], +} diff --git a/light/Light.cpp b/light/Light.cpp new file mode 100644 index 0000000..54d05b3 --- /dev/null +++ b/light/Light.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2018-2019 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "LightService" + +#include + +#include "Light.h" + +#include + +#define LCD_LED "/sys/class/backlight/panel0-backlight/" +#define WHITE_LED "/sys/class/leds/white/" + +#define BREATH "breath" +#define BRIGHTNESS "brightness" + +#define MAX_LED_BRIGHTNESS 255 +#define MAX_LCD_BRIGHTNESS 4095 + +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()); + return; + } + + file << value; +} + +static void set(std::string path, int value) { + set(path, std::to_string(value)); +} + +static uint32_t getBrightness(const LightState& state) { + uint32_t alpha, red, green, blue; + + /* + * Extract brightness from AARRGGBB. + */ + alpha = (state.color >> 24) & 0xFF; + red = (state.color >> 16) & 0xFF; + green = (state.color >> 8) & 0xFF; + blue = state.color & 0xFF; + + /* + * Scale RGB brightness if Alpha brightness is not 0xFF. + */ + if (alpha != 0xFF) { + red = red * alpha / 0xFF; + green = green * alpha / 0xFF; + blue = blue * alpha / 0xFF; + } + + 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, MAX_LCD_BRIGHTNESS); + set(LCD_LED BRIGHTNESS, brightness); +} + +static void handleNotification(const LightState& state) { + uint32_t whiteBrightness = getScaledBrightness(state, MAX_LED_BRIGHTNESS); + + /* Disable breathing or blinking */ + set(WHITE_LED BREATH, 0); + + switch (state.flashMode) { + case Flash::HARDWARE: + case Flash::TIMED: + /* Breathing */ + set(WHITE_LED BREATH, 1); + break; + case Flash::NONE: + default: + set(WHITE_LED BRIGHTNESS, whiteBrightness); + } +} + +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 }, +}; + +} // anonymous namespace + +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 no handler has been found, then the type is not supported. */ + if (!handler) { + 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); + + return Status::SUCCESS; +} + +Return Light::getSupportedTypes(getSupportedTypes_cb _hidl_cb) { + std::vector types; + + for (const LightBackend& backend : backends) { + types.push_back(backend.type); + } + + _hidl_cb(types); + + return Void(); +} + +} // namespace implementation +} // namespace V2_0 +} // namespace light +} // namespace hardware +} // namespace android diff --git a/light/Light.h b/light/Light.h new file mode 100644 index 0000000..4f102d8 --- /dev/null +++ b/light/Light.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2018 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * 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 + +#include +#include +#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 { +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; + + private: + std::mutex globalLock; +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace light +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H diff --git a/light/android.hardware.light@2.0-service.davinci.rc b/light/android.hardware.light@2.0-service.davinci.rc new file mode 100644 index 0000000..9bd6ad6 --- /dev/null +++ b/light/android.hardware.light@2.0-service.davinci.rc @@ -0,0 +1,18 @@ +on boot + chown system system /sys/class/backlight/panel0-backlight/brightness + chown system system /sys/class/backlight/panel0-backlight/max_brightness + chown system system /sys/class/leds/white/brightness + chown system system /sys/class/leds/white/breath + + chmod 0644 /sys/class/backlight/panel0-backlight/brightness + chmod 0644 /sys/class/backlight/panel0-backlight/max_brightness + chmod 0644 /sys/class/leds/white/brightness + chmod 0644 /sys/class/leds/white/breath + +service vendor.light-hal-2-0 /vendor/bin/hw/android.hardware.light@2.0-service.davinci + interface android.hardware.light@2.0::ILight default + class hal + user system + group system + # shutting off lights while powering-off + shutdown critical diff --git a/light/service.cpp b/light/service.cpp new file mode 100644 index 0000000..e7cffb8 --- /dev/null +++ b/light/service.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "android.hardware.light@2.0-service.davinci" + +#include + +#include "Light.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; + +using android::hardware::light::V2_0::ILight; +using android::hardware::light::V2_0::implementation::Light; + +using android::OK; +using android::sp; +using android::status_t; + +int main() { + sp service = new Light(); + + configureRpcThreadpool(1, true); + + status_t status = service->registerAsService(); + if (status != OK) { + ALOGE("Cannot register Light HAL service."); + return 1; + } + + ALOGI("Light HAL service ready."); + + joinRpcThreadpool(); + + ALOGI("Light HAL service failed to join thread pool."); + return 1; +}