diff options
author | Steven Laver <lavers@google.com> | 2020-02-04 22:57:22 -0800 |
---|---|---|
committer | Steven Laver <lavers@google.com> | 2020-02-06 14:27:42 -0800 |
commit | 89ec9480cf4430b6728b16396a408c1aa26f19a9 (patch) | |
tree | f9a888e63588b25c457d8871f6fbb6b673044f1a /light | |
parent | 4e64db5a184f0734778df5e1c12d32f702220b35 (diff) | |
parent | 146a5a28331209aa145c0af2f883b7e023ce4800 (diff) |
Merge RP1A.200204.001
Change-Id: Icdc452e8cf70e432759c112a5b5b12b61e40f0bc
Diffstat (limited to 'light')
-rw-r--r-- | light/aidl/Android.bp | 18 | ||||
-rw-r--r-- | light/aidl/android/hardware/light/BrightnessMode.aidl | 58 | ||||
-rw-r--r-- | light/aidl/android/hardware/light/FlashMode.aidl | 34 | ||||
-rw-r--r-- | light/aidl/android/hardware/light/HwLight.aidl | 42 | ||||
-rw-r--r-- | light/aidl/android/hardware/light/HwLightState.aidl | 64 | ||||
-rw-r--r-- | light/aidl/android/hardware/light/ILights.aidl | 47 | ||||
-rw-r--r-- | light/aidl/android/hardware/light/LightType.aidl | 35 | ||||
-rw-r--r-- | light/aidl/default/Android.bp | 16 | ||||
-rw-r--r-- | light/aidl/default/Lights.cpp | 39 | ||||
-rw-r--r-- | light/aidl/default/Lights.h | 35 | ||||
-rw-r--r-- | light/aidl/default/lights-default.rc | 5 | ||||
-rw-r--r-- | light/aidl/default/lights-default.xml | 6 | ||||
-rw-r--r-- | light/aidl/default/main.cpp | 35 | ||||
-rw-r--r-- | light/aidl/vts/functional/Android.bp | 35 | ||||
-rw-r--r-- | light/aidl/vts/functional/VtsHalLightTargetTest.cpp | 171 | ||||
-rw-r--r-- | light/utils/Android.bp | 4 | ||||
-rw-r--r-- | light/utils/main.cpp | 104 |
17 files changed, 717 insertions, 31 deletions
diff --git a/light/aidl/Android.bp b/light/aidl/Android.bp new file mode 100644 index 0000000000..916a857b58 --- /dev/null +++ b/light/aidl/Android.bp @@ -0,0 +1,18 @@ +aidl_interface { + name: "android.hardware.light", + vendor_available: true, + srcs: [ + "android/hardware/light/*.aidl", + ], + stability: "vintf", + backend: { + java: { + platform_apis: true, + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} diff --git a/light/aidl/android/hardware/light/BrightnessMode.aidl b/light/aidl/android/hardware/light/BrightnessMode.aidl new file mode 100644 index 0000000000..bc296990ce --- /dev/null +++ b/light/aidl/android/hardware/light/BrightnessMode.aidl @@ -0,0 +1,58 @@ +/* + * 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. + */ +package android.hardware.light; + +@VintfStability +enum BrightnessMode { + /** + * Light brightness is managed by a user setting. + */ + USER = 0, + + /** + * Light brightness is managed by a light sensor. This is typically used + * to control the display backlight, but not limited to it. HALs and + * hardware implementations are free to support sensor for other lights or + * none whatsoever. + */ + SENSOR = 1, + + /** + * Use a low-persistence mode for display backlights, where the pixel + * color transition times are lowered. + * + * When set, the device driver must switch to a mode optimized for low display + * persistence that is intended to be used when the device is being treated as a + * head mounted display (HMD). The actual display brightness in this mode is + * implementation dependent, and any value set for color in LightState may be + * overridden by the HAL implementation. + * + * For an optimal HMD viewing experience, the display must meet the following + * criteria in this mode: + * - Gray-to-Gray, White-to-Black, and Black-to-White switching time must be ≤ 3 ms. + * - The display must support low-persistence with ≤ 3.5 ms persistence. + * Persistence is defined as the amount of time for which a pixel is + * emitting light for a single frame. + * - Any "smart panel" or other frame buffering options that increase display + * latency are disabled. + * - Display brightness is set so that the display is still visible to the user + * under normal indoor lighting. + * - The display must update at 60 Hz at least, but higher refresh rates are + * recommended for low latency. + * + */ + LOW_PERSISTENCE = 2, +} diff --git a/light/aidl/android/hardware/light/FlashMode.aidl b/light/aidl/android/hardware/light/FlashMode.aidl new file mode 100644 index 0000000000..00c6b6a028 --- /dev/null +++ b/light/aidl/android/hardware/light/FlashMode.aidl @@ -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. + */ +package android.hardware.light; + +@VintfStability +enum FlashMode { + /** + * Keep the light steady on or off. + */ + NONE = 0, + /** + * Flash the light at specified rate, potentially using a software-based + * implementation. + */ + TIMED = 1, + /** + * Flash the light using hardware flashing support. This may or may not + * support a user-defined flashing rate or other features. + */ + HARDWARE = 2, +} diff --git a/light/aidl/android/hardware/light/HwLight.aidl b/light/aidl/android/hardware/light/HwLight.aidl new file mode 100644 index 0000000000..43fdb4bf81 --- /dev/null +++ b/light/aidl/android/hardware/light/HwLight.aidl @@ -0,0 +1,42 @@ +/* + * 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 android.hardware.light; + +import android.hardware.light.LightType; + +/** + * A description of a single light. Multiple lights can map to the same physical + * LED. Separate physical LEDs are always represented by separate instances. + */ +@VintfStability +parcelable HwLight { + /** + * Integer ID used for controlling this light + */ + int id; + + /** + * For a group of lights of the same logical type, sorting by ordinal should + * be give their physical order. No other meaning is carried by it. + */ + int ordinal; + + /** + * Logical type use of this light. + */ + LightType type; +} diff --git a/light/aidl/android/hardware/light/HwLightState.aidl b/light/aidl/android/hardware/light/HwLightState.aidl new file mode 100644 index 0000000000..24d3250887 --- /dev/null +++ b/light/aidl/android/hardware/light/HwLightState.aidl @@ -0,0 +1,64 @@ +/* + * 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. + */ + +package android.hardware.light; + +import android.hardware.light.BrightnessMode; +import android.hardware.light.FlashMode; + +/** + * The parameters that can be set for a given light. + * + * Not all lights must support all parameters. If you + * can do something backward-compatible, do it. + */ +@VintfStability +parcelable HwLightState { + /** + * The color of the LED in ARGB. + * + * The implementation of this in the HAL and hardware is a best-effort one. + * - If a light can only do red or green and blue is requested, green + * should be shown. + * - If only a brightness ramp is supported, then this formula applies: + * unsigned char brightness = ((77*((color>>16)&0x00ff)) + * + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8; + * - If only on and off are supported, 0 is off, anything else is on. + * + * The high byte should be ignored. Callers should set it to 0xff (which + * would correspond to 255 alpha). + */ + int color; + + /** + * To flash the light at a given rate, set flashMode to FLASH_TIMED. + */ + FlashMode flashMode; + + /** + * flashOnMs should be set to the number of milliseconds to turn the + * light on, before it's turned off. + */ + int flashOnMs; + + /** + * flashOfMs should be set to the number of milliseconds to turn the + * light off, before it's turned back on. + */ + int flashOffMs; + + BrightnessMode brightnessMode; +} diff --git a/light/aidl/android/hardware/light/ILights.aidl b/light/aidl/android/hardware/light/ILights.aidl new file mode 100644 index 0000000000..2253f73c36 --- /dev/null +++ b/light/aidl/android/hardware/light/ILights.aidl @@ -0,0 +1,47 @@ +/* + * 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. + */ + +package android.hardware.light; + +import android.hardware.light.HwLightState; +import android.hardware.light.HwLight; + +/** + * Allows controlling logical lights/indicators, mapped to LEDs in a + * hardware-specific manner by the HAL implementation. + */ +@VintfStability +interface ILights { + /** + * Set light identified by id to the provided state. + * + * If control over an invalid light is requested, this method exists with + * EX_UNSUPPORTED_OPERATION. Control over supported lights is done on a + * device-specific best-effort basis and unsupported sub-features will not + * be reported. + * + * @param id ID of logical light to set as returned by getLights() + * @param state describes what the light should look like. + */ + void setLightState(in int id, in HwLightState state); + + /** + * Discover what lights are supported by the HAL implementation. + * + * @return List of available lights + */ + HwLight[] getLights(); +} diff --git a/light/aidl/android/hardware/light/LightType.aidl b/light/aidl/android/hardware/light/LightType.aidl new file mode 100644 index 0000000000..9a7f65619d --- /dev/null +++ b/light/aidl/android/hardware/light/LightType.aidl @@ -0,0 +1,35 @@ +/* + * 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. + */ +package android.hardware.light; + +/** + * These light IDs correspond to logical lights, not physical. + * So for example, if your INDICATOR light is in line with your + * BUTTONS, it might make sense to also light the INDICATOR + * light to a reasonable color when the BUTTONS are lit. + */ +@VintfStability +enum LightType { + BACKLIGHT = 0, + KEYBOARD = 1, + BUTTONS = 2, + BATTERY = 3, + NOTIFICATIONS = 4, + ATTENTION = 5, + BLUETOOTH = 6, + WIFI = 7, + MICROPHONE = 8, +} diff --git a/light/aidl/default/Android.bp b/light/aidl/default/Android.bp new file mode 100644 index 0000000000..ae3f4630de --- /dev/null +++ b/light/aidl/default/Android.bp @@ -0,0 +1,16 @@ +cc_binary { + name: "android.hardware.lights-service.example", + relative_install_path: "hw", + init_rc: ["lights-default.rc"], + vintf_fragments: ["lights-default.xml"], + vendor: true, + shared_libs: [ + "libbase", + "libbinder_ndk", + "android.hardware.light-ndk_platform", + ], + srcs: [ + "Lights.cpp", + "main.cpp", + ], +} diff --git a/light/aidl/default/Lights.cpp b/light/aidl/default/Lights.cpp new file mode 100644 index 0000000000..74747d57bd --- /dev/null +++ b/light/aidl/default/Lights.cpp @@ -0,0 +1,39 @@ +/* + * 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 <android-base/logging.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace light { + +ndk::ScopedAStatus Lights::setLightState(int id, const HwLightState& state) { + LOG(INFO) << "Lights setting state for id=" << id << " to color " << std::hex << state.color; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* /*lights*/) { + LOG(INFO) << "Lights reporting supported lights"; + return ndk::ScopedAStatus::ok(); +} + +} // namespace light +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/light/aidl/default/Lights.h b/light/aidl/default/Lights.h new file mode 100644 index 0000000000..8cba5a1cfd --- /dev/null +++ b/light/aidl/default/Lights.h @@ -0,0 +1,35 @@ +/* + * 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> + +namespace aidl { +namespace android { +namespace hardware { +namespace light { + +// Default implementation that reports no supported lights. +class Lights : public BnLights { + ndk::ScopedAStatus setLightState(int id, const HwLightState& state) override; + ndk::ScopedAStatus getLights(std::vector<HwLight>* types) override; +}; + +} // namespace light +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/light/aidl/default/lights-default.rc b/light/aidl/default/lights-default.rc new file mode 100644 index 0000000000..687ec97dd1 --- /dev/null +++ b/light/aidl/default/lights-default.rc @@ -0,0 +1,5 @@ +service vendor.light-default /vendor/bin/hw/android.hardware.lights-service.example + class hal + user nobody + group nobody + shutdown critical diff --git a/light/aidl/default/lights-default.xml b/light/aidl/default/lights-default.xml new file mode 100644 index 0000000000..db604d61f0 --- /dev/null +++ b/light/aidl/default/lights-default.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/light/aidl/default/main.cpp b/light/aidl/default/main.cpp new file mode 100644 index 0000000000..a860bf4a98 --- /dev/null +++ b/light/aidl/default/main.cpp @@ -0,0 +1,35 @@ +/* + * 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 +} diff --git a/light/aidl/vts/functional/Android.bp b/light/aidl/vts/functional/Android.bp new file mode 100644 index 0000000000..3dd8cf64ce --- /dev/null +++ b/light/aidl/vts/functional/Android.bp @@ -0,0 +1,35 @@ +// +// 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. +// + +cc_test { + name: "VtsHalLightTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: [ + "VtsHalLightTargetTest.cpp", + ], + shared_libs: [ + "libbinder", + ], + static_libs: [ + "android.hardware.light-cpp", + ], + test_suites: [ + "vts-core", + ], +} diff --git a/light/aidl/vts/functional/VtsHalLightTargetTest.cpp b/light/aidl/vts/functional/VtsHalLightTargetTest.cpp new file mode 100644 index 0000000000..3c26278a19 --- /dev/null +++ b/light/aidl/vts/functional/VtsHalLightTargetTest.cpp @@ -0,0 +1,171 @@ +/* + * 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. + */ + +#define LOG_TAG "light_aidl_hal_test" + +#include <aidl/Gtest.h> +#include <aidl/Vintf.h> + +#include <android-base/logging.h> +#include <android/hardware/light/ILights.h> +#include <binder/IServiceManager.h> +#include <binder/ProcessState.h> +#include <gtest/gtest.h> +#include <hidl/GtestPrinter.h> +#include <hidl/ServiceManagement.h> + +#include <unistd.h> +#include <set> + +using android::ProcessState; +using android::sp; +using android::String16; +using android::binder::Status; +using android::hardware::hidl_vec; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::light::BrightnessMode; +using android::hardware::light::FlashMode; +using android::hardware::light::HwLight; +using android::hardware::light::HwLightState; +using android::hardware::light::ILights; +using android::hardware::light::LightType; + +#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) +#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk()) + +const std::set<LightType> kAllTypes{android::enum_range<LightType>().begin(), + android::enum_range<LightType>().end()}; + +class LightsAidl : public testing::TestWithParam<std::string> { + public: + virtual void SetUp() override { + lights = android::waitForDeclaredService<ILights>(String16(GetParam().c_str())); + ASSERT_NE(lights, nullptr); + ASSERT_TRUE(lights->getLights(&supportedLights).isOk()); + } + + sp<ILights> lights; + std::vector<HwLight> supportedLights; + + virtual void TearDown() override { + for (const HwLight& light : supportedLights) { + HwLightState off; + off.color = 0x00000000; + off.flashMode = FlashMode::NONE; + off.brightnessMode = BrightnessMode::USER; + EXPECT_TRUE(lights->setLightState(light.id, off).isOk()); + } + + // must leave the device in a useable condition + for (const HwLight& light : supportedLights) { + if (light.type == LightType::BACKLIGHT) { + HwLightState backlightOn; + backlightOn.color = 0xFFFFFFFF; + backlightOn.flashMode = FlashMode::TIMED; + backlightOn.brightnessMode = BrightnessMode::USER; + EXPECT_TRUE(lights->setLightState(light.id, backlightOn).isOk()); + } + } + } +}; + +/** + * Ensure all reported lights actually work. + */ +TEST_P(LightsAidl, TestSupported) { + HwLightState whiteFlashing; + whiteFlashing.color = 0xFFFFFFFF; + whiteFlashing.flashMode = FlashMode::TIMED; + whiteFlashing.flashOnMs = 100; + whiteFlashing.flashOffMs = 50; + whiteFlashing.brightnessMode = BrightnessMode::USER; + for (const HwLight& light : supportedLights) { + EXPECT_TRUE(lights->setLightState(light.id, whiteFlashing).isOk()); + } +} + +/** + * Ensure all reported lights have one of the supported types. + */ +TEST_P(LightsAidl, TestSupportedLightTypes) { + for (const HwLight& light : supportedLights) { + EXPECT_TRUE(kAllTypes.find(light.type) != kAllTypes.end()); + } +} + +/** + * Ensure all lights have a unique id. + */ +TEST_P(LightsAidl, TestUniqueIds) { + std::set<int> ids; + for (const HwLight& light : supportedLights) { + EXPECT_TRUE(ids.find(light.id) == ids.end()); + ids.insert(light.id); + } +} + +/** + * Ensure all lights have a unique ordinal for a given type. + */ +TEST_P(LightsAidl, TestUniqueOrdinalsForType) { + std::map<int, std::set<int>> ordinalsByType; + for (const HwLight& light : supportedLights) { + auto& ordinals = ordinalsByType[(int)light.type]; + EXPECT_TRUE(ordinals.find(light.ordinal) == ordinals.end()); + ordinals.insert(light.ordinal); + } +} + +/** + * Ensure EX_UNSUPPORTED_OPERATION is returned if LOW_PERSISTENCE is not supported. + */ +TEST_P(LightsAidl, TestLowPersistence) { + HwLightState lowPersistence; + lowPersistence.color = 0xFF123456; + lowPersistence.flashMode = FlashMode::TIMED; + lowPersistence.flashOnMs = 100; + lowPersistence.flashOffMs = 50; + lowPersistence.brightnessMode = BrightnessMode::LOW_PERSISTENCE; + for (const HwLight& light : supportedLights) { + Status status = lights->setLightState(light.id, lowPersistence); + EXPECT_TRUE(status.isOk() || Status::EX_UNSUPPORTED_OPERATION == status.exceptionCode()); + } +} + +/** + * Ensure EX_UNSUPPORTED_OPERATION is returns for an invalid light id. + */ +TEST_P(LightsAidl, TestInvalidLightIdUnsupported) { + int maxId = INT_MIN; + for (const HwLight& light : supportedLights) { + maxId = std::max(maxId, light.id); + } + + Status status = lights->setLightState(maxId + 1, HwLightState()); + EXPECT_TRUE(status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION); +} + +INSTANTIATE_TEST_SUITE_P(Lights, LightsAidl, + testing::ValuesIn(android::getAidlHalInstanceNames(ILights::descriptor)), + android::PrintInstanceNameToString); + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ProcessState::self()->setThreadPoolMaxThreadCount(1); + ProcessState::self()->startThreadPool(); + return RUN_ALL_TESTS(); +} diff --git a/light/utils/Android.bp b/light/utils/Android.bp index 4c287e4620..e901129d1f 100644 --- a/light/utils/Android.bp +++ b/light/utils/Android.bp @@ -23,7 +23,11 @@ cc_binary { shared_libs: [ "android.hardware.light@2.0", "libbase", + "libbinder", "libhidlbase", "libutils", ], + static_libs: [ + "android.hardware.light-cpp", + ], } diff --git a/light/utils/main.cpp b/light/utils/main.cpp index b83413246b..b9b6489eec 100644 --- a/light/utils/main.cpp +++ b/light/utils/main.cpp @@ -19,34 +19,23 @@ #include <android-base/logging.h> #include <android/hardware/light/2.0/ILight.h> +#include <android/hardware/light/ILights.h> +#include <binder/IServiceManager.h> + +using android::sp; +using android::waitForVintfService; +using android::binder::Status; +using android::hardware::hidl_vec; + +namespace V2_0 = android::hardware::light::V2_0; +namespace aidl = android::hardware::light; void error(const std::string& msg) { LOG(ERROR) << msg; std::cerr << msg << std::endl; } -int main(int argc, char* argv[]) { - using ::android::hardware::hidl_vec; - using ::android::hardware::light::V2_0::Brightness; - using ::android::hardware::light::V2_0::Flash; - 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; - using ::android::sp; - - sp<ILight> service = ILight::getService(); - if (service == nullptr) { - error("Could not retrieve light service."); - return -1; - } - - static LightState off = { - .color = 0u, - .flashMode = Flash::NONE, - .brightnessMode = Brightness::USER, - }; - +int parseArgs(int argc, char* argv[], unsigned int* color) { if (argc > 2) { error("Usage: blank_screen [color]"); return -1; @@ -54,25 +43,78 @@ int main(int argc, char* argv[]) { if (argc > 1) { char* col_ptr; - unsigned int col_new; - col_new = strtoul(argv[1], &col_ptr, 0); + *color = strtoul(argv[1], &col_ptr, 0); if (*col_ptr != '\0') { error("Failed to convert " + std::string(argv[1]) + " to number"); return -1; } - off.color = col_new; + + return 0; + } + + *color = 0u; + return 0; +} + +void setToColorAidl(sp<aidl::ILights> hal, unsigned int color) { + static aidl::HwLightState off; + off.color = color; + off.flashMode = aidl::FlashMode::NONE; + off.brightnessMode = aidl::BrightnessMode::USER; + + std::vector<aidl::HwLight> lights; + Status status = hal->getLights(&lights); + if (!status.isOk()) { + error("Failed to list lights"); + return; + } + + for (auto light : lights) { + Status setStatus = hal->setLightState(light.id, off); + if (!setStatus.isOk()) { + error("Failed to shut off light id " + std::to_string(light.id)); + } } +} - service->getSupportedTypes([&](const hidl_vec<Type>& types) { - for (Type type : types) { - Status ret = service->setLight(type, off); - if (ret != Status::SUCCESS) { - error("Failed to shut off screen for type " + +void setToColorHidl(sp<V2_0::ILight> hal, unsigned int color) { + static V2_0::LightState off = { + .color = color, + .flashMode = V2_0::Flash::NONE, + .brightnessMode = V2_0::Brightness::USER, + }; + + hal->getSupportedTypes([&](const hidl_vec<V2_0::Type>& types) { + for (auto type : types) { + V2_0::Status ret = hal->setLight(type, off); + if (ret != V2_0::Status::SUCCESS) { + error("Failed to shut off light for type " + std::to_string(static_cast<int>(type))); } } }); +} - return 0; +int main(int argc, char* argv[]) { + unsigned int inputColor; + int result = parseArgs(argc, argv, &inputColor); + if (result != 0) { + return result; + } + + auto aidlHal = waitForVintfService<aidl::ILights>(); + if (aidlHal != nullptr) { + setToColorAidl(aidlHal, inputColor); + return 0; + } + + sp<V2_0::ILight> hidlHal = V2_0::ILight::getService(); + if (hidlHal != nullptr) { + setToColorHidl(hidlHal, inputColor); + return 0; + } + + error("Could not retrieve light service."); + return -1; } |