summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lights/Android.bp18
-rw-r--r--lights/Lights.cpp118
-rw-r--r--lights/Lights.h43
-rw-r--r--lights/android.hardware.lights-qti.rc5
-rw-r--r--lights/android.hardware.lights-qti.xml6
-rw-r--r--lights/main.cpp34
6 files changed, 224 insertions, 0 deletions
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..aa288b0
--- /dev/null
+++ b/lights/Lights.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2019 The Android Open Source 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.
+ */
+
+#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<LightType, light_device_t*> lights;
+ std::vector<HwLight> availableLights;
+ for(auto const &pair : kLogicalLights) {
+ LightType type = pair.first;
+ const char* name = pair.second;
+ light_device_t* lightDevice = getLightDevice(name);
+ if (lightDevice != nullptr) {
+ lights[type] = lightDevice;
+ }
+ HwLight hwLight{};
+ hwLight.id = availableLights.size();
+ hwLight.type = type;
+ hwLight.ordinal = 0;
+ availableLights.emplace_back(hwLight);
+ }
+ mAvailableLights = availableLights;
+ mLights = lights;
+}
+
+ndk::ScopedAStatus Lights::setLightState(int id, const HwLightState& state) {
+ if (id >= mAvailableLights.size()) {
+ ALOGE("Invalid Light id : %d", id);
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ HwLight const& light = mAvailableLights[id];
+ auto it = mLights.find(light.type);
+ 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..879ea55
--- /dev/null
+++ b/lights/Lights.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source 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.
+ */
+
+#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<LightType, light_device_t*> mLights;
+ std::vector<HwLight> mAvailableLights;
+};
+
+} // 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..5bab50d
--- /dev/null
+++ b/lights/main.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source 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.
+ */
+
+#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>();
+
+ 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
+}