aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Martins <bgcngm@gmail.com>2018-01-19 15:42:00 +0000
committerDavide Garberi <dade.garberi@gmail.com>2018-01-25 17:06:44 +0100
commite03f3220a3bb949ca5c11b78de3c6ce5228b0d19 (patch)
tree69e5478269bda2d50354ce8c6f821c37e5075833
parent01a7a3c04cde89a3ba8c81d55c3d29d9309ae8b5 (diff)
msm8996-common: Convert lights HAL into a native binderized HAL
Change-Id: If41458e22b9a67a5c2a415571723917df1904aa1 Signed-off-by: Davide Garberi <dade.garberi@gmail.com>
-rw-r--r--Android.bp3
-rw-r--r--hidl.mk3
-rw-r--r--light/Android.bp32
-rw-r--r--light/Light.cpp295
-rw-r--r--light/Light.h97
-rw-r--r--light/android.hardware.light@2.0-service.zuk_8996.rc66
-rw-r--r--light/service.cpp284
-rwxr-xr-xrootdir/etc/init.qcom.rc61
-rw-r--r--sepolicy/file_contexts5
9 files changed, 783 insertions, 63 deletions
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..f61e31b
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,3 @@
+subdirs = [
+ "light",
+]
diff --git a/hidl.mk b/hidl.mk
index c1192ec..bcb7e18 100644
--- a/hidl.mk
+++ b/hidl.mk
@@ -92,8 +92,7 @@ PRODUCT_PACKAGES += \
# Lights
PRODUCT_PACKAGES += \
- android.hardware.light@2.0-impl \
- android.hardware.light@2.0-service
+ android.hardware.light@2.0-service.zuk_8996
# Power
PRODUCT_PACKAGES += \
diff --git a/light/Android.bp b/light/Android.bp
new file mode 100644
index 0000000..078b448
--- /dev/null
+++ b/light/Android.bp
@@ -0,0 +1,32 @@
+//
+// 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.
+
+cc_binary {
+ name: "android.hardware.light@2.0-service.zuk_8996",
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.light@2.0-service.zuk_8996.rc"],
+ srcs: ["service.cpp", "Light.cpp"],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hardware.light@2.0",
+ ],
+ proprietary: true,
+}
diff --git a/light/Light.cpp b/light/Light.cpp
new file mode 100644
index 0000000..a364f05
--- /dev/null
+++ b/light/Light.cpp
@@ -0,0 +1,295 @@
+/*
+ * 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 "LightService"
+
+#include "Light.h"
+
+#include <android-base/logging.h>
+
+namespace {
+using android::hardware::light::V2_0::LightState;
+
+static constexpr int RAMP_SIZE = 8;
+static constexpr int RAMP_STEP_DURATION = 50;
+
+static constexpr int BRIGHTNESS_RAMP[RAMP_SIZE] = {0, 12, 25, 37, 50, 72, 85, 100};
+static constexpr int DEFAULT_MAX_BRIGHTNESS = 255;
+
+static uint32_t rgbToBrightness(const LightState& state) {
+ uint32_t color = state.color & 0x00ffffff;
+ return ((77 * ((color >> 16) & 0xff)) + (150 * ((color >> 8) & 0xff)) +
+ (29 * (color & 0xff))) >> 8;
+}
+
+static bool isLit(const LightState& state) {
+ return (state.color & 0x00ffffff);
+}
+
+static std::string getScaledDutyPcts(int brightness) {
+ std::string buf, pad;
+
+ for (auto i : BRIGHTNESS_RAMP) {
+ buf += pad;
+ buf += std::to_string(i * brightness / 255);
+ pad = ",";
+ }
+
+ return buf;
+}
+} // anonymous namespace
+
+namespace android {
+namespace hardware {
+namespace light {
+namespace V2_0 {
+namespace implementation {
+
+Light::Light(std::pair<std::ofstream, uint32_t>&& lcd_backlight,
+ std::vector<std::ofstream>&& button_backlight,
+ std::ofstream&& red_led, std::ofstream&& green_led, std::ofstream&& blue_led,
+ std::ofstream&& red_duty_pcts, std::ofstream&& green_duty_pcts, std::ofstream&& blue_duty_pcts,
+ std::ofstream&& red_start_idx, std::ofstream&& green_start_idx, std::ofstream&& blue_start_idx,
+ std::ofstream&& red_pause_lo, std::ofstream&& green_pause_lo, std::ofstream&& blue_pause_lo,
+ std::ofstream&& red_pause_hi, std::ofstream&& green_pause_hi, std::ofstream&& blue_pause_hi,
+ std::ofstream&& red_ramp_step_ms, std::ofstream&& green_ramp_step_ms, std::ofstream&& blue_ramp_step_ms,
+ std::ofstream&& red_blink, std::ofstream&& green_blink, std::ofstream&& blue_blink,
+ std::ofstream&& rgb_blink)
+ : mLcdBacklight(std::move(lcd_backlight)),
+ mButtonBacklight(std::move(button_backlight)),
+ mRedLed(std::move(red_led)),
+ mGreenLed(std::move(green_led)),
+ mBlueLed(std::move(blue_led)),
+ mRedDutyPcts(std::move(red_duty_pcts)),
+ mGreenDutyPcts(std::move(green_duty_pcts)),
+ mBlueDutyPcts(std::move(blue_duty_pcts)),
+ mRedStartIdx(std::move(red_start_idx)),
+ mGreenStartIdx(std::move(green_start_idx)),
+ mBlueStartIdx(std::move(blue_start_idx)),
+ mRedPauseLo(std::move(red_pause_lo)),
+ mGreenPauseLo(std::move(green_pause_lo)),
+ mBluePauseLo(std::move(blue_pause_lo)),
+ mRedPauseHi(std::move(red_pause_hi)),
+ mGreenPauseHi(std::move(green_pause_hi)),
+ mBluePauseHi(std::move(blue_pause_hi)),
+ mRedRampStepMs(std::move(red_ramp_step_ms)),
+ mGreenRampStepMs(std::move(green_ramp_step_ms)),
+ mBlueRampStepMs(std::move(blue_ramp_step_ms)),
+ mRedBlink(std::move(red_blink)),
+ mGreenBlink(std::move(green_blink)),
+ mBlueBlink(std::move(blue_blink)),
+ mRgbBlink(std::move(rgb_blink)) {
+ auto attnFn(std::bind(&Light::setAttentionLight, this, std::placeholders::_1));
+ auto backlightFn(std::bind(&Light::setLcdBacklight, this, std::placeholders::_1));
+ auto batteryFn(std::bind(&Light::setBatteryLight, this, std::placeholders::_1));
+ auto buttonsFn(std::bind(&Light::setButtonsBacklight, this, std::placeholders::_1));
+ auto notifFn(std::bind(&Light::setNotificationLight, this, std::placeholders::_1));
+ mLights.emplace(std::make_pair(Type::ATTENTION, attnFn));
+ mLights.emplace(std::make_pair(Type::BACKLIGHT, backlightFn));
+ mLights.emplace(std::make_pair(Type::BATTERY, batteryFn));
+ mLights.emplace(std::make_pair(Type::BUTTONS, buttonsFn));
+ mLights.emplace(std::make_pair(Type::NOTIFICATIONS, notifFn));
+}
+
+// Methods from ::android::hardware::light::V2_0::ILight follow.
+Return<Status> Light::setLight(Type type, const LightState& state) {
+ auto it = mLights.find(type);
+
+ if (it == mLights.end()) {
+ return Status::LIGHT_NOT_SUPPORTED;
+ }
+
+ it->second(state);
+
+ return Status::SUCCESS;
+}
+
+Return<void> Light::getSupportedTypes(getSupportedTypes_cb _hidl_cb) {
+ std::vector<Type> types;
+
+ for (auto const& light : mLights) {
+ types.push_back(light.first);
+ }
+
+ _hidl_cb(types);
+
+ return Void();
+}
+
+void Light::setAttentionLight(const LightState& state) {
+ std::lock_guard<std::mutex> lock(mLock);
+ mAttentionState = state;
+ setSpeakerBatteryLightLocked();
+}
+
+void Light::setLcdBacklight(const LightState& state) {
+ std::lock_guard<std::mutex> lock(mLock);
+
+ uint32_t brightness = rgbToBrightness(state);
+
+ // If max panel brightness is not the default (255),
+ // apply linear scaling across the accepted range.
+ if (mLcdBacklight.second != DEFAULT_MAX_BRIGHTNESS) {
+ int old_brightness = brightness;
+ brightness = brightness * mLcdBacklight.second / DEFAULT_MAX_BRIGHTNESS;
+ LOG(VERBOSE) << "scaling brightness " << old_brightness << " => " << brightness;
+ }
+
+ mLcdBacklight.first << brightness << std::endl;
+}
+
+void Light::setButtonsBacklight(const LightState& state) {
+ std::lock_guard<std::mutex> lock(mLock);
+
+ uint32_t brightness = rgbToBrightness(state);
+
+ for (auto& button : mButtonBacklight) {
+ button << brightness << std::endl;
+ }
+}
+
+void Light::setBatteryLight(const LightState& state) {
+ std::lock_guard<std::mutex> lock(mLock);
+ mBatteryState = state;
+ setSpeakerBatteryLightLocked();
+}
+
+void Light::setNotificationLight(const LightState& state) {
+ std::lock_guard<std::mutex> lock(mLock);
+
+ uint32_t brightness, color, rgb[3];
+ LightState localState = state;
+
+ // If a brightness has been applied by the user
+ brightness = (localState.color & 0xff000000) >> 24;
+ if (brightness > 0 && brightness < 255) {
+ // Retrieve each of the RGB colors
+ color = localState.color & 0x00ffffff;
+ rgb[0] = (color >> 16) & 0xff;
+ rgb[1] = (color >> 8) & 0xff;
+ rgb[2] = color & 0xff;
+
+ // Apply the brightness level
+ if (rgb[0] > 0) {
+ rgb[0] = (rgb[0] * brightness) / 0xff;
+ }
+ if (rgb[1] > 0) {
+ rgb[1] = (rgb[1] * brightness) / 0xff;
+ }
+ if (rgb[2] > 0) {
+ rgb[2] = (rgb[2] * brightness) / 0xff;
+ }
+
+ // Update with the new color
+ localState.color = (rgb[0] << 16) + (rgb[1] << 8) + rgb[2];
+ }
+
+ mNotificationState = localState;
+ setSpeakerBatteryLightLocked();
+}
+
+void Light::setSpeakerBatteryLightLocked() {
+ if (isLit(mNotificationState)) {
+ setSpeakerLightLocked(mNotificationState);
+ } else if (isLit(mAttentionState)) {
+ setSpeakerLightLocked(mAttentionState);
+ } else if (isLit(mBatteryState)) {
+ setSpeakerLightLocked(mBatteryState);
+ } else {
+ // Lights off
+ mRedLed << 0 << std::endl;
+ mGreenLed << 0 << std::endl;
+ mBlueLed << 0 << std::endl;
+ mRedBlink << 0 << std::endl;
+ mGreenBlink << 0 << std::endl;
+ mBlueBlink << 0 << std::endl;
+ }
+}
+
+void Light::setSpeakerLightLocked(const LightState& state) {
+ int red, green, blue, blink;
+ int onMs, offMs, stepDuration, pauseHi;
+ uint32_t colorRGB = state.color;
+
+ switch (state.flashMode) {
+ case Flash::TIMED:
+ onMs = state.flashOnMs;
+ offMs = state.flashOffMs;
+ break;
+ case Flash::NONE:
+ default:
+ onMs = 0;
+ offMs = 0;
+ break;
+ }
+
+ red = (colorRGB >> 16) & 0xff;
+ green = (colorRGB >> 8) & 0xff;
+ blue = colorRGB & 0xff;
+ blink = onMs > 0 && offMs > 0;
+
+ // Disable all blinking to start
+ mRgbBlink << 0 << std::endl;
+
+ if (blink) {
+ stepDuration = RAMP_STEP_DURATION;
+ pauseHi = onMs - (stepDuration * RAMP_SIZE * 2);
+
+ if (stepDuration * RAMP_SIZE * 2 > onMs) {
+ stepDuration = onMs / (RAMP_SIZE * 2);
+ pauseHi = 0;
+ }
+
+ // Red
+ mRedStartIdx << 0 << std::endl;
+ mRedDutyPcts << getScaledDutyPcts(red) << std::endl;
+ mRedPauseLo << offMs << std::endl;
+ mRedPauseHi << pauseHi << std::endl;
+ mRedRampStepMs << stepDuration << std::endl;
+
+ // Green
+ mGreenStartIdx << RAMP_SIZE << std::endl;
+ mGreenDutyPcts << getScaledDutyPcts(green) << std::endl;
+ mGreenPauseLo << offMs << std::endl;
+ mGreenPauseHi << pauseHi << std::endl;
+ mGreenRampStepMs << stepDuration << std::endl;
+
+ // Blue
+ mBlueStartIdx << RAMP_SIZE * 2 << std::endl;
+ mBlueDutyPcts << getScaledDutyPcts(blue) << std::endl;
+ mBluePauseLo << offMs << std::endl;
+ mBluePauseHi << pauseHi << std::endl;
+ mBlueRampStepMs << stepDuration << std::endl;
+
+ // Start the party
+ mRgbBlink << 1 << std::endl;
+ } else {
+ if (red == 0 && green == 0 && blue == 0) {
+ mRedBlink << 0 << std::endl;
+ mGreenBlink << 0 << std::endl;
+ mBlueBlink << 0 << std::endl;
+ }
+ mRedLed << red << std::endl;
+ mGreenLed << green << std::endl;
+ mBlueLed << blue << std::endl;
+ }
+}
+
+} // 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..f21e19e
--- /dev/null
+++ b/light/Light.h
@@ -0,0 +1,97 @@
+/*
+ * 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 <android/hardware/light/2.0/ILight.h>
+#include <hidl/Status.h>
+
+#include <fstream>
+#include <mutex>
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace light {
+namespace V2_0 {
+namespace implementation {
+
+struct Light : public ILight {
+ Light(std::pair<std::ofstream, uint32_t>&& lcd_backlight,
+ std::vector<std::ofstream>&& button_backlight,
+ std::ofstream&& red_led, std::ofstream&& green_led, std::ofstream&& blue_led,
+ std::ofstream&& red_duty_pcts, std::ofstream&& green_duty_pcts, std::ofstream&& blue_duty_pcts,
+ std::ofstream&& red_start_idx, std::ofstream&& green_start_idx, std::ofstream&& blue_start_idx,
+ std::ofstream&& red_pause_lo, std::ofstream&& green_pause_lo, std::ofstream&& blue_pause_lo,
+ std::ofstream&& red_pause_hi, std::ofstream&& green_pause_hi, std::ofstream&& blue_pause_hi,
+ std::ofstream&& red_ramp_step_ms, std::ofstream&& green_ramp_step_ms, std::ofstream&& blue_ramp_step_ms,
+ std::ofstream&& red_blink, std::ofstream&& green_blink, std::ofstream&& blue_blink,
+ std::ofstream&& rgb_blink);
+
+ // Methods from ::android::hardware::light::V2_0::ILight follow.
+ Return<Status> setLight(Type type, const LightState& state) override;
+ Return<void> getSupportedTypes(getSupportedTypes_cb _hidl_cb) override;
+
+ private:
+ void setAttentionLight(const LightState& state);
+ void setBatteryLight(const LightState& state);
+ void setButtonsBacklight(const LightState& state);
+ void setLcdBacklight(const LightState& state);
+ void setNotificationLight(const LightState& state);
+ void setSpeakerBatteryLightLocked();
+ void setSpeakerLightLocked(const LightState& state);
+
+ std::pair<std::ofstream, uint32_t> mLcdBacklight;
+ std::vector<std::ofstream> mButtonBacklight;
+ std::ofstream mRedLed;
+ std::ofstream mGreenLed;
+ std::ofstream mBlueLed;
+ std::ofstream mRedDutyPcts;
+ std::ofstream mGreenDutyPcts;
+ std::ofstream mBlueDutyPcts;
+ std::ofstream mRedStartIdx;
+ std::ofstream mGreenStartIdx;
+ std::ofstream mBlueStartIdx;
+ std::ofstream mRedPauseLo;
+ std::ofstream mGreenPauseLo;
+ std::ofstream mBluePauseLo;
+ std::ofstream mRedPauseHi;
+ std::ofstream mGreenPauseHi;
+ std::ofstream mBluePauseHi;
+ std::ofstream mRedRampStepMs;
+ std::ofstream mGreenRampStepMs;
+ std::ofstream mBlueRampStepMs;
+ std::ofstream mRedBlink;
+ std::ofstream mGreenBlink;
+ std::ofstream mBlueBlink;
+ std::ofstream mRgbBlink;
+
+ LightState mAttentionState;
+ LightState mBatteryState;
+ LightState mNotificationState;
+
+ std::unordered_map<Type, std::function<void(const LightState&)>> mLights;
+ std::mutex mLock;
+};
+
+} // 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.zuk_8996.rc b/light/android.hardware.light@2.0-service.zuk_8996.rc
new file mode 100644
index 0000000..ce90011
--- /dev/null
+++ b/light/android.hardware.light@2.0-service.zuk_8996.rc
@@ -0,0 +1,66 @@
+on init
+ # RGB lights
+ chown system system /sys/class/leds/red/brightness
+ chown system system /sys/class/leds/green/brightness
+ chown system system /sys/class/leds/blue/brightness
+
+ chown system system /sys/class/leds/red/pause_lo
+ chown system system /sys/class/leds/green/pause_lo
+ chown system system /sys/class/leds/blue/pause_lo
+
+ chown system system /sys/class/leds/red/pause_hi
+ chown system system /sys/class/leds/green/pause_hi
+ chown system system /sys/class/leds/blue/pause_hi
+
+ chown system system /sys/class/leds/red/blink
+ chown system system /sys/class/leds/green/blink
+ chown system system /sys/class/leds/blue/blink
+
+ chown system system /sys/class/leds/rgb/rgb_blink
+
+ chown system system /sys/class/leds/red/ramp_step_ms
+ chown system system /sys/class/leds/green/ramp_step_ms
+ chown system system /sys/class/leds/blue/ramp_step_ms
+
+ chown system system /sys/class/leds/red/duty_pcts
+ chown system system /sys/class/leds/green/duty_pcts
+ chown system system /sys/class/leds/blue/duty_pcts
+
+ chown system system /sys/class/leds/red/start_idx
+ chown system system /sys/class/leds/green/start_idx
+ chown system system /sys/class/leds/blue/start_idx
+
+ chown system system /sys/class/leds/blue/lut_flags
+ chown system system /sys/class/leds/red/lut_flags
+ chown system system /sys/class/leds/green/lut_flags
+
+ chmod 660 /sys/class/leds/red/brightness
+ chmod 660 /sys/class/leds/green/brightness
+ chmod 660 /sys/class/leds/blue/brightness
+
+ chmod 660 /sys/class/leds/red/ramp_step_ms
+ chmod 660 /sys/class/leds/green/ramp_step_ms
+ chmod 660 /sys/class/leds/blue/ramp_step_ms
+
+ chmod 660 /sys/class/leds/red/duty_pcts
+ chmod 660 /sys/class/leds/green/duty_pcts
+ chmod 660 /sys/class/leds/blue/duty_pcts
+
+ chmod 660 /sys/class/leds/red/start_idx
+ chmod 660 /sys/class/leds/green/start_idx
+ chmod 660 /sys/class/leds/blue/start_idx
+
+ chmod 660 /sys/class/leds/blue/lut_flags
+ chmod 660 /sys/class/leds/red/lut_flags
+ chmod 660 /sys/class/leds/green/lut_flags
+
+ chmod 660 /sys/class/leds/blue/pause_lo
+ chmod 660 /sys/class/leds/red/pause_lo
+ chmod 660 /sys/class/leds/green/pause_lo
+
+ chmod 660 /sys/class/leds/rgb/rgb_blink
+
+service light-hal-2-0 /vendor/bin/hw/android.hardware.light@2.0-service.zuk_8996
+ class hal
+ user system
+ group system
diff --git a/light/service.cpp b/light/service.cpp
new file mode 100644
index 0000000..8dd750d
--- /dev/null
+++ b/light/service.cpp
@@ -0,0 +1,284 @@
+/*
+ * 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.zuk_8996"
+
+#include <android-base/logging.h>
+#include <hidl/HidlTransportSupport.h>
+#include <utils/Errors.h>
+
+#include "Light.h"
+
+// libhwbinder:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::hardware::light::V2_0::ILight;
+using android::hardware::light::V2_0::implementation::Light;
+
+const static std::string kLcdBacklightPath = "/sys/class/leds/lcd-backlight/brightness";
+const static std::string kLcdMaxBacklightPath = "/sys/class/leds/lcd-backlight/max_brightness";
+const static std::string kButton1BacklightPath = "/sys/class/leds/button-backlight/brightness";
+const static std::string kButton2BacklightPath = "/sys/class/leds/button-backlight1/brightness";
+const static std::string kButton3BacklightPath = "/sys/class/leds/button-backlight2/brightness";
+const static std::string kRedLedPath = "/sys/class/leds/red/brightness";
+const static std::string kGreenLedPath = "/sys/class/leds/green/brightness";
+const static std::string kBlueLedPath = "/sys/class/leds/blue/brightness";
+const static std::string kRedDutyPctsPath = "/sys/class/leds/red/duty_pcts";
+const static std::string kGreenDutyPctsPath = "/sys/class/leds/green/duty_pcts";
+const static std::string kBlueDutyPctsPath = "/sys/class/leds/blue/duty_pcts";
+const static std::string kRedStartIdxPath = "/sys/class/leds/red/start_idx";
+const static std::string kGreenStartIdxPath = "/sys/class/leds/green/start_idx";
+const static std::string kBlueStartIdxPath = "/sys/class/leds/blue/start_idx";
+const static std::string kRedPauseLoPath = "/sys/class/leds/red/pause_lo";
+const static std::string kGreenPauseLoPath = "/sys/class/leds/green/pause_lo";
+const static std::string kBluePauseLoPath = "/sys/class/leds/blue/pause_lo";
+const static std::string kRedPauseHiPath = "/sys/class/leds/red/pause_hi";
+const static std::string kGreenPauseHiPath = "/sys/class/leds/green/pause_hi";
+const static std::string kBluePauseHiPath = "/sys/class/leds/blue/pause_hi";
+const static std::string kRedRampStepMsPath = "/sys/class/leds/red/ramp_step_ms";
+const static std::string kGreenRampStepMsPath = "/sys/class/leds/green/ramp_step_ms";
+const static std::string kBlueRampStepMsPath = "/sys/class/leds/blue/ramp_step_ms";
+const static std::string kRedBlinkPath = "/sys/class/leds/red/blink";
+const static std::string kGreenBlinkPath = "/sys/class/leds/green/blink";
+const static std::string kBlueBlinkPath = "/sys/class/leds/blue/blink";
+const static std::string kRgbBlinkPath = "/sys/class/leds/rgb/rgb_blink";
+
+int main() {
+ uint32_t lcdMaxBrightness = 255;
+ std::vector<std::ofstream> buttonBacklight;
+
+ std::ofstream lcdBacklight(kLcdBacklightPath);
+ if (!lcdBacklight) {
+ LOG(ERROR) << "Failed to open " << kLcdBacklightPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ifstream lcdMaxBacklight(kLcdMaxBacklightPath);
+ if (!lcdMaxBacklight) {
+ LOG(ERROR) << "Failed to open " << kLcdMaxBacklightPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ } else {
+ lcdMaxBacklight >> lcdMaxBrightness;
+ }
+
+ std::ofstream button1Backlight(kButton1BacklightPath);
+ if (button1Backlight) {
+ buttonBacklight.emplace_back(std::move(button1Backlight));
+ } else {
+ LOG(WARNING) << "Failed to open " << kButton1BacklightPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ }
+
+ std::ofstream button2Backlight(kButton2BacklightPath);
+ if (button2Backlight) {
+ buttonBacklight.emplace_back(std::move(button2Backlight));
+ } else {
+ LOG(WARNING) << "Failed to open " << kButton2BacklightPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ }
+
+ std::ofstream button3Backlight(kButton3BacklightPath);
+ if (button3Backlight) {
+ buttonBacklight.emplace_back(std::move(button3Backlight));
+ } else {
+ LOG(WARNING) << "Failed to open " << kButton3BacklightPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ }
+
+ std::ofstream redLed(kRedLedPath);
+ if (!redLed) {
+ LOG(ERROR) << "Failed to open " << kRedLedPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream greenLed(kGreenLedPath);
+ if (!greenLed) {
+ LOG(ERROR) << "Failed to open " << kGreenLedPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream blueLed(kBlueLedPath);
+ if (!blueLed) {
+ LOG(ERROR) << "Failed to open " << kBlueLedPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream redDutyPcts(kRedDutyPctsPath);
+ if (!redDutyPcts) {
+ LOG(ERROR) << "Failed to open " << kRedDutyPctsPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream greenDutyPcts(kGreenDutyPctsPath);
+ if (!greenDutyPcts) {
+ LOG(ERROR) << "Failed to open " << kGreenDutyPctsPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream blueDutyPcts(kBlueDutyPctsPath);
+ if (!blueDutyPcts) {
+ LOG(ERROR) << "Failed to open " << kBlueDutyPctsPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream redStartIdx(kRedStartIdxPath);
+ if (!redStartIdx) {
+ LOG(ERROR) << "Failed to open " << kRedStartIdxPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream greenStartIdx(kGreenStartIdxPath);
+ if (!greenStartIdx) {
+ LOG(ERROR) << "Failed to open " << kGreenStartIdxPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream blueStartIdx(kBlueStartIdxPath);
+ if (!blueStartIdx) {
+ LOG(ERROR) << "Failed to open " << kBlueStartIdxPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream redPauseLo(kRedPauseLoPath);
+ if (!redPauseLo) {
+ LOG(ERROR) << "Failed to open " << kRedPauseLoPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream greenPauseLo(kGreenPauseLoPath);
+ if (!greenPauseLo) {
+ LOG(ERROR) << "Failed to open " << kGreenPauseLoPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream bluePauseLo(kBluePauseLoPath);
+ if (!bluePauseLo) {
+ LOG(ERROR) << "Failed to open " << kBluePauseLoPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream redPauseHi(kRedPauseHiPath);
+ if (!redPauseHi) {
+ LOG(ERROR) << "Failed to open " << kRedPauseHiPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream greenPauseHi(kGreenPauseHiPath);
+ if (!greenPauseHi) {
+ LOG(ERROR) << "Failed to open " << kGreenPauseHiPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream bluePauseHi(kBluePauseHiPath);
+ if (!bluePauseHi) {
+ LOG(ERROR) << "Failed to open " << kBluePauseHiPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream redRampStepMs(kRedRampStepMsPath);
+ if (!redRampStepMs) {
+ LOG(ERROR) << "Failed to open " << kRedRampStepMsPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream greenRampStepMs(kGreenRampStepMsPath);
+ if (!greenRampStepMs) {
+ LOG(ERROR) << "Failed to open " << kGreenRampStepMsPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream blueRampStepMs(kBlueRampStepMsPath);
+ if (!blueRampStepMs) {
+ LOG(ERROR) << "Failed to open " << kBlueRampStepMsPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream redBlink(kRedBlinkPath);
+ if (!redBlink) {
+ LOG(ERROR) << "Failed to open " << kRedBlinkPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream greenBlink(kGreenBlinkPath);
+ if (!greenBlink) {
+ LOG(ERROR) << "Failed to open " << kGreenBlinkPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream blueBlink(kBlueBlinkPath);
+ if (!blueBlink) {
+ LOG(ERROR) << "Failed to open " << kBlueBlinkPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ std::ofstream rgbBlink(kRgbBlinkPath);
+ if (!rgbBlink) {
+ LOG(ERROR) << "Failed to open " << kRgbBlinkPath << ", error=" << errno
+ << " (" << strerror(errno) << ")";
+ return -errno;
+ }
+
+ android::sp<ILight> service = new Light(
+ {std::move(lcdBacklight), lcdMaxBrightness}, std::move(buttonBacklight),
+ std::move(redLed), std::move(greenLed), std::move(blueLed),
+ std::move(redDutyPcts), std::move(greenDutyPcts), std::move(blueDutyPcts),
+ std::move(redStartIdx), std::move(greenStartIdx), std::move(blueStartIdx),
+ std::move(redPauseLo), std::move(greenPauseLo), std::move(bluePauseLo),
+ std::move(redPauseHi), std::move(greenPauseHi), std::move(bluePauseHi),
+ std::move(redRampStepMs), std::move(greenRampStepMs), std::move(blueRampStepMs),
+ std::move(redBlink), std::move(greenBlink), std::move(blueBlink),
+ std::move(rgbBlink));
+
+ configureRpcThreadpool(1, true);
+
+ android::status_t status = service->registerAsService();
+
+ if (status != android::OK) {
+ LOG(ERROR) << "Cannot register Light HAL service";
+ return 1;
+ }
+
+ LOG(INFO) << "Light HAL Ready.";
+ joinRpcThreadpool();
+ // Under normal cases, execution will not reach this line.
+ LOG(ERROR) << "Light HAL failed to join thread pool.";
+ return 1;
+}
diff --git a/rootdir/etc/init.qcom.rc b/rootdir/etc/init.qcom.rc
index 5c4b4fb..e456a1b 100755
--- a/rootdir/etc/init.qcom.rc
+++ b/rootdir/etc/init.qcom.rc
@@ -168,67 +168,6 @@ on boot
chown system system /sys/module/dwc3/parameters/usb30_disabled
chmod 0660 /sys/module/dwc3/parameters/usb30_disabled
- # RGB light
- chown system system /sys/class/leds/red/brightness
- chown system system /sys/class/leds/green/brightness
- chown system system /sys/class/leds/blue/brightness
-
- chown system system /sys/class/leds/red/pause_lo
- chown system system /sys/class/leds/green/pause_lo
- chown system system /sys/class/leds/blue/pause_lo
-
- chown system system /sys/class/leds/red/pause_hi
- chown system system /sys/class/leds/green/pause_hi
- chown system system /sys/class/leds/blue/pause_hi
-
- chown system system /sys/class/leds/red/blink
- chown system system /sys/class/leds/green/blink
- chown system system /sys/class/leds/blue/blink
-
- chown system system /sys/class/leds/rgb/rgb_blink
-
- chown system system /sys/class/leds/red/ramp_step_ms
- chown system system /sys/class/leds/green/ramp_step_ms
- chown system system /sys/class/leds/blue/ramp_step_ms
-
- chown system system /sys/class/leds/red/duty_pcts
- chown system system /sys/class/leds/green/duty_pcts
- chown system system /sys/class/leds/blue/duty_pcts
-
- chown system system /sys/class/leds/red/start_idx
- chown system system /sys/class/leds/green/start_idx
- chown system system /sys/class/leds/blue/start_idx
-
- chown system system /sys/class/leds/blue/lut_flags
- chown system system /sys/class/leds/red/lut_flags
- chown system system /sys/class/leds/green/lut_flags
-
- chmod 660 /sys/class/leds/red/brightness
- chmod 660 /sys/class/leds/green/brightness
- chmod 660 /sys/class/leds/blue/brightness
-
- chmod 660 /sys/class/leds/red/ramp_step_ms
- chmod 660 /sys/class/leds/green/ramp_step_ms
- chmod 660 /sys/class/leds/blue/ramp_step_ms
-
- chmod 660 /sys/class/leds/red/duty_pcts
- chmod 660 /sys/class/leds/green/duty_pcts
- chmod 660 /sys/class/leds/blue/duty_pcts
-
- chmod 660 /sys/class/leds/red/start_idx
- chmod 660 /sys/class/leds/green/start_idx
- chmod 660 /sys/class/leds/blue/start_idx
-
- chmod 660 /sys/class/leds/blue/lut_flags
- chmod 660 /sys/class/leds/red/lut_flags
- chmod 660 /sys/class/leds/green/lut_flags
-
- chmod 660 /sys/class/leds/blue/pause_lo
- chmod 660 /sys/class/leds/red/pause_lo
- chmod 660 /sys/class/leds/green/pause_lo
-
- chmod 660 /sys/class/leds/rgb/rgb_blink
-
chown bluetooth bluetooth /sys/module/bluetooth_power/parameters/power
chown bluetooth net_bt /sys/class/rfkill/rfkill0/type
chown bluetooth net_bt /sys/class/rfkill/rfkill0/state
diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts
index 2f977f9..90d9a88 100644
--- a/sepolicy/file_contexts
+++ b/sepolicy/file_contexts
@@ -25,6 +25,11 @@
/system/bin/wcnss_filter u:object_r:wcnss_filter_exec:s0
/data/time(/.*)? u:object_r:time_data_file:s0
+# lights
+/sys/devices/soc/75b7000\.i2c/i2c-9/9-[0-9a-f]+/leds(/.*)? u:object_r:sysfs_leds:s0
+/sys/devices/soc/leds-qpnp-[0-9]+/leds(/.*)? u:object_r:sysfs_leds:s0
+/(vendor|system/vendor)/bin/hw/android\.hardware\.light@2\.0-service.zuk_8996 u:object_r:hal_light_default_exec:s0
+
# persist
/dev/block/mmcblk0p40 u:object_r:persist_block_device:s0
/persist/rfs(/.*)? u:object_r:rfs_file:s0