diff options
author | Xin Li <delphij@google.com> | 2020-01-15 15:57:11 -0800 |
---|---|---|
committer | Xin Li <delphij@google.com> | 2020-01-15 15:57:11 -0800 |
commit | 1757a9f73982d37ba8da4c2ef355e82f03fd4765 (patch) | |
tree | 34396d9e4c8b4af49bbcff7f053dcd2ae4ce53df | |
parent | ea081333724915b239bc6dc396a22ec35de0abab (diff) | |
parent | 1ad4c16f11bef019e38f9e0f85b1ab8cdf3ab190 (diff) | |
download | interfaces-android10-sidebranch.tar.gz |
DO NOT MERGE - Merge qt-qpr1-dev-plus-aosp-without-vendor (6129114) into stage-aosp-masterandroid10-sidebranch
Bug: 146167222
Change-Id: I35157ba15934c88fcf7560ebd6153ce685168320
-rw-r--r-- | current.txt | 4 | ||||
-rw-r--r-- | light/1.1/Android.bp | 15 | ||||
-rw-r--r-- | light/1.1/ILight.hal | 37 | ||||
-rw-r--r-- | light/1.1/default/Android.bp | 47 | ||||
-rw-r--r-- | light/1.1/default/Light.cpp | 175 | ||||
-rw-r--r-- | light/1.1/default/Light.h | 59 | ||||
-rw-r--r-- | light/1.1/default/LightExt.cpp | 140 | ||||
-rw-r--r-- | light/1.1/default/LightExt.h | 79 | ||||
-rw-r--r-- | light/1.1/default/hardware.google.light@1.1-service.rc | 9 | ||||
-rw-r--r-- | light/1.1/default/service.cpp | 55 |
10 files changed, 620 insertions, 0 deletions
diff --git a/current.txt b/current.txt index 7a1fb24..b0dae6a 100644 --- a/current.txt +++ b/current.txt @@ -1,3 +1,7 @@ +# HALs released in Android P MAR20 QPR + +bcaa8ef72b0ebbcbd0873f600a8d2bc45f76a6fb119ad6aeae4c5347a790aedb hardware.google.light@1.1::ILight + # HALs released in Android P b5f3bf3382d7bddf9c22a5f132ff265168e68c4e5373db702cb260d8b20f27d8 hardware.google.light@1.0::ILight diff --git a/light/1.1/Android.bp b/light/1.1/Android.bp new file mode 100644 index 0000000..3b6fdf9 --- /dev/null +++ b/light/1.1/Android.bp @@ -0,0 +1,15 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "hardware.google.light@1.1", + root: "hardware.google", + srcs: [ + "ILight.hal", + ], + interfaces: [ + "hardware.google.light@1.0", + "android.hardware.light@2.0", + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/light/1.1/ILight.hal b/light/1.1/ILight.hal new file mode 100644 index 0000000..dab0b0a --- /dev/null +++ b/light/1.1/ILight.hal @@ -0,0 +1,37 @@ +/* + * 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. + */ + +package hardware.google.light@1.1; + +import hardware.google.light@1.0::ILight; +import android.hardware.light@2.0::Status; + +interface ILight extends hardware.google.light@1.0::ILight { + /** + * Set High Brightness Mode Sunlight Visibility state to light. + * + * @param state on/off + * @return status result of applying state transformation. + */ + setHbmSv(bool state) generates (Status status); + + /** + * Get High Brightness Mode Sunlight Visibility state. + * + * @return state on/off + */ + getHbmSv() generates (bool state); +}; diff --git a/light/1.1/default/Android.bp b/light/1.1/default/Android.bp new file mode 100644 index 0000000..a6b1e5d --- /dev/null +++ b/light/1.1/default/Android.bp @@ -0,0 +1,47 @@ +// +// 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. +// + +cc_defaults { + name: "hardware.google.light_defaults-1.1", + relative_install_path: "hw", + vendor: true, + srcs: [ + "Light.cpp", + "LightExt.cpp", + ], + shared_libs: [ + "liblog", + "libbase", + "libutils", + "libhardware", + "libhidlbase", + "android.hardware.light@2.0", + "hardware.google.light@1.0", + "hardware.google.light@1.1", + ], +} + +cc_binary { + name: "hardware.google.light@1.1-service", + defaults: [ + "hardware.google.light_defaults-1.1", + "hidl_defaults" + ], + init_rc: ["hardware.google.light@1.1-service.rc"], + srcs: [ + "service.cpp", + ], +} diff --git a/light/1.1/default/Light.cpp b/light/1.1/default/Light.cpp new file mode 100644 index 0000000..b242599 --- /dev/null +++ b/light/1.1/default/Light.cpp @@ -0,0 +1,175 @@ +/* + * 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. + */ + +#define LOG_TAG "light" + +#include <log/log.h> + +#include <stdio.h> + +#include "Light.h" + +namespace android { +namespace hardware { +namespace light { +namespace V2_0 { +namespace implementation { + +static_assert(LIGHT_FLASH_NONE == static_cast<int>(Flash::NONE), + "Flash::NONE must match legacy value."); +static_assert(LIGHT_FLASH_TIMED == static_cast<int>(Flash::TIMED), + "Flash::TIMED must match legacy value."); +static_assert(LIGHT_FLASH_HARDWARE == static_cast<int>(Flash::HARDWARE), + "Flash::HARDWARE must match legacy value."); + +static_assert(BRIGHTNESS_MODE_USER == static_cast<int>(Brightness::USER), + "Brightness::USER must match legacy value."); +static_assert(BRIGHTNESS_MODE_SENSOR == static_cast<int>(Brightness::SENSOR), + "Brightness::SENSOR must match legacy value."); +static_assert(BRIGHTNESS_MODE_LOW_PERSISTENCE == + static_cast<int>(Brightness::LOW_PERSISTENCE), + "Brightness::LOW_PERSISTENCE must match legacy value."); + +Light::Light(std::map<Type, light_device_t*>&& lights) + : mLights(std::move(lights)) {} + +// 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; + + light_device_t* hwLight = it->second; + + light_state_t legacyState{ + .color = 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 Status::BRIGHTNESS_NOT_SUPPORTED; + case 0: + return Status::SUCCESS; + default: + return Status::UNKNOWN; + } +} + +Return<void> Light::getSupportedTypes(getSupportedTypes_cb _hidl_cb) { + std::vector<Type> types(mLights.size()); + + int idx = 0; + for (const auto& pair : mLights) { + types[idx++] = pair.first; + } + + hidl_vec<Type> hidl_types{}; + hidl_types.setToExternal(types.data(), types.size()); + + _hidl_cb(hidl_types); + + return Void(); +} + +static const std::map<Type, const char*> kLogicalLights = { + {Type::BACKLIGHT, LIGHT_ID_BACKLIGHT}, + {Type::KEYBOARD, LIGHT_ID_KEYBOARD}, + {Type::BUTTONS, LIGHT_ID_BUTTONS}, + {Type::BATTERY, LIGHT_ID_BATTERY}, + {Type::NOTIFICATIONS, LIGHT_ID_NOTIFICATIONS}, + {Type::ATTENTION, LIGHT_ID_ATTENTION}, + {Type::BLUETOOTH, LIGHT_ID_BLUETOOTH}, + {Type::WIFI, LIGHT_ID_WIFI}}; + +Return<void> Light::debug(const hidl_handle& handle, + const hidl_vec<hidl_string>& /* options */) { + if (handle == nullptr || handle->numFds < 1) { + ALOGE("debug called with no handle\n"); + return Void(); + } + + int fd = handle->data[0]; + if (fd < 0) { + ALOGE("invalid FD: %d\n", handle->data[0]); + return Void(); + } + + dprintf(fd, "The following lights are registered: "); + for (const auto& pair : mLights) { + const Type type = pair.first; + dprintf(fd, "%s,", kLogicalLights.at(type)); + } + dprintf(fd, ".\n"); + fsync(fd); + return Void(); +} + +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; + } +} + +ILight* HIDL_FETCH_ILight(const char* /* name */) { + std::map<Type, light_device_t*> lights; + + for (const auto& pair : kLogicalLights) { + Type type = pair.first; + const char* name = pair.second; + + light_device_t* light = getLightDevice(name); + + if (light != nullptr) lights[type] = light; + } + + if (lights.size() == 0) { + // Log information, but still return new Light. + // Some devices may not have any lights. + ALOGI("Could not open any lights."); + } + + return new Light(std::move(lights)); +} + +} // namespace implementation +} // namespace V2_0 +} // namespace light +} // namespace hardware +} // namespace android diff --git a/light/1.1/default/Light.h b/light/1.1/default/Light.h new file mode 100644 index 0000000..87f71b8 --- /dev/null +++ b/light/1.1/default/Light.h @@ -0,0 +1,59 @@ +/* + * 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. + */ +#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 <hardware/hardware.h> +#include <hardware/lights.h> +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> +#include <map> + +namespace android { +namespace hardware { +namespace light { +namespace V2_0 { +namespace implementation { + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +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; + +struct Light : public ILight { + Light(std::map<Type, light_device_t*>&& lights); + + Return<Status> setLight(Type type, const LightState& state) override; + Return<void> getSupportedTypes(getSupportedTypes_cb _hidl_cb) override; + + Return<void> debug(const hidl_handle& handle, + const hidl_vec<hidl_string>& options) override; + + private: + std::map<Type, light_device_t*> mLights; +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace light +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H diff --git a/light/1.1/default/LightExt.cpp b/light/1.1/default/LightExt.cpp new file mode 100644 index 0000000..3fc9c4c --- /dev/null +++ b/light/1.1/default/LightExt.cpp @@ -0,0 +1,140 @@ +/* + * 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. + */ + +#define LOG_TAG "light" + +#include <android-base/file.h> +#include <hardware/lights.h> +#include <log/log.h> + +#include "LightExt.h" + +namespace hardware { +namespace google { +namespace light { +namespace V1_1 { +namespace implementation { +using ::android::hardware::light::V2_0::Brightness; + +#define HBM_OFF "0" +#define HBM_ON "1" +#define HBM_SV "2" + +Return<Status> LightExt::applyHBM() { + if (!mHasHbmNode) return Status::UNKNOWN; + + /* skip if no change */ + if (mRegHBM == mCurHBM && mRegHBMSV == mCurHBMSV) return Status::SUCCESS; + + // off + // <-------- + // 0,0 --------> 0,1 + // | ^ sv ^ | + // hbm| | off nop| |nop + // V | sv | V + // 1,0 --------> 1,1 + // <-------- + // hbm + + // Transition from (mCurHBM, mCurHBMSV) --> (mRegHBM, mRegHBMSV) + const char *action = NULL; + + if (!mRegHBM && !mRegHBMSV) { + // to state (0,0) + action = HBM_OFF; + } else if (mRegHBMSV) { + // to state (0,1) or (1,1). + if (!mCurHBMSV) + action = HBM_SV; + } else { + // to state (1,0) + action = HBM_ON; + } + + if (action) { + if (!android::base::WriteStringToFile(action, kHighBrightnessModeNode)) { + ALOGE("write %s to HBM sysfs file failed!", action); + return Status::UNKNOWN; + } + + ALOGD("write %s to HBM sysfs file succeeded", action); + } + + mCurHBM = mRegHBM; + mCurHBMSV = mRegHBMSV; + + return Status::SUCCESS; +} + +// Methods from ::android::hardware::light::V2_0::ILight follow. +Return<Status> LightExt::setLight(Type type, const LightState& state) { + if (type == Type::BACKLIGHT) { + if (state.brightnessMode == Brightness::LOW_PERSISTENCE) { + mRegHBM = false; + mRegHBMSV = false; + applyHBM(); + mVRMode = true; + } else { + // VR has higher priority than HBM. We cannot update HBM status + // when VR is enabled. Disable VR before apply HBM mode + Status status = mLight->setLight(type, state); + mVRMode = false; + applyHBM(); + return status; + } + } + return mLight->setLight(type, state); +} + +// Methods from ::hardware::google::light::V1_0::ILight follow. +Return<Status> LightExt::setHbm(bool on) { + /* save the request state */ + mRegHBM = on; + + if (mVRMode) return Status::UNKNOWN; + + Status status = applyHBM(); + + if (status != Status::SUCCESS) + mRegHBM = mCurHBM; + + return status; +} + +// Methods from ::hardware::google::light::V1_1::ILight follow. +Return<Status> LightExt::setHbmSv(bool on) { + /* save the request state */ + mRegHBMSV = on; + + if (mVRMode) return Status::UNKNOWN; + + Status status = applyHBM(); + + if (status != Status::SUCCESS) + mRegHBMSV = mCurHBMSV; + + return status; +} + +Return<bool> LightExt::getHbmSv() { + return mCurHBMSV; +} + +} // namespace implementation +} // namespace V1_1 +} // namespace light +} // namespace google +} // namespace hardware diff --git a/light/1.1/default/LightExt.h b/light/1.1/default/LightExt.h new file mode 100644 index 0000000..420e61e --- /dev/null +++ b/light/1.1/default/LightExt.h @@ -0,0 +1,79 @@ +/* + * 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. + */ +#ifndef HARDWARE_GOOGLE_LIGHT_V1_1_LIGHT_H +#define HARDWARE_GOOGLE_LIGHT_V1_1_LIGHT_H + +#include <hidl/Status.h> +#include <string> + +#include <hidl/MQDescriptor.h> +#include <hardware/google/light/1.1/ILight.h> +#include "Light.h" + +namespace hardware { +namespace google { +namespace light { +namespace V1_1 { +namespace implementation { + +using ::android::hardware::Return; +using ::android::hardware::light::V2_0::LightState; +using ::android::hardware::light::V2_0::Status; +using ::android::hardware::light::V2_0::Type; +using HwILight = ::android::hardware::light::V2_0::ILight; + +constexpr const char kHighBrightnessModeNode[] = + "/sys/class/backlight/panel0-backlight/hbm_mode"; + +struct LightExt : public ::hardware::google::light::V1_1::ILight { + LightExt(HwILight*&& light) : mLight(light) { + mHasHbmNode = !access(kHighBrightnessModeNode, F_OK); + if (mHasHbmNode) { + // In case this service is crashed/restarted and leaves hbm on. + setHbm(false); + setHbmSv(false); + } + }; + + // 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 { + return mLight->getSupportedTypes(_hidl_cb); + } + + // Methods from ::hardware::google::light::V1_0::ILight follow. + Return<Status> setHbm(bool on) override; + // Methods from ::hardware::google::light::V1_1::ILight follow. + Return<Status> setHbmSv(bool on) override; + Return<bool> getHbmSv() override; + + private: + std::unique_ptr<HwILight> mLight; + Return<Status> applyHBM(); + bool mVRMode = 0; + bool mRegHBM = 0; + bool mRegHBMSV = 0; + bool mCurHBM = 0; + bool mCurHBMSV = 0; + bool mHasHbmNode = false; +}; +} // namespace implementation +} // namespace V1_1 +} // namespace light +} // namespace google +} // namespace hardware + +#endif // HARDWARD_GOOGLE_LIGHT_V1_1_LIGHT_H diff --git a/light/1.1/default/hardware.google.light@1.1-service.rc b/light/1.1/default/hardware.google.light@1.1-service.rc new file mode 100644 index 0000000..5714781 --- /dev/null +++ b/light/1.1/default/hardware.google.light@1.1-service.rc @@ -0,0 +1,9 @@ +service vendor.light-1-1 /vendor/bin/hw/hardware.google.light@1.1-service + interface android.hardware.light@2.0::ILight default + interface hardware.google.light@1.0::ILight default + interface hardware.google.light@1.1::ILight default + class hal + user system + group system + # shutting off lights while powering-off + shutdown critical diff --git a/light/1.1/default/service.cpp b/light/1.1/default/service.cpp new file mode 100644 index 0000000..275f68a --- /dev/null +++ b/light/1.1/default/service.cpp @@ -0,0 +1,55 @@ +/* + * 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. + */ +#define LOG_TAG "hardware.google.light@1.1-service" + +#include <hardware/lights.h> +#include <hidl/LegacySupport.h> +#include <hardware/google/light/1.1/ILight.h> +#include "LightExt.h" + +namespace android { +namespace hardware { +namespace light { +namespace V2_0 { +namespace implementation { + +extern ILight* HIDL_FETCH_ILight(const char* /* name */); + +} // namespace implementation +} // namespace V2_0 +} // namespace light +} // namespace hardware +} // namespace android + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using hardware::google::light::V1_1::implementation::LightExt; +using hwLight = hardware::google::light::V1_1::ILight; + +int main() { + configureRpcThreadpool(1, true /*willJoinThreadpool*/); + + android::sp<hwLight> light = new LightExt{ + android::hardware::light::V2_0::implementation::HIDL_FETCH_ILight( + nullptr)}; + auto ret = light->registerAsService(); + if (ret != android::OK) { + ALOGE("open light servie failed, ret=%d", ret); + return 1; + } + joinRpcThreadpool(); + return 1; +} |