diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl index 8acdaf2014..8d8fb88e1d 100644 --- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl +++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl @@ -43,4 +43,5 @@ interface IPower { android.hardware.power.IPowerHintSession createHintSessionWithConfig(in int tgid, in int uid, in int[] threadIds, in long durationNanos, in android.hardware.power.SessionTag tag, out android.hardware.power.SessionConfig config); android.hardware.power.ChannelConfig getSessionChannel(in int tgid, in int uid); oneway void closeSessionChannel(in int tgid, in int uid); + android.hardware.power.SupportInfo getSupportInfo(); } diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl new file mode 100644 index 0000000000..85da2fcc74 --- /dev/null +++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.power; +@VintfStability +parcelable SupportInfo { + boolean usesSessions; + long boosts; + long modes; + long sessionHints; + long sessionModes; + long sessionTags; +} diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl index e25714fda5..2f1564831b 100644 --- a/power/aidl/android/hardware/power/IPower.aidl +++ b/power/aidl/android/hardware/power/IPower.aidl @@ -22,6 +22,7 @@ import android.hardware.power.IPowerHintSession; import android.hardware.power.Mode; import android.hardware.power.SessionConfig; import android.hardware.power.SessionTag; +import android.hardware.power.SupportInfo; @VintfStability interface IPower { @@ -144,4 +145,14 @@ interface IPower { * @param uid The UID to be associated with this channel. */ oneway void closeSessionChannel(in int tgid, in int uid); + + /** + * Called to get detailed information on the support status of various PowerHAL + * features, such as hint sessions and specific boosts. + * + * @return a SupportInfo giving detailed support information, or + * EX_UNSUPPORTED_OPERATION if detailed support checking is itself + * not supported. + */ + SupportInfo getSupportInfo(); } diff --git a/power/aidl/android/hardware/power/SupportInfo.aidl b/power/aidl/android/hardware/power/SupportInfo.aidl new file mode 100644 index 0000000000..46bcdd3d95 --- /dev/null +++ b/power/aidl/android/hardware/power/SupportInfo.aidl @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2024 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; +import android.hardware.power.SessionHint; +import android.hardware.power.SessionMode; + +/** + * Tells clients the status of various PowerHAL features in a single call. + * SupportInfo consists of several bitsets, where each bit from the left + * corresponds to the support status of that same value of that enum index. + * + * For "Boost", having the first bit set would mean "INTERACTION" + * boost is supported, having the second bit set would mean + * "DISPLAY_UPDATE_IMMINENT" is supported, and so on. The expectation + * is that a client should be able to index the bitset like + * "(supportInfo.boosts >> Boost::AUDIO_LAUNCH) % 2" and it should return + * the support value of Boost::AUDIO_LAUNCH. This pattern is the same for + * all four support bitsets. + */ +@VintfStability +parcelable SupportInfo { + /** + * Boolean representing whether hint sessions are supported on this device + */ + boolean usesSessions; + + /** + * The set of "Boost" enum values that are supported by this device + * Each bit should correspond to a value of the "Boost.aidl" enum + */ + long boosts; + + /** + * The set of "Mode" enum values that are supported by this device + * Each bit should correspond to a value of the "Mode.aidl" enum + */ + long modes; + + /** + * The set of "SessionHint" enum values that are supported by this device + * Each bit should correspond to a value of the "SessionHint.aidl" enum + */ + long sessionHints; + + /** + * The set of "SessionMode" enum values that are supported by this device + * Each bit should correspond to a value of the "SessionMode.aidl" enum + */ + long sessionModes; + + /** + * The set of "SessionTag" enum values that are supported by this device + * Each bit should correspond to a value of the "SessionTag.aidl" enum + */ + long sessionTags; +} diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp index 64294e5229..36d0055324 100644 --- a/power/aidl/default/Power.cpp +++ b/power/aidl/default/Power.cpp @@ -41,6 +41,11 @@ const std::vector BOOST_RANGE{ndk::enum_range().begin(), ndk::enum_range().end()}; const std::vector MODE_RANGE{ndk::enum_range().begin(), ndk::enum_range().end()}; +template +constexpr size_t enum_size() { + return static_cast(*(ndk::enum_range().end() - 1)) + 1; +} + ScopedAStatus Power::setMode(Mode type, bool enabled) { LOG(VERBOSE) << "Power setMode: " << static_cast(type) << " to: " << enabled; return ScopedAStatus::ok(); @@ -105,11 +110,30 @@ ndk::ScopedAStatus Power::closeSessionChannel(int32_t, int32_t) { return ndk::ScopedAStatus::ok(); } -ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) { +ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) { *outNanoseconds = std::chrono::nanoseconds(1ms).count(); return ScopedAStatus::ok(); } +template +int64_t bitsForEnum() { + return static_cast(std::bitset()>().set().to_ullong()); +} + +ndk::ScopedAStatus Power::getSupportInfo(SupportInfo* _aidl_return) { + static SupportInfo supportInfo = { + .usesSessions = false, + .modes = bitsForEnum(), + .boosts = bitsForEnum(), + .sessionHints = 0, + .sessionModes = 0, + .sessionTags = 0, + }; + // Copy the support object into the binder + *_aidl_return = supportInfo; + return ndk::ScopedAStatus::ok(); +} + } // namespace example } // namespace impl } // namespace power diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h index baabaa7271..ef524e1996 100644 --- a/power/aidl/default/Power.h +++ b/power/aidl/default/Power.h @@ -44,6 +44,7 @@ class Power : public BnPower { ndk::ScopedAStatus getSessionChannel(int32_t tgid, int32_t uid, ChannelConfig* _aidl_return) override; ndk::ScopedAStatus closeSessionChannel(int32_t tgid, int32_t uid) override; + ndk::ScopedAStatus getSupportInfo(SupportInfo* _aidl_return) override; private: std::vector> mPowerHintSessions; diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp index 272674f194..9684c38fcc 100644 --- a/power/aidl/vts/VtsHalPowerTargetTest.cpp +++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp @@ -45,6 +45,7 @@ using android::hardware::power::IPowerHintSession; using android::hardware::power::Mode; using android::hardware::power::SessionHint; using android::hardware::power::SessionMode; +using android::hardware::power::SupportInfo; using android::hardware::power::WorkDuration; using ChannelMessageContents = ChannelMessage::ChannelMessageContents; using ModeSetter = ChannelMessage::ChannelMessageContents::SessionModeSetter; @@ -83,6 +84,16 @@ const std::vector kInvalidSessionModes = { static_cast(static_cast(kSessionModes.back()) + 1), }; +template +constexpr size_t enum_size() { + return static_cast(*(ndk::enum_range().end() - 1)) + 1; +} + +template +bool supportFromBitset(int64_t& supportInt, E type) { + return (supportInt >> static_cast(type)) % 2; +} + class DurationWrapper : public WorkDuration { public: DurationWrapper(int64_t dur, int64_t time) { @@ -288,6 +299,21 @@ TEST_P(PowerAidl, hasFixedPerformance) { ASSERT_TRUE(supported); } +TEST_P(PowerAidl, hasSupportInfo) { + SupportInfo config; + ASSERT_TRUE(power->getSupportInfo(&config).isOk()); + for (Mode mode : kModes) { + bool supported; + power->isModeSupported(mode, &supported); + ASSERT_EQ(supported, supportFromBitset(config.modes, mode)); + } + for (Boost boost : kBoosts) { + bool supported; + power->isBoostSupported(boost, &supported); + ASSERT_EQ(supported, supportFromBitset(config.boosts, boost)); + } +} + TEST_P(HintSessionAidl, createAndCloseHintSession) { if (!mSessionSupport) { GTEST_SKIP() << "DEVICE not support Hint Session.";