Power: PowerHAL AIDL interface

Bug: 146453294
Test: build and run VtsHalPowerTargetTest pass
Change-Id: Id2a0194173325015933b0db72067f03a375566ee
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 2bd2c93..9e29ec7 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -331,9 +331,8 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="aidl" optional="true">
         <name>android.hardware.power</name>
-        <version>1.0-3</version>
         <interface>
             <name>IPower</name>
             <instance>default</instance>
diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp
new file mode 100644
index 0000000..2a6cf94
--- /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 0000000..162a36a
--- /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 0000000..9fb3fc0
--- /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 0000000..9bb5b98
--- /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 0000000..07cd368
--- /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 0000000..8610de3
--- /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 <android-base/logging.h>
+
+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<int32_t>(type) << " to: " << enabled;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) {
+    LOG(INFO) << "Power isModeSupported: " << static_cast<int32_t>(type);
+    *_aidl_return = false;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
+    LOG(VERBOSE) << "Power setBoost: " << static_cast<int32_t>(type)
+                 << ", duration: " << durationMs;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) {
+    LOG(INFO) << "Power isBoostSupported: " << static_cast<int32_t>(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 0000000..f7645aa
--- /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 <aidl/android/hardware/power/BnPower.h>
+
+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 0000000..964bd96
--- /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 <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::power::impl::example::Power;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<Power> vib = ndk::SharedRefBase::make<Power>();
+
+    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 0000000..9efbc85
--- /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 0000000..caf6ea2
--- /dev/null
+++ b/power/aidl/default/power-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.power</name>
+        <fqname>IPower/default</fqname>
+    </hal>
+</manifest>
diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp
new file mode 100644
index 0000000..7726fd8
--- /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 0000000..c0e0858
--- /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 <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <android/hardware/power/Boost.h>
+#include <android/hardware/power/IPower.h>
+#include <android/hardware/power/Mode.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include <future>
+
+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<Boost> kBoosts{android::enum_range<Boost>().begin(),
+                                 android::enum_range<Boost>().end()};
+
+const std::vector<Mode> kModes{android::enum_range<Mode>().begin(),
+                               android::enum_range<Mode>().end()};
+
+const std::vector<Boost> kInvalidBoosts = {
+        static_cast<Boost>(static_cast<int32_t>(kBoosts.front()) - 1),
+        static_cast<Boost>(static_cast<int32_t>(kBoosts.back()) + 1),
+};
+
+const std::vector<Mode> kInvalidModes = {
+        static_cast<Mode>(static_cast<int32_t>(kModes.front()) - 1),
+        static_cast<Mode>(static_cast<int32_t>(kModes.back()) + 1),
+};
+
+class PowerAidl : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        power = android::waitForDeclaredService<IPower>(String16(GetParam().c_str()));
+        ASSERT_NE(power, nullptr);
+    }
+
+    sp<IPower> 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();
+}