zenfone8: Import the QTI AIDL lights HAL from LA.UM.9.14.r1-17700-LAHAINA.0.

Change-Id: I86dccd1ae8b3b236f05dca79ad1f25f1e042fd48
diff --git a/device.mk b/device.mk
index a10fb65..3d10544 100755
--- a/device.mk
+++ b/device.mk
@@ -205,6 +205,10 @@
 PRODUCT_PACKAGES += \
     android.hardware.keymaster@4.1.vendor
 
+# Lights
+PRODUCT_PACKAGES += \
+    android.hardware.lights-service.qti
+
 # Live Wallpapers
 PRODUCT_PACKAGES += \
     LiveWallpapers \
diff --git a/lights/Android.bp b/lights/Android.bp
new file mode 100644
index 0000000..cd4c44e
--- /dev/null
+++ b/lights/Android.bp
@@ -0,0 +1,18 @@
+cc_binary {
+    name: "android.hardware.lights-service.qti",
+    relative_install_path: "hw",
+    init_rc: ["android.hardware.lights-qti.rc"],
+    vintf_fragments: ["android.hardware.lights-qti.xml"],
+    vendor: true,
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libhardware",
+        "libbinder_ndk",
+        "android.hardware.light-ndk_platform",
+    ],
+    srcs: [
+        "Lights.cpp",
+        "main.cpp",
+    ],
+}
diff --git a/lights/Lights.cpp b/lights/Lights.cpp
new file mode 100644
index 0000000..fc98433
--- /dev/null
+++ b/lights/Lights.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "Lights.h"
+#include <log/log.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace light {
+
+const static std::map<LightType, const char*> kLogicalLights = {
+    {LightType::BACKLIGHT,     LIGHT_ID_BACKLIGHT},
+    {LightType::KEYBOARD,      LIGHT_ID_KEYBOARD},
+    {LightType::BUTTONS,       LIGHT_ID_BUTTONS},
+    {LightType::BATTERY,       LIGHT_ID_BATTERY},
+    {LightType::NOTIFICATIONS, LIGHT_ID_NOTIFICATIONS},
+    {LightType::ATTENTION,     LIGHT_ID_ATTENTION},
+    {LightType::BLUETOOTH,     LIGHT_ID_BLUETOOTH},
+    {LightType::WIFI,          LIGHT_ID_WIFI}
+};
+
+light_device_t* getLightDevice(const char* name) {
+    light_device_t* lightDevice;
+    const hw_module_t* hwModule = NULL;
+    int ret = hw_get_module (LIGHTS_HARDWARE_MODULE_ID, &hwModule);
+    if (ret == 0) {
+        ret = hwModule->methods->open(hwModule, name,
+            reinterpret_cast<hw_device_t**>(&lightDevice));
+        if (ret != 0) {
+            ALOGE("light_open %s %s failed: %d", LIGHTS_HARDWARE_MODULE_ID, name, ret);
+        }
+    } else {
+        ALOGE("hw_get_module %s %s failed: %d", LIGHTS_HARDWARE_MODULE_ID, name, ret);
+    }
+    if (ret == 0) {
+        return lightDevice;
+    } else {
+        ALOGE("Light passthrough failed to load legacy HAL.");
+        return nullptr;
+    }
+}
+
+Lights::Lights() {
+    std::map<int, light_device_t*> lights;
+    std::vector<HwLight> availableLights;
+    int lightCount =0;
+    for(auto const &pair : kLogicalLights) {
+        LightType type = pair.first;
+        const char* name = pair.second;
+        light_device_t* lightDevice = getLightDevice(name);
+        lightCount++;
+        if (lightDevice != nullptr) {
+            HwLight hwLight{};
+            hwLight.id = (int)type;
+            hwLight.type = type;
+            hwLight.ordinal = 0;
+            lights[hwLight.id] = lightDevice;
+            availableLights.emplace_back(hwLight);
+        }
+    }
+    mAvailableLights = availableLights;
+    mLights = lights;
+    maxLights = lightCount;
+}
+
+ndk::ScopedAStatus Lights::setLightState(int id, const HwLightState& state) {
+    if (id >= maxLights) {
+        ALOGE("Invalid Light id : %d", id);
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    auto it = mLights.find(id);
+    if (it == mLights.end()) {
+        ALOGE("Light not supported");
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    light_device_t* hwLight = it->second;
+    light_state_t legacyState {
+        .color = static_cast<unsigned int>(state.color),
+        .flashMode = static_cast<int>(state.flashMode),
+        .flashOnMS = state.flashOnMs,
+        .flashOffMS = state.flashOffMs,
+        .brightnessMode = static_cast<int>(state.brightnessMode),
+    };
+    int ret = hwLight->set_light(hwLight, &legacyState);
+    switch (ret) {
+        case -ENOSYS:
+            return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+        case 0:
+            return ndk::ScopedAStatus::ok();
+        default:
+            return ndk::ScopedAStatus::fromServiceSpecificError(ret);
+    }
+}
+
+ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* lights) {
+    for (auto i = mAvailableLights.begin(); i != mAvailableLights.end(); i++) {
+        lights->push_back(*i);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace light
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/lights/Lights.h b/lights/Lights.h
new file mode 100644
index 0000000..3d0cac5
--- /dev/null
+++ b/lights/Lights.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/light/BnLights.h>
+#include <hardware/hardware.h>
+#include <hardware/lights.h>
+#include <map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace light {
+
+class Lights : public BnLights {
+    public:
+      Lights();
+      ndk::ScopedAStatus setLightState(int id, const HwLightState& state) override;
+      ndk::ScopedAStatus getLights(std::vector<HwLight>* types) override;
+
+    private:
+      std::map<int, light_device_t*> mLights;
+      std::vector<HwLight> mAvailableLights;
+      int maxLights;
+};
+
+}  // namespace light
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/lights/android.hardware.lights-qti.rc b/lights/android.hardware.lights-qti.rc
new file mode 100644
index 0000000..beb1c8d
--- /dev/null
+++ b/lights/android.hardware.lights-qti.rc
@@ -0,0 +1,5 @@
+service vendor.light-qti /vendor/bin/hw/android.hardware.lights-service.qti
+    class hal
+    user system
+    group system
+    shutdown critical
diff --git a/lights/android.hardware.lights-qti.xml b/lights/android.hardware.lights-qti.xml
new file mode 100644
index 0000000..db604d6
--- /dev/null
+++ b/lights/android.hardware.lights-qti.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.light</name>
+        <fqname>ILights/default</fqname>
+    </hal>
+</manifest>
diff --git a/lights/main.cpp b/lights/main.cpp
new file mode 100644
index 0000000..c3d5f79
--- /dev/null
+++ b/lights/main.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "Lights.h"
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using ::aidl::android::hardware::light::Lights;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<Lights> lights = ndk::SharedRefBase::make<Lights>();
+    if (!lights) {
+        return EXIT_FAILURE;
+    }
+
+    const std::string instance = std::string() + Lights::descriptor + "/default";
+    binder_status_t status = AServiceManager_addService(lights->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reached
+}