From 61c2a337a9e26fbbe15c7b7f9dba1c15632bc9ad Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 8 Jan 2020 16:51:47 -0800 Subject: [PATCH] Power: PowerHAL AIDL interface Bug: 146453294 Test: build and run VtsHalPowerTargetTest pass Change-Id: Id2a0194173325015933b0db72067f03a375566ee --- .../compatibility_matrix.current.xml | 3 +- power/aidl/Android.bp | 32 +++++ power/aidl/android/hardware/power/Boost.aidl | 55 ++++++++ power/aidl/android/hardware/power/IPower.aidl | 72 +++++++++++ power/aidl/android/hardware/power/Mode.aidl | 109 ++++++++++++++++ power/aidl/default/Android.bp | 30 +++++ power/aidl/default/Power.cpp | 56 ++++++++ power/aidl/default/Power.h | 40 ++++++ power/aidl/default/main.cpp | 35 +++++ power/aidl/default/power-default.rc | 4 + power/aidl/default/power-default.xml | 6 + power/aidl/vts/Android.bp | 31 +++++ power/aidl/vts/VtsHalPowerTargetTest.cpp | 120 ++++++++++++++++++ 13 files changed, 591 insertions(+), 2 deletions(-) create mode 100644 power/aidl/Android.bp create mode 100644 power/aidl/android/hardware/power/Boost.aidl create mode 100644 power/aidl/android/hardware/power/IPower.aidl create mode 100644 power/aidl/android/hardware/power/Mode.aidl create mode 100644 power/aidl/default/Android.bp create mode 100644 power/aidl/default/Power.cpp create mode 100644 power/aidl/default/Power.h create mode 100644 power/aidl/default/main.cpp create mode 100644 power/aidl/default/power-default.rc create mode 100644 power/aidl/default/power-default.xml create mode 100644 power/aidl/vts/Android.bp create mode 100644 power/aidl/vts/VtsHalPowerTargetTest.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 2bd2c93a8c..9e29ec7749 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -331,9 +331,8 @@ default - + android.hardware.power - 1.0-3 IPower default diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp new file mode 100644 index 0000000000..2a6cf94977 --- /dev/null +++ b/power/aidl/Android.bp @@ -0,0 +1,32 @@ +// 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. + +aidl_interface { + name: "android.hardware.power", + vendor_available: true, + srcs: [ + "android/hardware/power/*.aidl", + ], + stability: "vintf", + backend: { + java: { + platform_apis: true, + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} diff --git a/power/aidl/android/hardware/power/Boost.aidl b/power/aidl/android/hardware/power/Boost.aidl new file mode 100644 index 0000000000..162a36ac2c --- /dev/null +++ b/power/aidl/android/hardware/power/Boost.aidl @@ -0,0 +1,55 @@ +/* + * 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.power; + +@VintfStability +@Backing(type="int") +enum Boost { + /** + * This boost is set when user interacting with the device, for example, + * touchscreen events are incoming. CPU and GPU load may be expected soon, + * and it may be appropriate to raise speeds of CPU, memory bus etc. + * Note that this is different from INTERACTIVE mode, which only indicates + * that such interaction *may* occur, not that it is actively occurring. + */ + INTERACTION, + + /** + * Below hints are currently not sent in Android framework but OEM might choose to + * implement for power/perf optimizations. + */ + + /** + * This boost indicates that the device is interacting with ML accelerator. + */ + ML_ACC, + + /** + * This boost indicates that the device is setting up audio stream. + */ + AUDIO_LAUNCH, + + /** + * This boost indicates that camera is being launched. + */ + CAMERA_LAUNCH, + + /** + * This boost indicates that camera shot is being taken. + */ + CAMERA_SHOT, +} diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl new file mode 100644 index 0000000000..9fb3fc0c48 --- /dev/null +++ b/power/aidl/android/hardware/power/IPower.aidl @@ -0,0 +1,72 @@ +/* + * 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.power; + +import android.hardware.power.Boost; +import android.hardware.power.Mode; + +@VintfStability +interface IPower { + /** + * setMode() is called to enable/disable specific hint mode, which + * may result in adjustment of power/performance parameters of the + * cpufreq governor and other controls on device side. + * + * A particular platform may choose to ignore any mode hint. + * + * @param type Mode which is to be enable/disable. + * @param enabled true to enable, false to disable the mode. + */ + oneway void setMode(in Mode type, in boolean enabled); + + /** + * isModeSupported() is called to query if the given mode hint is + * supported by vendor. + * + * @return true if the hint passed is supported on this platform. + * If false, setting the mode will have no effect. + * @param type Mode to be queried + */ + boolean isModeSupported(in Mode type); + + /** + * setBoost() indicates the device may need to boost some resources, as the + * the load is likely to increase before the kernel governors can react. + * Depending on the boost, it may be appropriate to raise the frequencies of + * CPU, GPU, memory subsystem, or stop CPU from going into deep sleep state. + * A particular platform may choose to ignore this hint. + * + * @param type Boost type which is to be set with a timeout. + * @param durationMs The expected duration of the user's interaction, if + * known, or 0 if the expected duration is unknown. + * a negative value indicates canceling previous boost. + * A given platform can choose to boost some time based on durationMs, + * and may also pick an appropriate timeout for 0 case. + */ + oneway void setBoost(in Boost type, in int durationMs); + + /** + * isBoostSupported() is called to query if the given boost hint is + * supported by vendor. When returns false, set the boost will have + * no effect on the platform. + * + * @return true if the hint passed is supported on this platform. + * If false, setting the boost will have no effect. + * @param type Boost to be queried + */ + boolean isBoostSupported(in Boost type); +} diff --git a/power/aidl/android/hardware/power/Mode.aidl b/power/aidl/android/hardware/power/Mode.aidl new file mode 100644 index 0000000000..9bb5b98d93 --- /dev/null +++ b/power/aidl/android/hardware/power/Mode.aidl @@ -0,0 +1,109 @@ +/* + * 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.power; + +@VintfStability +@Backing(type="int") +enum Mode { + /** + * This mode indicates that the device is to allow wake up when the + * screen is tapped twice. + */ + DOUBLE_TAP_TO_WAKE, + + /** + * This mode indidates Low power mode is activated or not. Low power + * mode is intended to save battery at the cost of performance. + */ + LOW_POWER, + + /** + * This mode indidates Sustained Performance mode is activated or not. + * Sustained performance mode is intended to provide a consistent level of + * performance for a prolonged amount of time. + */ + SUSTAINED_PERFORMANCE, + + /** + * This mode indidates VR Mode is activated or not. VR mode is intended + * to provide minimum guarantee for performance for the amount of time the + * device can sustain it. + */ + VR, + + /** + * This mode indicates that an application has been launched. + */ + LAUNCH, + + /** + * This mode indicates that the device is about to enter a period of + * expensive rendering. + */ + EXPENSIVE_RENDERING, + + /** + * This mode indicates that the device is about entering/leaving + * interactive state. (that is, the system is awake and ready for + * interaction, often with UI devices such as display and touchscreen + * enabled) or non-interactive state (the + * system appears asleep, display usually turned off). The + * non-interactive state may be entered after a period of + * inactivity in order to conserve battery power during + * such inactive periods. + * + * Typical actions are to turn on or off devices and adjust + * cpufreq parameters. This function may also call the + * appropriate interfaces to allow the kernel to suspend the + * system to low-power sleep state when entering non-interactive + * state, and to disallow low-power suspend when the system is in + * interactive state. When low-power suspend state is allowed, the + * kernel may suspend the system whenever no wakelocks are held. + */ + INTERACTIVE, + + + /** + * Below hints are currently not sent in Android framework but OEM might choose to + * implement for power/perf optimizations. + */ + + /** + * This mode indicates that low latency audio is active. + */ + AUDIO_STREAMING_LOW_LATENCY, + + /** + * This hint indicates that camera secure stream is being started. + */ + CAMERA_STREAMING_SECURE, + + /** + * This hint indicates that camera low resolution stream is being started. + */ + CAMERA_STREAMING_LOW, + + /** + * This hint indicates that camera mid resolution stream is being started. + */ + CAMERA_STREAMING_MID, + + /** + * This hint indicates that camera high resolution stream is being started. + */ + CAMERA_STREAMING_HIGH, +} diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp new file mode 100644 index 0000000000..07cd368a54 --- /dev/null +++ b/power/aidl/default/Android.bp @@ -0,0 +1,30 @@ +// 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_binary { + name: "android.hardware.power-service.example", + relative_install_path: "hw", + init_rc: ["power-default.rc"], + vintf_fragments: ["power-default.xml"], + vendor: true, + shared_libs: [ + "libbase", + "libbinder_ndk", + "android.hardware.power-ndk_platform", + ], + srcs: [ + "main.cpp", + "Power.cpp", + ], +} diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp new file mode 100644 index 0000000000..8610de35b8 --- /dev/null +++ b/power/aidl/default/Power.cpp @@ -0,0 +1,56 @@ +/* + * 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 "Power.h" + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace power { +namespace impl { +namespace example { + +ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) { + LOG(VERBOSE) << "Power setMode: " << static_cast(type) << " to: " << enabled; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) { + LOG(INFO) << "Power isModeSupported: " << static_cast(type); + *_aidl_return = false; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) { + LOG(VERBOSE) << "Power setBoost: " << static_cast(type) + << ", duration: " << durationMs; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) { + LOG(INFO) << "Power isBoostSupported: " << static_cast(type); + *_aidl_return = false; + return ndk::ScopedAStatus::ok(); +} + +} // namespace example +} // namespace impl +} // namespace power +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h new file mode 100644 index 0000000000..f7645aa527 --- /dev/null +++ b/power/aidl/default/Power.h @@ -0,0 +1,40 @@ +/* + * 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 + +namespace aidl { +namespace android { +namespace hardware { +namespace power { +namespace impl { +namespace example { + +class Power : public BnPower { + ndk::ScopedAStatus setMode(Mode type, bool enabled) override; + ndk::ScopedAStatus isModeSupported(Mode type, bool* _aidl_return) override; + ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override; + ndk::ScopedAStatus isBoostSupported(Boost type, bool* _aidl_return) override; +}; + +} // namespace example +} // namespace impl +} // namespace power +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/power/aidl/default/main.cpp b/power/aidl/default/main.cpp new file mode 100644 index 0000000000..964bd96506 --- /dev/null +++ b/power/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 "Power.h" + +#include +#include +#include + +using aidl::android::hardware::power::impl::example::Power; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr vib = ndk::SharedRefBase::make(); + + const std::string instance = std::string() + Power::descriptor + "/default"; + binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} diff --git a/power/aidl/default/power-default.rc b/power/aidl/default/power-default.rc new file mode 100644 index 0000000000..9efbc850c3 --- /dev/null +++ b/power/aidl/default/power-default.rc @@ -0,0 +1,4 @@ +service vendor.power-default /vendor/bin/hw/android.hardware.power-service.example + class hal + user nobody + group system diff --git a/power/aidl/default/power-default.xml b/power/aidl/default/power-default.xml new file mode 100644 index 0000000000..caf6ea2d5d --- /dev/null +++ b/power/aidl/default/power-default.xml @@ -0,0 +1,6 @@ + + + android.hardware.power + IPower/default + + diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp new file mode 100644 index 0000000000..7726fd8a73 --- /dev/null +++ b/power/aidl/vts/Android.bp @@ -0,0 +1,31 @@ +// 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: "VtsHalPowerTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalPowerTargetTest.cpp"], + shared_libs: [ + "libbinder", + ], + static_libs: [ + "android.hardware.power-cpp", + ], + test_suites: [ + "vts-core", + ], +} diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp new file mode 100644 index 0000000000..c0e0858d58 --- /dev/null +++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp @@ -0,0 +1,120 @@ +/* + * 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 +#include + +#include +#include +#include +#include +#include + +#include + +using android::ProcessState; +using android::sp; +using android::String16; +using android::binder::Status; +using android::hardware::power::Boost; +using android::hardware::power::IPower; +using android::hardware::power::Mode; + +const std::vector kBoosts{android::enum_range().begin(), + android::enum_range().end()}; + +const std::vector kModes{android::enum_range().begin(), + android::enum_range().end()}; + +const std::vector kInvalidBoosts = { + static_cast(static_cast(kBoosts.front()) - 1), + static_cast(static_cast(kBoosts.back()) + 1), +}; + +const std::vector kInvalidModes = { + static_cast(static_cast(kModes.front()) - 1), + static_cast(static_cast(kModes.back()) + 1), +}; + +class PowerAidl : public testing::TestWithParam { + public: + virtual void SetUp() override { + power = android::waitForDeclaredService(String16(GetParam().c_str())); + ASSERT_NE(power, nullptr); + } + + sp power; +}; + +TEST_P(PowerAidl, setMode) { + for (const auto& mode : kModes) { + ASSERT_TRUE(power->setMode(mode, true).isOk()); + ASSERT_TRUE(power->setMode(mode, false).isOk()); + } + for (const auto& mode : kInvalidModes) { + ASSERT_TRUE(power->setMode(mode, true).isOk()); + ASSERT_TRUE(power->setMode(mode, false).isOk()); + } +} + +TEST_P(PowerAidl, isModeSupported) { + for (const auto& mode : kModes) { + bool supported; + ASSERT_TRUE(power->isModeSupported(mode, &supported).isOk()); + } + for (const auto& mode : kInvalidModes) { + bool supported; + ASSERT_TRUE(power->isModeSupported(mode, &supported).isOk()); + // Should return false for values outsides enum + ASSERT_FALSE(supported); + } +} + +TEST_P(PowerAidl, setBoost) { + for (const auto& boost : kBoosts) { + ASSERT_TRUE(power->setBoost(boost, 0).isOk()); + ASSERT_TRUE(power->setBoost(boost, 1000).isOk()); + ASSERT_TRUE(power->setBoost(boost, -1).isOk()); + } + for (const auto& boost : kInvalidBoosts) { + ASSERT_TRUE(power->setBoost(boost, 0).isOk()); + ASSERT_TRUE(power->setBoost(boost, 1000).isOk()); + ASSERT_TRUE(power->setBoost(boost, -1).isOk()); + } +} + +TEST_P(PowerAidl, isBoostSupported) { + for (const auto& boost : kBoosts) { + bool supported; + ASSERT_TRUE(power->isBoostSupported(boost, &supported).isOk()); + } + for (const auto& boost : kInvalidBoosts) { + bool supported; + ASSERT_TRUE(power->isBoostSupported(boost, &supported).isOk()); + // Should return false for values outsides enum + ASSERT_FALSE(supported); + } +} + +INSTANTIATE_TEST_SUITE_P(Power, PowerAidl, + testing::ValuesIn(android::getAidlHalInstanceNames(IPower::descriptor)), + android::PrintInstanceNameToString); + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ProcessState::self()->setThreadPoolMaxThreadCount(1); + ProcessState::self()->startThreadPool(); + return RUN_ALL_TESTS(); +}