ADPF: IPower: add aidl interfaces

Test: Manual test, run bouncy ball
Test: atest VtsHalPowerTargetTest
Bug: 163794808
Change-Id: I295cf03b33ae8cb68826641c08a877a2a3e3a461
Signed-off-by: Wei Wang <wvw@google.com>
diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp
index 054fea5..dbd18fd 100644
--- a/power/aidl/Android.bp
+++ b/power/aidl/Android.bp
@@ -29,6 +29,9 @@
     ],
     stability: "vintf",
     backend: {
+        cpp: {
+            enabled: true,
+        },
         java: {
             platform_apis: true,
         },
@@ -38,5 +41,7 @@
             },
         },
     },
-    versions: ["1"],
+    versions: [
+        "1",
+    ],
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Boost.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Boost.aidl
index aced215..c792d4e 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Boost.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Boost.aidl
@@ -1,14 +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.
+ */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// 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 <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// 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
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 8a06623..ae03313 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
@@ -1,14 +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.
+ */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// 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 <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// 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
@@ -22,4 +38,6 @@
   boolean isModeSupported(in android.hardware.power.Mode type);
   oneway void setBoost(in android.hardware.power.Boost type, in int durationMs);
   boolean isBoostSupported(in android.hardware.power.Boost type);
+  android.hardware.power.IPowerHintSession createHintSession(in int tgid, in int uid, in int[] threadIds, in long durationNanos);
+  long getHintSessionPreferredRate();
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
new file mode 100644
index 0000000..1d3ecb7
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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 <name>-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
+interface IPowerHintSession {
+  oneway void updateTargetWorkDuration(long targetDurationNanos);
+  oneway void reportActualWorkDuration(in android.hardware.power.WorkDuration[] durations);
+  oneway void pause();
+  oneway void resume();
+  oneway void close();
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
index f7c2552..8920c01 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
@@ -1,14 +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.
+ */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// 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 <name>-update-api`.
 //
-// You must not make a backward incompatible changes to the AIDL files built
+// 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
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl
new file mode 100644
index 0000000..e86cd40
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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 <name>-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 WorkDuration {
+  long timeStampNanos;
+  long durationNanos;
+}
diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl
index 2c4bd86..ee8e5a3 100644
--- a/power/aidl/android/hardware/power/IPower.aidl
+++ b/power/aidl/android/hardware/power/IPower.aidl
@@ -17,6 +17,7 @@
 package android.hardware.power;
 
 import android.hardware.power.Boost;
+import android.hardware.power.IPowerHintSession;
 import android.hardware.power.Mode;
 
 @VintfStability
@@ -69,4 +70,37 @@
      * @param type Boost to be queried
      */
     boolean isBoostSupported(in Boost type);
+
+    /**
+     * A Session represents a group of threads with an inter-related workload such that hints for
+     * their performance should be considered as a unit. The threads in a given session should be
+     * long-life and not created or destroyed dynamically.
+     *
+     * Each session is expected to have a periodic workload with a target duration for each
+     * cycle. The cycle duration is likely greater than the target work duration to allow other
+     * parts of the pipeline to run within the available budget. For example, a renderer thread may
+     * work at 60hz in order to produce frames at the display's frame but have a target work
+     * duration of only 6ms.
+     *
+     * Creates a session for the given set of threads and sets their initial target work
+     * duration.
+     *
+     * @return  the new session if it is supported on this device, otherwise return with
+     *          EX_UNSUPPORTED_OPERATION error if hint session is not supported on this device.
+     * @param   tgid The TGID to be associated with this session.
+     * @param   uid The UID to be associated with this session.
+     * @param   threadIds The list of threads to be associated with this session.
+     * @param   durationNanos The desired duration in nanoseconds for this session.
+     */
+    IPowerHintSession createHintSession(
+            in int tgid, in int uid, in int[] threadIds, in long durationNanos);
+
+    /**
+     * Get preferred update rate (interval) information for this device. Framework must communicate
+     * this rate to Apps, and also ensure the session hint sent no faster than the update rate.
+     *
+     * @return the preferred update rate in nanoseconds supported by device software. Return with
+     *         EX_UNSUPPORTED_OPERATION if hint session is not supported.
+     */
+    long getHintSessionPreferredRate();
 }
diff --git a/power/aidl/android/hardware/power/IPowerHintSession.aidl b/power/aidl/android/hardware/power/IPowerHintSession.aidl
new file mode 100644
index 0000000..9a85bee
--- /dev/null
+++ b/power/aidl/android/hardware/power/IPowerHintSession.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 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.WorkDuration;
+
+@VintfStability
+oneway interface IPowerHintSession {
+    /**
+     * Updates the desired duration of a previously-created thread group.
+     *
+     * See {@link IPowerHintSession#createHintSession} for more information on how
+     * the desired duration will be used.
+     *
+     * @param targetDurationNanos the new desired duration in nanoseconds
+     */
+    void updateTargetWorkDuration(long targetDurationNanos);
+
+    /**
+     * Reports the actual duration of a thread group.
+     *
+     * The system will attempt to adjust the core placement of the threads within
+     * the thread group and/or the frequency of the core on which they are run to bring
+     * the actual duration close to the target duration.
+     *
+     * @param actualDurationMicros how long the thread group took to complete its
+     *        last task in nanoseconds
+     */
+    void reportActualWorkDuration(in WorkDuration[] durations);
+
+    /**
+     * Pause the session when the application is not in foreground and above
+     */
+    void pause();
+
+    /**
+     * Resume the session when the application is not in foreground and above
+     */
+    void resume();
+
+    /**
+     * Close the session to release resources
+     */
+    void close();
+}
diff --git a/power/aidl/android/hardware/power/WorkDuration.aidl b/power/aidl/android/hardware/power/WorkDuration.aidl
new file mode 100644
index 0000000..a06a058
--- /dev/null
+++ b/power/aidl/android/hardware/power/WorkDuration.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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
+parcelable WorkDuration {
+    /**
+     * Time stamp in nanoseconds based on CLOCK_MONOTONIC when the duration
+     * sample was measured.
+     */
+    long timeStampNanos;
+    /**
+     * Work duration in nanoseconds.
+     */
+    long durationNanos;
+}
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index 5aa6893..c0ba9a0 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -30,7 +30,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.power-V1-ndk_platform",
+        "android.hardware.power-V2-ndk_platform",
     ],
     srcs: [
         "main.cpp",
diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp
index 8610de3..7f08f44 100644
--- a/power/aidl/default/Power.cpp
+++ b/power/aidl/default/Power.cpp
@@ -25,6 +25,10 @@
 namespace impl {
 namespace example {
 
+const std::vector<Boost> BOOST_RANGE{ndk::enum_range<Boost>().begin(),
+                                     ndk::enum_range<Boost>().end()};
+const std::vector<Mode> MODE_RANGE{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
+
 ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
     LOG(VERBOSE) << "Power setMode: " << static_cast<int32_t>(type) << " to: " << enabled;
     return ndk::ScopedAStatus::ok();
@@ -32,7 +36,7 @@
 
 ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) {
     LOG(INFO) << "Power isModeSupported: " << static_cast<int32_t>(type);
-    *_aidl_return = false;
+    *_aidl_return = type >= MODE_RANGE.front() && type <= MODE_RANGE.back();
     return ndk::ScopedAStatus::ok();
 }
 
@@ -44,10 +48,21 @@
 
 ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) {
     LOG(INFO) << "Power isBoostSupported: " << static_cast<int32_t>(type);
-    *_aidl_return = false;
+    *_aidl_return = type >= BOOST_RANGE.front() && type <= BOOST_RANGE.back();
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector<int32_t>&, int64_t,
+                                            std::shared_ptr<IPowerHintSession>* _aidl_return) {
+    *_aidl_return = nullptr;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) {
+    *outNanoseconds = -1;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
 }  // namespace example
 }  // namespace impl
 }  // namespace power
diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h
index f7645aa..ef6439d 100644
--- a/power/aidl/default/Power.h
+++ b/power/aidl/default/Power.h
@@ -30,6 +30,11 @@
     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;
+    ndk::ScopedAStatus createHintSession(int32_t tgid, int32_t uid,
+                                         const std::vector<int32_t>& threadIds,
+                                         int64_t durationNanos,
+                                         std::shared_ptr<IPowerHintSession>* _aidl_return) override;
+    ndk::ScopedAStatus getHintSessionPreferredRate(int64_t* outNanoseconds) override;
 };
 
 }  // namespace example
diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp
index 1051b03..3036b82 100644
--- a/power/aidl/vts/Android.bp
+++ b/power/aidl/vts/Android.bp
@@ -29,10 +29,10 @@
     ],
     srcs: ["VtsHalPowerTargetTest.cpp"],
     shared_libs: [
-        "libbinder",
+        "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.power-V1-cpp",
+        "android.hardware.power-V2-ndk_platform",
     ],
     test_suites: [
         "vts",
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index d036c90..5bb088a 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -16,29 +16,28 @@
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 
+#include <aidl/android/hardware/power/BnPower.h>
+#include <aidl/android/hardware/power/BnPowerHintSession.h>
 #include <android-base/properties.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 <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
 
-#include <future>
+#include <unistd.h>
 
-using android::ProcessState;
-using android::sp;
-using android::String16;
-using android::base::GetUintProperty;
-using android::binder::Status;
+namespace aidl::android::hardware::power {
+namespace {
+
+using ::android::base::GetUintProperty;
 using android::hardware::power::Boost;
 using android::hardware::power::IPower;
+using android::hardware::power::IPowerHintSession;
 using android::hardware::power::Mode;
+using android::hardware::power::WorkDuration;
 
-const std::vector<Boost> kBoosts{android::enum_range<Boost>().begin(),
-                                 android::enum_range<Boost>().end()};
+const std::vector<Boost> kBoosts{ndk::enum_range<Boost>().begin(), ndk::enum_range<Boost>().end()};
 
-const std::vector<Mode> kModes{android::enum_range<Mode>().begin(),
-                               android::enum_range<Mode>().end()};
+const std::vector<Mode> kModes{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
 
 const std::vector<Boost> kInvalidBoosts = {
         static_cast<Boost>(static_cast<int32_t>(kBoosts.front()) - 1),
@@ -50,14 +49,48 @@
         static_cast<Mode>(static_cast<int32_t>(kModes.back()) + 1),
 };
 
+class DurationWrapper : public WorkDuration {
+  public:
+    DurationWrapper(int64_t dur, int64_t time) {
+        durationNanos = dur;
+        timeStampNanos = time;
+    }
+};
+
+const std::vector<int32_t> kSelfTids = {
+        gettid(),
+};
+
+const std::vector<int32_t> kEmptyTids = {};
+
+const std::vector<WorkDuration> kNoDurations = {};
+
+const std::vector<WorkDuration> kDurationsWithZero = {
+        DurationWrapper(1000L, 1L),
+        DurationWrapper(0L, 2L),
+};
+
+const std::vector<WorkDuration> kDurationsWithNegative = {
+        DurationWrapper(1000L, 1L),
+        DurationWrapper(-1000L, 2L),
+};
+
+const std::vector<WorkDuration> kDurations = {
+        DurationWrapper(1L, 1L),
+        DurationWrapper(1000L, 2L),
+        DurationWrapper(1000000L, 3L),
+        DurationWrapper(1000000000L, 4L),
+};
+
 class PowerAidl : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
-        power = android::waitForDeclaredService<IPower>(String16(GetParam().c_str()));
-        ASSERT_NE(power, nullptr);
+        AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+        ASSERT_NE(binder, nullptr);
+        power = IPower::fromBinder(ndk::SpAIBinder(binder));
     }
 
-    sp<IPower> power;
+    std::shared_ptr<IPower> power;
 };
 
 TEST_P(PowerAidl, setMode) {
@@ -110,6 +143,56 @@
     }
 }
 
+TEST_P(PowerAidl, getHintSessionPreferredRate) {
+    int64_t rate = -1;
+    auto status = power->getHintSessionPreferredRate(&rate);
+    if (!status.isOk()) {
+        ASSERT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
+        return;
+    }
+
+    // At least 1ms rate limit from HAL
+    ASSERT_GE(rate, 1000000);
+}
+
+TEST_P(PowerAidl, createAndCloseHintSession) {
+    std::shared_ptr<IPowerHintSession> session;
+    auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session);
+    if (!status.isOk()) {
+        ASSERT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
+        return;
+    }
+    ASSERT_NE(nullptr, session);
+    ASSERT_TRUE(session->pause().isOk());
+    ASSERT_TRUE(session->resume().isOk());
+    // Test normal destroy operation
+    ASSERT_TRUE(session->close().isOk());
+    session.reset();
+}
+TEST_P(PowerAidl, createHintSessionFailed) {
+    std::shared_ptr<IPowerHintSession> session;
+    auto status = power->createHintSession(getpid(), getuid(), kEmptyTids, 16666666L, &session);
+    ASSERT_FALSE(status.isOk());
+    if (EX_UNSUPPORTED_OPERATION == status.getExceptionCode()) {
+        return;
+    }
+    // Test with empty tid list
+    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+}
+
+TEST_P(PowerAidl, updateAndReportDurations) {
+    std::shared_ptr<IPowerHintSession> session;
+    auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session);
+    if (!status.isOk()) {
+        ASSERT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
+        return;
+    }
+    ASSERT_NE(nullptr, session);
+
+    ASSERT_TRUE(session->updateTargetWorkDuration(16666667LL).isOk());
+    ASSERT_TRUE(session->reportActualWorkDuration(kDurations).isOk());
+}
+
 // FIXED_PERFORMANCE mode is required for all devices which ship on Android 11
 // or later
 TEST_P(PowerAidl, hasFixedPerformance) {
@@ -128,12 +211,16 @@
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerAidl);
 INSTANTIATE_TEST_SUITE_P(Power, PowerAidl,
-                         testing::ValuesIn(android::getAidlHalInstanceNames(IPower::descriptor)),
-                         android::PrintInstanceNameToString);
+                         testing::ValuesIn(::android::getAidlHalInstanceNames(IPower::descriptor)),
+                         ::android::PrintInstanceNameToString);
+
+}  // namespace
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
-    ProcessState::self()->setThreadPoolMaxThreadCount(1);
-    ProcessState::self()->startThreadPool();
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
     return RUN_ALL_TESTS();
 }
+
+}  // namespace aidl::android::hardware::power