diff --git a/light/aidl/Android.bp b/light/aidl/Android.bp new file mode 100644 index 00000000..cd4c44ee --- /dev/null +++ b/light/aidl/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/light/aidl/Lights.cpp b/light/aidl/Lights.cpp new file mode 100644 index 00000000..aa288b03 --- /dev/null +++ b/light/aidl/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 +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace light { + +const static std::map 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(&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 lights; + std::vector 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(state.color), + .flashMode = static_cast(state.flashMode), + .flashOnMS = state.flashOnMs, + .flashOffMS = state.flashOffMs, + .brightnessMode = static_cast(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* 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/light/aidl/Lights.h b/light/aidl/Lights.h new file mode 100644 index 00000000..879ea552 --- /dev/null +++ b/light/aidl/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 +#include +#include +#include + +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* types) override; + + private: + std::map mLights; + std::vector mAvailableLights; +}; + +} // namespace light +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/light/aidl/android.hardware.lights-qti.rc b/light/aidl/android.hardware.lights-qti.rc new file mode 100644 index 00000000..beb1c8d5 --- /dev/null +++ b/light/aidl/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/light/aidl/android.hardware.lights-qti.xml b/light/aidl/android.hardware.lights-qti.xml new file mode 100644 index 00000000..db604d61 --- /dev/null +++ b/light/aidl/android.hardware.lights-qti.xml @@ -0,0 +1,6 @@ + + + android.hardware.light + ILights/default + + diff --git a/light/aidl/main.cpp b/light/aidl/main.cpp new file mode 100644 index 00000000..5bab50d7 --- /dev/null +++ b/light/aidl/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 +#include +#include + +using ::aidl::android::hardware::light::Lights; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr lights = ndk::SharedRefBase::make(); + + 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 +}