Update HintManager to use NDK backend

- Update HintManager and its aidl types to use NDK backend
- Switch HintManager to using PowerHAL's WorkDuration
- Update SDK WorkDuration.java to no longer be parcelable,
    since it isn't being sent over binders anymore.
- Remove duplicate WorkDuration in powermanager in favor of PowerHAL's

Bug: 315894228
Test: atest HintManagerServiceTest
Test: atest PerformanceHintNativeTestCases
Test: atest PerformanceHintManagerTest
Change-Id: Ibc5a3aa96e73a225fce980811694ee02bdabb963
diff --git a/Android.bp b/Android.bp
index 8d7ab98..057b1d6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -355,8 +355,11 @@
             "packages/modules/Media/apex/aidl/stable",
             "hardware/interfaces/biometrics/common/aidl",
             "hardware/interfaces/biometrics/fingerprint/aidl",
+            "hardware/interfaces/common/aidl",
+            "hardware/interfaces/common/fmq/aidl",
             "hardware/interfaces/graphics/common/aidl",
             "hardware/interfaces/keymaster/aidl",
+            "hardware/interfaces/power/aidl",
             "system/hardware/interfaces/media/aidl",
         ],
     },
diff --git a/api/Android.bp b/api/Android.bp
index 093ee4b..010a2a5 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -342,8 +342,11 @@
             "packages/modules/Media/apex/aidl/stable",
             "hardware/interfaces/biometrics/common/aidl",
             "hardware/interfaces/biometrics/fingerprint/aidl",
+            "hardware/interfaces/common/aidl",
+            "hardware/interfaces/common/fmq/aidl",
             "hardware/interfaces/graphics/common/aidl",
             "hardware/interfaces/keymaster/aidl",
+            "hardware/interfaces/power/aidl",
             "system/hardware/interfaces/media/aidl",
         ],
     },
diff --git a/core/api/current.txt b/core/api/current.txt
index cd9c3ad..082a702a 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -34212,9 +34212,8 @@
     method @RequiresPermission(android.Manifest.permission.VIBRATE) public final void vibrate(@NonNull android.os.CombinedVibration, @Nullable android.os.VibrationAttributes);
   }
 
-  @FlaggedApi("android.os.adpf_gpu_report_actual_work_duration") public final class WorkDuration implements android.os.Parcelable {
+  @FlaggedApi("android.os.adpf_gpu_report_actual_work_duration") public final class WorkDuration {
     ctor public WorkDuration();
-    method public int describeContents();
     method public long getActualCpuDurationNanos();
     method public long getActualGpuDurationNanos();
     method public long getActualTotalDurationNanos();
@@ -34223,8 +34222,6 @@
     method public void setActualGpuDurationNanos(long);
     method public void setActualTotalDurationNanos(long);
     method public void setWorkPeriodStartTimestampNanos(long);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.os.WorkDuration> CREATOR;
   }
 
   public class WorkSource implements android.os.Parcelable {
diff --git a/core/java/Android.bp b/core/java/Android.bp
index ab1c9a4..2d34fd1 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -135,8 +135,6 @@
     srcs: [
         "android/os/Temperature.aidl",
         "android/os/CoolingDevice.aidl",
-        "android/os/IHintManager.aidl",
-        "android/os/IHintSession.aidl",
         "android/os/IThermalEventListener.aidl",
         "android/os/IThermalStatusListener.aidl",
         "android/os/IThermalService.aidl",
@@ -145,6 +143,30 @@
     ],
 }
 
+aidl_interface {
+    name: "android.os.hintmanager_aidl",
+    srcs: [
+        "android/os/IHintManager.aidl",
+        "android/os/IHintSession.aidl",
+    ],
+    unstable: true,
+    backend: {
+        java: {
+            sdk_version: "module_current",
+            enabled: true,
+        },
+        cpp: {
+            enabled: false,
+        },
+        ndk: {
+            enabled: true,
+        },
+    },
+    imports: [
+        "android.hardware.power-V5",
+    ],
+}
+
 aidl_library {
     name: "ILogcatManagerService_aidl",
     srcs: ["android/os/logcat/ILogcatManagerService.aidl"],
diff --git a/core/java/android/os/IHintSession.aidl b/core/java/android/os/IHintSession.aidl
index fe85da2..6fd4f3c 100644
--- a/core/java/android/os/IHintSession.aidl
+++ b/core/java/android/os/IHintSession.aidl
@@ -17,7 +17,7 @@
 
 package android.os;
 
-import android.os.WorkDuration;
+import android.hardware.power.WorkDuration;
 
 /** {@hide} */
 oneway interface IHintSession {
diff --git a/core/java/android/os/WorkDuration.aidl b/core/java/android/os/WorkDuration.aidl
deleted file mode 100644
index 0f61204..0000000
--- a/core/java/android/os/WorkDuration.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2023 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.os;
-
-parcelable WorkDuration cpp_header "android/WorkDuration.h";
\ No newline at end of file
diff --git a/core/java/android/os/WorkDuration.java b/core/java/android/os/WorkDuration.java
index 5a54e90..3627502 100644
--- a/core/java/android/os/WorkDuration.java
+++ b/core/java/android/os/WorkDuration.java
@@ -17,7 +17,6 @@
 package android.os;
 
 import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
 
 import java.util.Objects;
 
@@ -29,24 +28,11 @@
  * All timings should be in {@link SystemClock#uptimeNanos()} and measured in wall time.
  */
 @FlaggedApi(Flags.FLAG_ADPF_GPU_REPORT_ACTUAL_WORK_DURATION)
-public final class WorkDuration implements Parcelable {
-    long mWorkPeriodStartTimestampNanos = 0;
+public final class WorkDuration {
     long mActualTotalDurationNanos = 0;
+    long mWorkPeriodStartTimestampNanos = 0;
     long mActualCpuDurationNanos = 0;
     long mActualGpuDurationNanos = 0;
-    long mTimestampNanos = 0;
-
-    public static final @NonNull Creator<WorkDuration> CREATOR = new Creator<>() {
-        @Override
-        public WorkDuration createFromParcel(Parcel in) {
-            return new WorkDuration(in);
-        }
-
-        @Override
-        public WorkDuration[] newArray(int size) {
-            return new WorkDuration[size];
-        }
-    };
 
     public WorkDuration() {}
 
@@ -58,34 +44,11 @@
     public WorkDuration(long workPeriodStartTimestampNanos,
                       long actualTotalDurationNanos,
                       long actualCpuDurationNanos,
-                      long actualGpuDurationNanos,
-                      long timestampNanos) {
-        mWorkPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
+                      long actualGpuDurationNanos) {
         mActualTotalDurationNanos = actualTotalDurationNanos;
+        mWorkPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
         mActualCpuDurationNanos = actualCpuDurationNanos;
         mActualGpuDurationNanos = actualGpuDurationNanos;
-        mTimestampNanos = timestampNanos;
-    }
-
-    WorkDuration(@NonNull Parcel in) {
-        mWorkPeriodStartTimestampNanos = in.readLong();
-        mActualTotalDurationNanos = in.readLong();
-        mActualCpuDurationNanos = in.readLong();
-        mActualGpuDurationNanos = in.readLong();
-        mTimestampNanos = in.readLong();
-    }
-
-    /**
-     * Sets the work period start timestamp in nanoseconds.
-     *
-     * All timings should be in {@link SystemClock#uptimeNanos()}.
-     */
-    public void setWorkPeriodStartTimestampNanos(long workPeriodStartTimestampNanos) {
-        if (workPeriodStartTimestampNanos <= 0) {
-            throw new IllegalArgumentException(
-                "the work period start timestamp should be greater than zero.");
-        }
-        mWorkPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
     }
 
     /**
@@ -102,6 +65,19 @@
     }
 
     /**
+     * Sets the work period start timestamp in nanoseconds.
+     *
+     * All timings should be in {@link SystemClock#uptimeNanos()}.
+     */
+    public void setWorkPeriodStartTimestampNanos(long workPeriodStartTimestampNanos) {
+        if (workPeriodStartTimestampNanos <= 0) {
+            throw new IllegalArgumentException(
+                "the work period start timestamp should be greater than zero.");
+        }
+        mWorkPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
+    }
+
+    /**
      * Sets the actual CPU duration in nanoseconds.
      *
      * All timings should be in {@link SystemClock#uptimeNanos()}.
@@ -128,15 +104,6 @@
     }
 
     /**
-     * Returns the work period start timestamp based in nanoseconds.
-     *
-     * All timings should be in {@link SystemClock#uptimeNanos()}.
-     */
-    public long getWorkPeriodStartTimestampNanos() {
-        return mWorkPeriodStartTimestampNanos;
-    }
-
-    /**
      * Returns the actual total duration in nanoseconds.
      *
      * All timings should be in {@link SystemClock#uptimeNanos()}.
@@ -146,6 +113,15 @@
     }
 
     /**
+     * Returns the work period start timestamp based in nanoseconds.
+     *
+     * All timings should be in {@link SystemClock#uptimeNanos()}.
+     */
+    public long getWorkPeriodStartTimestampNanos() {
+        return mWorkPeriodStartTimestampNanos;
+    }
+
+    /**
      * Returns the actual CPU duration in nanoseconds.
      *
      * All timings should be in {@link SystemClock#uptimeNanos()}.
@@ -163,27 +139,6 @@
         return mActualGpuDurationNanos;
     }
 
-    /**
-     * @hide
-     */
-    public long getTimestampNanos() {
-        return mTimestampNanos;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeLong(mWorkPeriodStartTimestampNanos);
-        dest.writeLong(mActualTotalDurationNanos);
-        dest.writeLong(mActualCpuDurationNanos);
-        dest.writeLong(mActualGpuDurationNanos);
-        dest.writeLong(mTimestampNanos);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
     @Override
     public boolean equals(Object obj) {
         if (obj == this) {
@@ -193,9 +148,8 @@
             return false;
         }
         WorkDuration workDuration = (WorkDuration) obj;
-        return workDuration.mTimestampNanos == this.mTimestampNanos
+        return workDuration.mActualTotalDurationNanos == this.mActualTotalDurationNanos
             && workDuration.mWorkPeriodStartTimestampNanos == this.mWorkPeriodStartTimestampNanos
-            && workDuration.mActualTotalDurationNanos == this.mActualTotalDurationNanos
             && workDuration.mActualCpuDurationNanos == this.mActualCpuDurationNanos
             && workDuration.mActualGpuDurationNanos == this.mActualGpuDurationNanos;
     }
@@ -203,6 +157,6 @@
     @Override
     public int hashCode() {
         return Objects.hash(mWorkPeriodStartTimestampNanos, mActualTotalDurationNanos,
-                            mActualCpuDurationNanos, mActualGpuDurationNanos, mTimestampNanos);
+                            mActualCpuDurationNanos, mActualGpuDurationNanos);
     }
 }
diff --git a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
index 2bd5631..93a5642 100644
--- a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
+++ b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
@@ -243,25 +243,25 @@
         assumeNotNull(s);
         s.updateTargetWorkDuration(16);
         assertThrows(IllegalArgumentException.class, () -> {
-            s.reportActualWorkDuration(new WorkDuration(-1, 12, 8, 6, 1));
+            s.reportActualWorkDuration(new WorkDuration(-1, 12, 8, 6));
         });
         assertThrows(IllegalArgumentException.class, () -> {
-            s.reportActualWorkDuration(new WorkDuration(0, 12, 8, 6, 1));
+            s.reportActualWorkDuration(new WorkDuration(0, 12, 8, 6));
         });
         assertThrows(IllegalArgumentException.class, () -> {
-            s.reportActualWorkDuration(new WorkDuration(1, -1, 8, 6, 1));
+            s.reportActualWorkDuration(new WorkDuration(1, -1, 8, 6));
         });
         assertThrows(IllegalArgumentException.class, () -> {
-            s.reportActualWorkDuration(new WorkDuration(1, 0, 8, 6, 1));
+            s.reportActualWorkDuration(new WorkDuration(1, 0, 8, 6));
         });
         assertThrows(IllegalArgumentException.class, () -> {
-            s.reportActualWorkDuration(new WorkDuration(1, 12, -1, 6, 1));
+            s.reportActualWorkDuration(new WorkDuration(1, 12, -1, 6));
         });
         assertThrows(IllegalArgumentException.class, () -> {
-            s.reportActualWorkDuration(new WorkDuration(1, 12, 0, 0, 1));
+            s.reportActualWorkDuration(new WorkDuration(1, 12, 0, 0));
         });
         assertThrows(IllegalArgumentException.class, () -> {
-            s.reportActualWorkDuration(new WorkDuration(1, 12, 8, -1, 1));
+            s.reportActualWorkDuration(new WorkDuration(1, 12, 8, -1));
         });
     }
 }
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 752ebdf..0cfb237 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -83,6 +83,7 @@
         "libinput",
         "libutils",
         "libbinder",
+        "libbinder_ndk",
         "libui",
         "libgui",
         "libharfbuzz_ng", // Only for including hb.h via minikin
@@ -100,6 +101,7 @@
         "android.hardware.configstore-utils",
         "android.os.flags-aconfig-cc",
         "libnativedisplay",
+        "libfmq",
     ],
 
     static_libs: [
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 279f9d6..8227bdb 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -18,15 +18,15 @@
 
 #include <aidl/android/hardware/power/SessionHint.h>
 #include <aidl/android/hardware/power/SessionMode.h>
+#include <aidl/android/hardware/power/SessionTag.h>
+#include <aidl/android/hardware/power/WorkDuration.h>
+#include <aidl/android/os/IHintManager.h>
+#include <aidl/android/os/IHintSession.h>
 #include <android-base/stringprintf.h>
-#include <android/WorkDuration.h>
-#include <android/os/IHintManager.h>
-#include <android/os/IHintSession.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
 #include <android/performance_hint.h>
 #include <android/trace.h>
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <binder/IServiceManager.h>
 #include <inttypes.h>
 #include <performance_hint_private.h>
 #include <utils/SystemClock.h>
@@ -37,22 +37,25 @@
 #include <vector>
 
 using namespace android;
-using namespace android::os;
+using namespace aidl::android::os;
 
 using namespace std::chrono_literals;
 
-using AidlSessionHint = aidl::android::hardware::power::SessionHint;
-using AidlSessionMode = aidl::android::hardware::power::SessionMode;
+using HalSessionHint = aidl::android::hardware::power::SessionHint;
+using HalSessionMode = aidl::android::hardware::power::SessionMode;
+using HalWorkDuration = aidl::android::hardware::power::WorkDuration;
+
 using android::base::StringPrintf;
 
 struct APerformanceHintSession;
 
 constexpr int64_t SEND_HINT_TIMEOUT = std::chrono::nanoseconds(100ms).count();
+struct AWorkDuration : public HalWorkDuration {};
 
 struct APerformanceHintManager {
 public:
     static APerformanceHintManager* getInstance();
-    APerformanceHintManager(sp<IHintManager> service, int64_t preferredRateNanos);
+    APerformanceHintManager(std::shared_ptr<IHintManager> service, int64_t preferredRateNanos);
     APerformanceHintManager() = delete;
     ~APerformanceHintManager() = default;
 
@@ -61,17 +64,28 @@
     int64_t getPreferredRateNanos() const;
 
 private:
-    static APerformanceHintManager* create(sp<IHintManager> iHintManager);
+    // Necessary to create an empty binder object
+    static void* tokenStubOnCreate(void*) {
+        return nullptr;
+    }
+    static void tokenStubOnDestroy(void*) {}
+    static binder_status_t tokenStubOnTransact(AIBinder*, transaction_code_t, const AParcel*,
+                                               AParcel*) {
+        return STATUS_OK;
+    }
 
-    sp<IHintManager> mHintManager;
-    const sp<IBinder> mToken = sp<BBinder>::make();
+    static APerformanceHintManager* create(std::shared_ptr<IHintManager> iHintManager);
+
+    std::shared_ptr<IHintManager> mHintManager;
+    ndk::SpAIBinder mToken;
     const int64_t mPreferredRateNanos;
 };
 
 struct APerformanceHintSession {
 public:
-    APerformanceHintSession(sp<IHintManager> hintManager, sp<IHintSession> session,
-                            int64_t preferredRateNanos, int64_t targetDurationNanos);
+    APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
+                            std::shared_ptr<IHintSession> session, int64_t preferredRateNanos,
+                            int64_t targetDurationNanos);
     APerformanceHintSession() = delete;
     ~APerformanceHintSession();
 
@@ -86,10 +100,10 @@
 private:
     friend struct APerformanceHintManager;
 
-    int reportActualWorkDurationInternal(WorkDuration* workDuration);
+    int reportActualWorkDurationInternal(AWorkDuration* workDuration);
 
-    sp<IHintManager> mHintManager;
-    sp<IHintSession> mHintSession;
+    std::shared_ptr<IHintManager> mHintManager;
+    std::shared_ptr<IHintSession> mHintSession;
     // HAL preferred update rate
     const int64_t mPreferredRateNanos;
     // Target duration for choosing update rate
@@ -101,7 +115,7 @@
     // Last hint reported from sendHint indexed by hint value
     std::vector<int64_t> mLastHintSentTimestamp;
     // Cached samples
-    std::vector<WorkDuration> mActualWorkDurations;
+    std::vector<HalWorkDuration> mActualWorkDurations;
     std::string mSessionName;
     static int32_t sIDCounter;
     // The most recent set of thread IDs
@@ -114,19 +128,24 @@
     void traceTargetDuration(int64_t targetDuration);
 };
 
-static IHintManager* gIHintManagerForTesting = nullptr;
+static std::shared_ptr<IHintManager>* gIHintManagerForTesting = nullptr;
 static APerformanceHintManager* gHintManagerForTesting = nullptr;
 int32_t APerformanceHintSession::sIDCounter = 0;
 
 // ===================================== APerformanceHintManager implementation
-APerformanceHintManager::APerformanceHintManager(sp<IHintManager> manager,
+APerformanceHintManager::APerformanceHintManager(std::shared_ptr<IHintManager> manager,
                                                  int64_t preferredRateNanos)
-      : mHintManager(std::move(manager)), mPreferredRateNanos(preferredRateNanos) {}
+      : mHintManager(std::move(manager)), mPreferredRateNanos(preferredRateNanos) {
+    static AIBinder_Class* tokenBinderClass =
+            AIBinder_Class_define("phm_token", tokenStubOnCreate, tokenStubOnDestroy,
+                                  tokenStubOnTransact);
+    mToken = ndk::SpAIBinder(AIBinder_new(tokenBinderClass, nullptr));
+}
 
 APerformanceHintManager* APerformanceHintManager::getInstance() {
     if (gHintManagerForTesting) return gHintManagerForTesting;
     if (gIHintManagerForTesting) {
-        APerformanceHintManager* manager = create(gIHintManagerForTesting);
+        APerformanceHintManager* manager = create(*gIHintManagerForTesting);
         gIHintManagerForTesting = nullptr;
         return manager;
     }
@@ -134,20 +153,19 @@
     return instance;
 }
 
-APerformanceHintManager* APerformanceHintManager::create(sp<IHintManager> manager) {
+APerformanceHintManager* APerformanceHintManager::create(std::shared_ptr<IHintManager> manager) {
     if (!manager) {
-        manager = interface_cast<IHintManager>(
-                defaultServiceManager()->checkService(String16("performance_hint")));
+        manager = IHintManager::fromBinder(
+                ndk::SpAIBinder(AServiceManager_waitForService("performance_hint")));
     }
     if (manager == nullptr) {
         ALOGE("%s: PerformanceHint service is not ready ", __FUNCTION__);
         return nullptr;
     }
     int64_t preferredRateNanos = -1L;
-    binder::Status ret = manager->getHintSessionPreferredRate(&preferredRateNanos);
+    ndk::ScopedAStatus ret = manager->getHintSessionPreferredRate(&preferredRateNanos);
     if (!ret.isOk()) {
-        ALOGE("%s: PerformanceHint cannot get preferred rate. %s", __FUNCTION__,
-              ret.exceptionMessage().c_str());
+        ALOGE("%s: PerformanceHint cannot get preferred rate. %s", __FUNCTION__, ret.getMessage());
         return nullptr;
     }
     if (preferredRateNanos <= 0) {
@@ -159,8 +177,8 @@
 APerformanceHintSession* APerformanceHintManager::createSession(
         const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos) {
     std::vector<int32_t> tids(threadIds, threadIds + size);
-    sp<IHintSession> session;
-    binder::Status ret =
+    std::shared_ptr<IHintSession> session;
+    ndk::ScopedAStatus ret =
             mHintManager->createHintSession(mToken, tids, initialTargetWorkDurationNanos, &session);
     if (!ret.isOk() || !session) {
         return nullptr;
@@ -179,8 +197,8 @@
 
 // ===================================== APerformanceHintSession implementation
 
-APerformanceHintSession::APerformanceHintSession(sp<IHintManager> hintManager,
-                                                 sp<IHintSession> session,
+APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
+                                                 std::shared_ptr<IHintSession> session,
                                                  int64_t preferredRateNanos,
                                                  int64_t targetDurationNanos)
       : mHintManager(hintManager),
@@ -189,17 +207,17 @@
         mTargetDurationNanos(targetDurationNanos),
         mFirstTargetMetTimestamp(0),
         mLastTargetMetTimestamp(0) {
-    const std::vector<AidlSessionHint> sessionHintRange{ndk::enum_range<AidlSessionHint>().begin(),
-                                                        ndk::enum_range<AidlSessionHint>().end()};
+    const std::vector<HalSessionHint> sessionHintRange{ndk::enum_range<HalSessionHint>().begin(),
+                                                       ndk::enum_range<HalSessionHint>().end()};
 
     mLastHintSentTimestamp = std::vector<int64_t>(sessionHintRange.size(), 0);
     mSessionName = android::base::StringPrintf("ADPF Session %" PRId32, ++sIDCounter);
 }
 
 APerformanceHintSession::~APerformanceHintSession() {
-    binder::Status ret = mHintSession->close();
+    ndk::ScopedAStatus ret = mHintSession->close();
     if (!ret.isOk()) {
-        ALOGE("%s: HintSession close failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
+        ALOGE("%s: HintSession close failed: %s", __FUNCTION__, ret.getMessage());
     }
 }
 
@@ -208,10 +226,10 @@
         ALOGE("%s: targetDurationNanos must be positive", __FUNCTION__);
         return EINVAL;
     }
-    binder::Status ret = mHintSession->updateTargetWorkDuration(targetDurationNanos);
+    ndk::ScopedAStatus ret = mHintSession->updateTargetWorkDuration(targetDurationNanos);
     if (!ret.isOk()) {
         ALOGE("%s: HintSession updateTargetWorkDuration failed: %s", __FUNCTION__,
-              ret.exceptionMessage().c_str());
+              ret.getMessage());
         return EPIPE;
     }
     mTargetDurationNanos = targetDurationNanos;
@@ -228,9 +246,12 @@
 }
 
 int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNanos) {
-    WorkDuration workDuration(0, actualDurationNanos, actualDurationNanos, 0);
+    HalWorkDuration workDuration{.durationNanos = actualDurationNanos,
+                                 .workPeriodStartTimestampNanos = 0,
+                                 .cpuDurationNanos = actualDurationNanos,
+                                 .gpuDurationNanos = 0};
 
-    return reportActualWorkDurationInternal(&workDuration);
+    return reportActualWorkDurationInternal(static_cast<AWorkDuration*>(&workDuration));
 }
 
 int APerformanceHintSession::sendHint(SessionHint hint) {
@@ -238,17 +259,17 @@
         ALOGE("%s: invalid session hint %d", __FUNCTION__, hint);
         return EINVAL;
     }
-    int64_t now = elapsedRealtimeNano();
+    int64_t now = uptimeNanos();
 
     // Limit sendHint to a pre-detemined rate for safety
     if (now < (mLastHintSentTimestamp[hint] + SEND_HINT_TIMEOUT)) {
         return 0;
     }
 
-    binder::Status ret = mHintSession->sendHint(hint);
+    ndk::ScopedAStatus ret = mHintSession->sendHint(hint);
 
     if (!ret.isOk()) {
-        ALOGE("%s: HintSession sendHint failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
+        ALOGE("%s: HintSession sendHint failed: %s", __FUNCTION__, ret.getMessage());
         return EPIPE;
     }
     mLastHintSentTimestamp[hint] = now;
@@ -261,12 +282,12 @@
         return EINVAL;
     }
     std::vector<int32_t> tids(threadIds, threadIds + size);
-    binder::Status ret = mHintManager->setHintSessionThreads(mHintSession, tids);
+    ndk::ScopedAStatus ret = mHintManager->setHintSessionThreads(mHintSession, tids);
     if (!ret.isOk()) {
-        ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
-        if (ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) {
+        ALOGE("%s: failed: %s", __FUNCTION__, ret.getMessage());
+        if (ret.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
             return EINVAL;
-        } else if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY) {
+        } else if (ret.getExceptionCode() == EX_SECURITY) {
             return EPERM;
         }
         return EPIPE;
@@ -279,9 +300,9 @@
 
 int APerformanceHintSession::getThreadIds(int32_t* const threadIds, size_t* size) {
     std::vector<int32_t> tids;
-    binder::Status ret = mHintManager->getHintSessionThreadIds(mHintSession, &tids);
+    ndk::ScopedAStatus ret = mHintManager->getHintSessionThreadIds(mHintSession, &tids);
     if (!ret.isOk()) {
-        ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
+        ALOGE("%s: failed: %s", __FUNCTION__, ret.getMessage());
         return EPIPE;
     }
 
@@ -301,28 +322,27 @@
 }
 
 int APerformanceHintSession::setPreferPowerEfficiency(bool enabled) {
-    binder::Status ret =
-            mHintSession->setMode(static_cast<int32_t>(AidlSessionMode::POWER_EFFICIENCY), enabled);
+    ndk::ScopedAStatus ret =
+            mHintSession->setMode(static_cast<int32_t>(HalSessionMode::POWER_EFFICIENCY), enabled);
 
     if (!ret.isOk()) {
         ALOGE("%s: HintSession setPreferPowerEfficiency failed: %s", __FUNCTION__,
-              ret.exceptionMessage().c_str());
+              ret.getMessage());
         return EPIPE;
     }
     tracePowerEfficient(enabled);
     return OK;
 }
 
-int APerformanceHintSession::reportActualWorkDuration(AWorkDuration* aWorkDuration) {
-    WorkDuration* workDuration = static_cast<WorkDuration*>(aWorkDuration);
+int APerformanceHintSession::reportActualWorkDuration(AWorkDuration* workDuration) {
     return reportActualWorkDurationInternal(workDuration);
 }
 
-int APerformanceHintSession::reportActualWorkDurationInternal(WorkDuration* workDuration) {
-    int64_t actualTotalDurationNanos = workDuration->actualTotalDurationNanos;
+int APerformanceHintSession::reportActualWorkDurationInternal(AWorkDuration* workDuration) {
+    int64_t actualTotalDurationNanos = workDuration->durationNanos;
     int64_t now = uptimeNanos();
-    workDuration->timestampNanos = now;
-    traceActualDuration(workDuration->actualTotalDurationNanos);
+    workDuration->timeStampNanos = now;
+    traceActualDuration(workDuration->durationNanos);
     mActualWorkDurations.push_back(std::move(*workDuration));
 
     if (actualTotalDurationNanos >= mTargetDurationNanos) {
@@ -346,14 +366,14 @@
         mLastTargetMetTimestamp = now;
     }
 
-    binder::Status ret = mHintSession->reportActualWorkDuration2(mActualWorkDurations);
+    ndk::ScopedAStatus ret = mHintSession->reportActualWorkDuration2(mActualWorkDurations);
     if (!ret.isOk()) {
         ALOGE("%s: HintSession reportActualWorkDuration failed: %s", __FUNCTION__,
-              ret.exceptionMessage().c_str());
+              ret.getMessage());
         mFirstTargetMetTimestamp = 0;
         mLastTargetMetTimestamp = 0;
         traceBatchSize(mActualWorkDurations.size());
-        return ret.exceptionCode() == binder::Status::EX_ILLEGAL_ARGUMENT ? EINVAL : EPIPE;
+        return ret.getExceptionCode() == EX_ILLEGAL_ARGUMENT ? EINVAL : EPIPE;
     }
     mActualWorkDurations.clear();
     traceBatchSize(0);
@@ -481,18 +501,16 @@
                                                AWorkDuration* workDurationPtr) {
     VALIDATE_PTR(session)
     VALIDATE_PTR(workDurationPtr)
-    WorkDuration& workDuration = *static_cast<WorkDuration*>(workDurationPtr);
-    VALIDATE_INT(workDuration.workPeriodStartTimestampNanos, > 0)
-    VALIDATE_INT(workDuration.actualTotalDurationNanos, > 0)
-    VALIDATE_INT(workDuration.actualCpuDurationNanos, >= 0)
-    VALIDATE_INT(workDuration.actualGpuDurationNanos, >= 0)
-    VALIDATE_INT(workDuration.actualGpuDurationNanos + workDuration.actualCpuDurationNanos, > 0)
+    VALIDATE_INT(workDurationPtr->durationNanos, > 0)
+    VALIDATE_INT(workDurationPtr->workPeriodStartTimestampNanos, > 0)
+    VALIDATE_INT(workDurationPtr->cpuDurationNanos, >= 0)
+    VALIDATE_INT(workDurationPtr->gpuDurationNanos, >= 0)
+    VALIDATE_INT(workDurationPtr->gpuDurationNanos + workDurationPtr->cpuDurationNanos, > 0)
     return session->reportActualWorkDuration(workDurationPtr);
 }
 
 AWorkDuration* AWorkDuration_create() {
-    WorkDuration* workDuration = new WorkDuration();
-    return static_cast<AWorkDuration*>(workDuration);
+    return new AWorkDuration();
 }
 
 void AWorkDuration_release(AWorkDuration* aWorkDuration) {
@@ -500,37 +518,36 @@
     delete aWorkDuration;
 }
 
-void AWorkDuration_setWorkPeriodStartTimestampNanos(AWorkDuration* aWorkDuration,
-                                                    int64_t workPeriodStartTimestampNanos) {
-    VALIDATE_PTR(aWorkDuration)
-    WARN_INT(workPeriodStartTimestampNanos, > 0)
-    static_cast<WorkDuration*>(aWorkDuration)->workPeriodStartTimestampNanos =
-            workPeriodStartTimestampNanos;
-}
-
 void AWorkDuration_setActualTotalDurationNanos(AWorkDuration* aWorkDuration,
                                                int64_t actualTotalDurationNanos) {
     VALIDATE_PTR(aWorkDuration)
     WARN_INT(actualTotalDurationNanos, > 0)
-    static_cast<WorkDuration*>(aWorkDuration)->actualTotalDurationNanos = actualTotalDurationNanos;
+    aWorkDuration->durationNanos = actualTotalDurationNanos;
+}
+
+void AWorkDuration_setWorkPeriodStartTimestampNanos(AWorkDuration* aWorkDuration,
+                                                    int64_t workPeriodStartTimestampNanos) {
+    VALIDATE_PTR(aWorkDuration)
+    WARN_INT(workPeriodStartTimestampNanos, > 0)
+    aWorkDuration->workPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
 }
 
 void AWorkDuration_setActualCpuDurationNanos(AWorkDuration* aWorkDuration,
                                              int64_t actualCpuDurationNanos) {
     VALIDATE_PTR(aWorkDuration)
     WARN_INT(actualCpuDurationNanos, >= 0)
-    static_cast<WorkDuration*>(aWorkDuration)->actualCpuDurationNanos = actualCpuDurationNanos;
+    aWorkDuration->cpuDurationNanos = actualCpuDurationNanos;
 }
 
 void AWorkDuration_setActualGpuDurationNanos(AWorkDuration* aWorkDuration,
                                              int64_t actualGpuDurationNanos) {
     VALIDATE_PTR(aWorkDuration)
     WARN_INT(actualGpuDurationNanos, >= 0)
-    static_cast<WorkDuration*>(aWorkDuration)->actualGpuDurationNanos = actualGpuDurationNanos;
+    aWorkDuration->gpuDurationNanos = actualGpuDurationNanos;
 }
 
 void APerformanceHint_setIHintManagerForTesting(void* iManager) {
     delete gHintManagerForTesting;
     gHintManagerForTesting = nullptr;
-    gIHintManagerForTesting = static_cast<IHintManager*>(iManager);
+    gIHintManagerForTesting = static_cast<std::shared_ptr<IHintManager>*>(iManager);
 }
diff --git a/native/android/tests/performance_hint/Android.bp b/native/android/tests/performance_hint/Android.bp
index fdc1bc6..608d5d8 100644
--- a/native/android/tests/performance_hint/Android.bp
+++ b/native/android/tests/performance_hint/Android.bp
@@ -39,6 +39,7 @@
         "libandroid",
         "liblog",
         "libbinder",
+        "libbinder_ndk",
         "libpowermanager",
         "libutils",
     ],
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index 4553b49..bfbe34e 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -16,11 +16,11 @@
 
 #define LOG_TAG "PerformanceHintNativeTest"
 
-#include <android/WorkDuration.h>
-#include <android/os/IHintManager.h>
-#include <android/os/IHintSession.h>
+#include <aidl/android/hardware/power/WorkDuration.h>
+#include <aidl/android/os/IHintManager.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
 #include <android/performance_hint.h>
-#include <binder/IBinder.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <performance_hint_private.h>
@@ -28,48 +28,54 @@
 #include <memory>
 #include <vector>
 
-using android::binder::Status;
-using android::os::IHintManager;
-using android::os::IHintSession;
+using aidl::android::hardware::power::WorkDuration;
+using aidl::android::os::IHintManager;
+using aidl::android::os::IHintSession;
+using ndk::ScopedAStatus;
+using ndk::SpAIBinder;
 
 using namespace android;
 using namespace testing;
 
 class MockIHintManager : public IHintManager {
 public:
-    MOCK_METHOD(Status, createHintSession,
-                (const sp<IBinder>& token, const ::std::vector<int32_t>& tids,
-                 int64_t durationNanos, ::android::sp<IHintSession>* _aidl_return),
+    MOCK_METHOD(ScopedAStatus, createHintSession,
+                (const SpAIBinder& token, const ::std::vector<int32_t>& tids, int64_t durationNanos,
+                 std::shared_ptr<IHintSession>* _aidl_return),
                 (override));
-    MOCK_METHOD(Status, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
-    MOCK_METHOD(Status, setHintSessionThreads,
-                (const sp<IHintSession>& hintSession, const ::std::vector<int32_t>& tids),
+    MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
+    MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
+                (const std::shared_ptr<IHintSession>& hintSession,
+                 const ::std::vector<int32_t>& tids),
                 (override));
-    MOCK_METHOD(Status, getHintSessionThreadIds,
-                (const sp<IHintSession>& hintSession, ::std::vector<int32_t>* tids), (override));
-    MOCK_METHOD(IBinder*, onAsBinder, (), (override));
+    MOCK_METHOD(ScopedAStatus, getHintSessionThreadIds,
+                (const std::shared_ptr<IHintSession>& hintSession, ::std::vector<int32_t>* tids),
+                (override));
+    MOCK_METHOD(SpAIBinder, asBinder, (), (override));
+    MOCK_METHOD(bool, isRemote, (), (override));
 };
 
 class MockIHintSession : public IHintSession {
 public:
-    MOCK_METHOD(Status, updateTargetWorkDuration, (int64_t targetDurationNanos), (override));
-    MOCK_METHOD(Status, reportActualWorkDuration,
+    MOCK_METHOD(ScopedAStatus, updateTargetWorkDuration, (int64_t targetDurationNanos), (override));
+    MOCK_METHOD(ScopedAStatus, reportActualWorkDuration,
                 (const ::std::vector<int64_t>& actualDurationNanos,
                  const ::std::vector<int64_t>& timeStampNanos),
                 (override));
-    MOCK_METHOD(Status, sendHint, (int32_t hint), (override));
-    MOCK_METHOD(Status, setMode, (int32_t mode, bool enabled), (override));
-    MOCK_METHOD(Status, close, (), (override));
-    MOCK_METHOD(IBinder*, onAsBinder, (), (override));
-    MOCK_METHOD(Status, reportActualWorkDuration2,
-                (const ::std::vector<android::os::WorkDuration>& workDurations), (override));
+    MOCK_METHOD(ScopedAStatus, sendHint, (int32_t hint), (override));
+    MOCK_METHOD(ScopedAStatus, setMode, (int32_t mode, bool enabled), (override));
+    MOCK_METHOD(ScopedAStatus, close, (), (override));
+    MOCK_METHOD(ScopedAStatus, reportActualWorkDuration2,
+                (const ::std::vector<WorkDuration>& workDurations), (override));
+    MOCK_METHOD(SpAIBinder, asBinder, (), (override));
+    MOCK_METHOD(bool, isRemote, (), (override));
 };
 
 class PerformanceHintTest : public Test {
 public:
     void SetUp() override {
-        mMockIHintManager = new StrictMock<MockIHintManager>();
-        APerformanceHint_setIHintManagerForTesting(mMockIHintManager);
+        mMockIHintManager = ndk::SharedRefBase::make<NiceMock<MockIHintManager>>();
+        APerformanceHint_setIHintManagerForTesting(&mMockIHintManager);
     }
 
     void TearDown() override {
@@ -79,15 +85,50 @@
     }
 
     APerformanceHintManager* createManager() {
-        EXPECT_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
-                .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<0>(123L), Return(Status())));
+        ON_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
+                .WillByDefault(DoAll(SetArgPointee<0>(123L), [] { return ScopedAStatus::ok(); }));
         return APerformanceHint_getManager();
     }
+    APerformanceHintSession* createSession(APerformanceHintManager* manager,
+                                           int64_t targetDuration = 56789L) {
+        mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
 
-    StrictMock<MockIHintManager>* mMockIHintManager = nullptr;
+        std::vector<int32_t> tids;
+        tids.push_back(1);
+        tids.push_back(2);
+
+        ON_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
+                .WillByDefault(DoAll(SetArgPointee<3>(std::shared_ptr<IHintSession>(mMockSession)),
+                                     [] { return ScopedAStatus::ok(); }));
+        ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
+            return ScopedAStatus::ok();
+        });
+        ON_CALL(*mMockSession, sendHint(_)).WillByDefault([] { return ScopedAStatus::ok(); });
+        ON_CALL(*mMockSession, setMode(_, _)).WillByDefault([] { return ScopedAStatus::ok(); });
+        ON_CALL(*mMockSession, close()).WillByDefault([] { return ScopedAStatus::ok(); });
+        ON_CALL(*mMockSession, updateTargetWorkDuration(_)).WillByDefault([] {
+            return ScopedAStatus::ok();
+        });
+        ON_CALL(*mMockSession, reportActualWorkDuration(_, _)).WillByDefault([] {
+            return ScopedAStatus::ok();
+        });
+        ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
+            return ScopedAStatus::ok();
+        });
+
+        return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+    }
+
+    std::shared_ptr<NiceMock<MockIHintManager>> mMockIHintManager = nullptr;
+    std::shared_ptr<NiceMock<MockIHintSession>> mMockSession = nullptr;
 };
 
+bool equalsWithoutTimestamp(WorkDuration lhs, WorkDuration rhs) {
+    return lhs.workPeriodStartTimestampNanos == rhs.workPeriodStartTimestampNanos &&
+            lhs.cpuDurationNanos == rhs.cpuDurationNanos &&
+            lhs.gpuDurationNanos == rhs.gpuDurationNanos && lhs.durationNanos == rhs.durationNanos;
+}
+
 TEST_F(PerformanceHintTest, TestGetPreferredUpdateRateNanos) {
     APerformanceHintManager* manager = createManager();
     int64_t preferredUpdateRateNanos = APerformanceHint_getPreferredUpdateRateNanos(manager);
@@ -96,25 +137,11 @@
 
 TEST_F(PerformanceHintTest, TestSession) {
     APerformanceHintManager* manager = createManager();
-
-    std::vector<int32_t> tids;
-    tids.push_back(1);
-    tids.push_back(2);
-    int64_t targetDuration = 56789L;
-
-    StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
-    sp<IHintSession> session_sp(iSession);
-
-    EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
-            .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
-    APerformanceHintSession* session =
-            APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+    APerformanceHintSession* session = createSession(manager);
     ASSERT_TRUE(session);
 
     int64_t targetDurationNanos = 10;
-    EXPECT_CALL(*iSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
+    EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
     int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
     EXPECT_EQ(0, result);
 
@@ -122,8 +149,7 @@
     int64_t actualDurationNanos = 20;
     std::vector<int64_t> actualDurations;
     actualDurations.push_back(20);
-    EXPECT_CALL(*iSession, reportActualWorkDuration(Eq(actualDurations), _)).Times(Exactly(1));
-    EXPECT_CALL(*iSession, reportActualWorkDuration2(_)).Times(Exactly(1));
+    EXPECT_CALL(*mMockSession, reportActualWorkDuration2(_)).Times(Exactly(1));
     result = APerformanceHint_reportActualWorkDuration(session, actualDurationNanos);
     EXPECT_EQ(0, result);
 
@@ -133,114 +159,70 @@
     EXPECT_EQ(EINVAL, result);
 
     SessionHint hintId = SessionHint::CPU_LOAD_RESET;
-    EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1));
+    EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(1));
     result = APerformanceHint_sendHint(session, hintId);
     EXPECT_EQ(0, result);
     usleep(110000); // Sleep for longer than the update timeout.
-    EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1));
+    EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(1));
     result = APerformanceHint_sendHint(session, hintId);
     EXPECT_EQ(0, result);
     // Expect to get rate limited if we try to send faster than the limiter allows
-    EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(0));
+    EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(0));
     result = APerformanceHint_sendHint(session, hintId);
     EXPECT_EQ(0, result);
 
     result = APerformanceHint_sendHint(session, static_cast<SessionHint>(-1));
     EXPECT_EQ(EINVAL, result);
 
-    EXPECT_CALL(*iSession, close()).Times(Exactly(1));
+    EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
     APerformanceHint_closeSession(session);
 }
 
 TEST_F(PerformanceHintTest, SetThreads) {
     APerformanceHintManager* manager = createManager();
 
-    std::vector<int32_t> tids;
-    tids.push_back(1);
-    tids.push_back(2);
-    int64_t targetDuration = 56789L;
-
-    StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
-    sp<IHintSession> session_sp(iSession);
-
-    EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
-            .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
-    APerformanceHintSession* session =
-            APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+    APerformanceHintSession* session = createSession(manager);
     ASSERT_TRUE(session);
 
-    std::vector<int32_t> emptyTids;
-    int result = APerformanceHint_setThreads(session, emptyTids.data(), emptyTids.size());
+    int32_t emptyTids[2];
+    int result = APerformanceHint_setThreads(session, emptyTids, 0);
     EXPECT_EQ(EINVAL, result);
 
     std::vector<int32_t> newTids;
     newTids.push_back(1);
     newTids.push_back(3);
-    EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(newTids)))
-            .Times(Exactly(1))
-            .WillOnce(Return(Status()));
+    EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(newTids))).Times(Exactly(1));
     result = APerformanceHint_setThreads(session, newTids.data(), newTids.size());
     EXPECT_EQ(0, result);
 
-    testing::Mock::VerifyAndClearExpectations(mMockIHintManager);
+    testing::Mock::VerifyAndClearExpectations(mMockIHintManager.get());
     std::vector<int32_t> invalidTids;
-    auto status = Status::fromExceptionCode(binder::Status::Exception::EX_SECURITY);
     invalidTids.push_back(4);
     invalidTids.push_back(6);
     EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(invalidTids)))
             .Times(Exactly(1))
-            .WillOnce(Return(status));
+            .WillOnce(Return(ByMove(ScopedAStatus::fromExceptionCode(EX_SECURITY))));
     result = APerformanceHint_setThreads(session, invalidTids.data(), invalidTids.size());
     EXPECT_EQ(EPERM, result);
 }
 
 TEST_F(PerformanceHintTest, SetPowerEfficient) {
     APerformanceHintManager* manager = createManager();
-
-    std::vector<int32_t> tids;
-    tids.push_back(1);
-    tids.push_back(2);
-    int64_t targetDuration = 56789L;
-
-    StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
-    sp<IHintSession> session_sp(iSession);
-
-    EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
-            .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
-    APerformanceHintSession* session =
-            APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+    APerformanceHintSession* session = createSession(manager);
     ASSERT_TRUE(session);
 
-    EXPECT_CALL(*iSession, setMode(_, Eq(true))).Times(Exactly(1));
+    EXPECT_CALL(*mMockSession, setMode(_, Eq(true))).Times(Exactly(1));
     int result = APerformanceHint_setPreferPowerEfficiency(session, true);
     EXPECT_EQ(0, result);
 
-    EXPECT_CALL(*iSession, setMode(_, Eq(false))).Times(Exactly(1));
+    EXPECT_CALL(*mMockSession, setMode(_, Eq(false))).Times(Exactly(1));
     result = APerformanceHint_setPreferPowerEfficiency(session, false);
     EXPECT_EQ(0, result);
 }
 
 TEST_F(PerformanceHintTest, CreateZeroTargetDurationSession) {
     APerformanceHintManager* manager = createManager();
-
-    std::vector<int32_t> tids;
-    tids.push_back(1);
-    tids.push_back(2);
-    int64_t targetDuration = 0;
-
-    StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
-    sp<IHintSession> session_sp(iSession);
-
-    EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
-            .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
-    APerformanceHintSession* session =
-            APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+    APerformanceHintSession* session = createSession(manager, 0);
     ASSERT_TRUE(session);
 }
 
@@ -251,12 +233,12 @@
         return false;
     }
     for (int i = 0; i < expected.size(); ++i) {
-        android::os::WorkDuration expectedWorkDuration = expected[i];
-        android::os::WorkDuration actualWorkDuration = arg[i];
-        if (!expectedWorkDuration.equalsWithoutTimestamp(actualWorkDuration)) {
+        WorkDuration expectedWorkDuration = expected[i];
+        WorkDuration actualWorkDuration = arg[i];
+        if (!equalsWithoutTimestamp(expectedWorkDuration, actualWorkDuration)) {
             *result_listener << "WorkDuration at [" << i << "] is different: "
-                             << "Expected: " << expectedWorkDuration
-                             << ", Actual: " << actualWorkDuration;
+                             << "Expected: " << expectedWorkDuration.toString()
+                             << ", Actual: " << actualWorkDuration.toString();
             return false;
         }
     }
@@ -265,92 +247,37 @@
 
 TEST_F(PerformanceHintTest, TestAPerformanceHint_reportActualWorkDuration2) {
     APerformanceHintManager* manager = createManager();
-
-    std::vector<int32_t> tids;
-    tids.push_back(1);
-    tids.push_back(2);
-    int64_t targetDuration = 56789L;
-
-    StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
-    sp<IHintSession> session_sp(iSession);
-
-    EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
-            .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
-    APerformanceHintSession* session =
-            APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+    APerformanceHintSession* session = createSession(manager);
     ASSERT_TRUE(session);
 
     int64_t targetDurationNanos = 10;
-    EXPECT_CALL(*iSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
+    EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
     int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
     EXPECT_EQ(0, result);
 
     usleep(2); // Sleep for longer than preferredUpdateRateNanos.
-    {
-        std::vector<android::os::WorkDuration> actualWorkDurations;
-        android::os::WorkDuration workDuration(1, 20, 13, 8);
-        actualWorkDurations.push_back(workDuration);
+    struct TestPair {
+        WorkDuration duration;
+        int expectedResult;
+    };
+    std::vector<TestPair> testPairs{
+            {{1, 20, 1, 13, 8}, OK},       {{1, -20, 1, 13, 8}, EINVAL},
+            {{1, 20, -1, 13, 8}, EINVAL},  {{1, -20, 1, -13, 8}, EINVAL},
+            {{1, -20, 1, 13, -8}, EINVAL},
+    };
+    for (auto&& pair : testPairs) {
+        std::vector<WorkDuration> actualWorkDurations;
+        actualWorkDurations.push_back(pair.duration);
 
-        EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
+        EXPECT_CALL(*mMockSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
                 .Times(Exactly(1));
         result = APerformanceHint_reportActualWorkDuration2(session,
-                                                            static_cast<AWorkDuration*>(
-                                                                    &workDuration));
-        EXPECT_EQ(0, result);
+                                                            reinterpret_cast<AWorkDuration*>(
+                                                                    &pair.duration));
+        EXPECT_EQ(pair.expectedResult, result);
     }
 
-    {
-        std::vector<android::os::WorkDuration> actualWorkDurations;
-        android::os::WorkDuration workDuration(-1, 20, 13, 8);
-        actualWorkDurations.push_back(workDuration);
-
-        EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
-                .Times(Exactly(1));
-        result = APerformanceHint_reportActualWorkDuration2(session,
-                                                            static_cast<AWorkDuration*>(
-                                                                    &workDuration));
-        EXPECT_EQ(22, result);
-    }
-    {
-        std::vector<android::os::WorkDuration> actualWorkDurations;
-        android::os::WorkDuration workDuration(1, -20, 13, 8);
-        actualWorkDurations.push_back(workDuration);
-
-        EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
-                .Times(Exactly(1));
-        result = APerformanceHint_reportActualWorkDuration2(session,
-                                                            static_cast<AWorkDuration*>(
-                                                                    &workDuration));
-        EXPECT_EQ(22, result);
-    }
-    {
-        std::vector<android::os::WorkDuration> actualWorkDurations;
-        android::os::WorkDuration workDuration(1, 20, -13, 8);
-        actualWorkDurations.push_back(workDuration);
-
-        EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
-                .Times(Exactly(1));
-        result = APerformanceHint_reportActualWorkDuration2(session,
-                                                            static_cast<AWorkDuration*>(
-                                                                    &workDuration));
-        EXPECT_EQ(EINVAL, result);
-    }
-    {
-        std::vector<android::os::WorkDuration> actualWorkDurations;
-        android::os::WorkDuration workDuration(1, 20, 13, -8);
-        actualWorkDurations.push_back(workDuration);
-
-        EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
-                .Times(Exactly(1));
-        result = APerformanceHint_reportActualWorkDuration2(session,
-                                                            static_cast<AWorkDuration*>(
-                                                                    &workDuration));
-        EXPECT_EQ(EINVAL, result);
-    }
-
-    EXPECT_CALL(*iSession, close()).Times(Exactly(1));
+    EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
     APerformanceHint_closeSession(session);
 }
 
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 35717af..aa1a41e 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -24,6 +24,7 @@
 import android.app.StatsManager;
 import android.app.UidObserver;
 import android.content.Context;
+import android.hardware.power.WorkDuration;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.IHintManager;
@@ -32,7 +33,6 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.os.WorkDuration;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -198,8 +198,8 @@
 
         private static native void nativeSetMode(long halPtr, int mode, boolean enabled);
 
-        private static native void nativeReportActualWorkDuration(long halPtr,
-                                                                  WorkDuration[] workDurations);
+        private static native void nativeReportActualWorkDuration(
+                long halPtr, WorkDuration[] workDurations);
 
         /** Wrapper for HintManager.nativeInit */
         public void halInit() {
@@ -670,46 +670,46 @@
 
         void validateWorkDuration(WorkDuration workDuration) {
             if (DEBUG) {
-                Slogf.d(TAG, "WorkDuration(" + workDuration.getTimestampNanos() + ", "
-                        + workDuration.getWorkPeriodStartTimestampNanos() + ", "
-                        + workDuration.getActualTotalDurationNanos() + ", "
-                        + workDuration.getActualCpuDurationNanos() + ", "
-                        + workDuration.getActualGpuDurationNanos() + ")");
+                Slogf.d(TAG, "WorkDuration("
+                        + workDuration.durationNanos + ", "
+                        + workDuration.workPeriodStartTimestampNanos + ", "
+                        + workDuration.cpuDurationNanos + ", "
+                        + workDuration.gpuDurationNanos + ")");
             }
 
             // Allow work period start timestamp to be zero in system server side because
             // legacy API call will use zero value. It can not be estimated with the timestamp
             // the sample is received because the samples could stack up.
-            if (workDuration.getWorkPeriodStartTimestampNanos() < 0) {
+            if (workDuration.durationNanos <= 0) {
+                throw new IllegalArgumentException(
+                    TextUtils.formatSimple("Actual total duration (%d) should be greater than 0",
+                            workDuration.durationNanos));
+            }
+            if (workDuration.workPeriodStartTimestampNanos < 0) {
                 throw new IllegalArgumentException(
                     TextUtils.formatSimple(
                             "Work period start timestamp (%d) should be greater than 0",
-                            workDuration.getWorkPeriodStartTimestampNanos()));
+                            workDuration.workPeriodStartTimestampNanos));
             }
-            if (workDuration.getActualTotalDurationNanos() <= 0) {
-                throw new IllegalArgumentException(
-                    TextUtils.formatSimple("Actual total duration (%d) should be greater than 0",
-                            workDuration.getActualTotalDurationNanos()));
-            }
-            if (workDuration.getActualCpuDurationNanos() < 0) {
+            if (workDuration.cpuDurationNanos < 0) {
                 throw new IllegalArgumentException(
                     TextUtils.formatSimple(
                         "Actual CPU duration (%d) should be greater than or equal to 0",
-                            workDuration.getActualCpuDurationNanos()));
+                            workDuration.cpuDurationNanos));
             }
-            if (workDuration.getActualGpuDurationNanos() < 0) {
+            if (workDuration.gpuDurationNanos < 0) {
                 throw new IllegalArgumentException(
                     TextUtils.formatSimple(
                         "Actual GPU duration (%d) should greater than or equal to 0",
-                            workDuration.getActualGpuDurationNanos()));
+                            workDuration.gpuDurationNanos));
             }
-            if (workDuration.getActualCpuDurationNanos()
-                    + workDuration.getActualGpuDurationNanos() <= 0) {
+            if (workDuration.cpuDurationNanos
+                    + workDuration.gpuDurationNanos <= 0) {
                 throw new IllegalArgumentException(
                     TextUtils.formatSimple(
                         "The actual CPU duration (%d) and the actual GPU duration (%d)"
-                        + " should not both be 0", workDuration.getActualCpuDurationNanos(),
-                        workDuration.getActualGpuDurationNanos()));
+                        + " should not both be 0", workDuration.cpuDurationNanos,
+                        workDuration.gpuDurationNanos));
             }
         }
 
diff --git a/services/core/jni/com_android_server_hint_HintManagerService.cpp b/services/core/jni/com_android_server_hint_HintManagerService.cpp
index b2bdaa3..5b8ef19 100644
--- a/services/core/jni/com_android_server_hint_HintManagerService.cpp
+++ b/services/core/jni/com_android_server_hint_HintManagerService.cpp
@@ -19,8 +19,11 @@
 //#define LOG_NDEBUG 0
 
 #include <aidl/android/hardware/power/IPower.h>
+#include <aidl/android/os/IHintManager.h>
 #include <android-base/stringprintf.h>
-#include <inttypes.h>
+#include <android/binder_manager.h>
+#include <android/binder_parcel.h>
+#include <android/binder_parcel_utils.h>
 #include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <powermanager/PowerHalController.h>
@@ -43,15 +46,16 @@
 static struct {
     jclass clazz{};
     jfieldID workPeriodStartTimestampNanos{};
-    jfieldID actualTotalDurationNanos{};
-    jfieldID actualCpuDurationNanos{};
-    jfieldID actualGpuDurationNanos{};
-    jfieldID timestampNanos{};
+    jfieldID durationNanos{};
+    jfieldID cpuDurationNanos{};
+    jfieldID gpuDurationNanos{};
+    jfieldID timeStampNanos{};
 } gWorkDurationInfo;
 
 static power::PowerHalController gPowerHalController;
-static std::unordered_map<jlong, std::shared_ptr<PowerHintSessionWrapper>> gSessionMap;
 static std::mutex gSessionMapLock;
+static std::unordered_map<jlong, std::shared_ptr<PowerHintSessionWrapper>> gSessionMap
+        GUARDED_BY(gSessionMapLock);
 
 static int64_t getHintSessionPreferredRate() {
     int64_t rate = -1;
@@ -63,15 +67,15 @@
 }
 
 static jlong createHintSession(JNIEnv* env, int32_t tgid, int32_t uid,
-                               std::vector<int32_t> threadIds, int64_t durationNanos) {
+                               std::vector<int32_t>& threadIds, int64_t durationNanos) {
     auto result = gPowerHalController.createHintSession(tgid, uid, threadIds, durationNanos);
     if (result.isOk()) {
-        auto session_ptr = reinterpret_cast<jlong>(result.value().get());
-        {
-            std::unique_lock<std::mutex> sessionLock(gSessionMapLock);
-            auto res = gSessionMap.insert({session_ptr, result.value()});
-            return res.second ? session_ptr : 0;
-        }
+        jlong session_ptr = reinterpret_cast<jlong>(result.value().get());
+        std::scoped_lock sessionLock(gSessionMapLock);
+        auto res = gSessionMap.insert({session_ptr, result.value()});
+        return res.second ? session_ptr : 0;
+    } else if (result.isFailed()) {
+        ALOGW("createHintSession failed with message: %s", result.errorMessage());
     }
     return 0;
 }
@@ -89,7 +93,7 @@
 static void closeHintSession(JNIEnv* env, int64_t session_ptr) {
     auto appSession = reinterpret_cast<PowerHintSessionWrapper*>(session_ptr);
     appSession->close();
-    std::unique_lock<std::mutex> sessionLock(gSessionMapLock);
+    std::scoped_lock sessionLock(gSessionMapLock);
     gSessionMap.erase(session_ptr);
 }
 
@@ -135,11 +139,8 @@
         ALOGW("GetIntArrayElements returns nullptr.");
         return 0;
     }
-    std::vector<int32_t> threadIds(tidArray.size());
-    for (size_t i = 0; i < tidArray.size(); i++) {
-        threadIds[i] = tidArray[i];
-    }
-    return createHintSession(env, tgid, uid, std::move(threadIds), durationNanos);
+    std::vector<int32_t> threadIds(tidArray.get(), tidArray.get() + tidArray.size());
+    return createHintSession(env, tgid, uid, threadIds, durationNanos);
 }
 
 static void nativePauseHintSession(JNIEnv* env, jclass /* clazz */, jlong session_ptr) {
@@ -177,12 +178,9 @@
 }
 
 static void nativeSetThreads(JNIEnv* env, jclass /* clazz */, jlong session_ptr, jintArray tids) {
-    ScopedIntArrayRO arrayThreadIds(env, tids);
+    ScopedIntArrayRO tidArray(env, tids);
 
-    std::vector<int32_t> threadIds(arrayThreadIds.size());
-    for (size_t i = 0; i < arrayThreadIds.size(); i++) {
-        threadIds[i] = arrayThreadIds[i];
-    }
+    std::vector<int32_t> threadIds(tidArray.get(), tidArray.get() + tidArray.size());
     setThreads(session_ptr, threadIds);
 }
 
@@ -200,13 +198,13 @@
         workDurations[i].workPeriodStartTimestampNanos =
                 env->GetLongField(workDuration, gWorkDurationInfo.workPeriodStartTimestampNanos);
         workDurations[i].durationNanos =
-                env->GetLongField(workDuration, gWorkDurationInfo.actualTotalDurationNanos);
+                env->GetLongField(workDuration, gWorkDurationInfo.durationNanos);
         workDurations[i].cpuDurationNanos =
-                env->GetLongField(workDuration, gWorkDurationInfo.actualCpuDurationNanos);
+                env->GetLongField(workDuration, gWorkDurationInfo.cpuDurationNanos);
         workDurations[i].gpuDurationNanos =
-                env->GetLongField(workDuration, gWorkDurationInfo.actualGpuDurationNanos);
+                env->GetLongField(workDuration, gWorkDurationInfo.gpuDurationNanos);
         workDurations[i].timeStampNanos =
-                env->GetLongField(workDuration, gWorkDurationInfo.timestampNanos);
+                env->GetLongField(workDuration, gWorkDurationInfo.timeStampNanos);
     }
     reportActualWorkDuration(session_ptr, workDurations);
 }
@@ -225,22 +223,22 @@
         {"nativeSendHint", "(JI)V", (void*)nativeSendHint},
         {"nativeSetThreads", "(J[I)V", (void*)nativeSetThreads},
         {"nativeSetMode", "(JIZ)V", (void*)nativeSetMode},
-        {"nativeReportActualWorkDuration", "(J[Landroid/os/WorkDuration;)V",
+        {"nativeReportActualWorkDuration", "(J[Landroid/hardware/power/WorkDuration;)V",
          (void*)nativeReportActualWorkDuration2},
 };
 
 int register_android_server_HintManagerService(JNIEnv* env) {
-    gWorkDurationInfo.clazz = env->FindClass("android/os/WorkDuration");
+    gWorkDurationInfo.clazz = env->FindClass("android/hardware/power/WorkDuration");
     gWorkDurationInfo.workPeriodStartTimestampNanos =
-            env->GetFieldID(gWorkDurationInfo.clazz, "mWorkPeriodStartTimestampNanos", "J");
-    gWorkDurationInfo.actualTotalDurationNanos =
-            env->GetFieldID(gWorkDurationInfo.clazz, "mActualTotalDurationNanos", "J");
-    gWorkDurationInfo.actualCpuDurationNanos =
-            env->GetFieldID(gWorkDurationInfo.clazz, "mActualCpuDurationNanos", "J");
-    gWorkDurationInfo.actualGpuDurationNanos =
-            env->GetFieldID(gWorkDurationInfo.clazz, "mActualGpuDurationNanos", "J");
-    gWorkDurationInfo.timestampNanos =
-            env->GetFieldID(gWorkDurationInfo.clazz, "mTimestampNanos", "J");
+            env->GetFieldID(gWorkDurationInfo.clazz, "workPeriodStartTimestampNanos", "J");
+    gWorkDurationInfo.durationNanos =
+            env->GetFieldID(gWorkDurationInfo.clazz, "durationNanos", "J");
+    gWorkDurationInfo.cpuDurationNanos =
+            env->GetFieldID(gWorkDurationInfo.clazz, "cpuDurationNanos", "J");
+    gWorkDurationInfo.gpuDurationNanos =
+            env->GetFieldID(gWorkDurationInfo.clazz, "gpuDurationNanos", "J");
+    gWorkDurationInfo.timeStampNanos =
+            env->GetFieldID(gWorkDurationInfo.clazz, "timeStampNanos", "J");
 
     return jniRegisterNativeMethods(env,
                                     "com/android/server/power/hint/"
diff --git a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
index 4ab9d3e..66599e9 100644
--- a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -39,12 +39,12 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.content.Context;
+import android.hardware.power.WorkDuration;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.IHintSession;
 import android.os.PerformanceHintManager;
 import android.os.Process;
-import android.os.WorkDuration;
 import android.util.Log;
 
 import com.android.server.FgThread;
@@ -76,6 +76,18 @@
 public class HintManagerServiceTest {
     private static final String TAG = "HintManagerServiceTest";
 
+    private static WorkDuration makeWorkDuration(
+            long timestamp, long duration, long workPeriodStartTime,
+            long cpuDuration, long gpuDuration) {
+        WorkDuration out = new WorkDuration();
+        out.timeStampNanos = timestamp;
+        out.durationNanos = duration;
+        out.workPeriodStartTimestampNanos = workPeriodStartTime;
+        out.cpuDurationNanos = cpuDuration;
+        out.gpuDurationNanos = gpuDuration;
+        return out;
+    }
+
     private static final long DEFAULT_HINT_PREFERRED_RATE = 16666666L;
     private static final long DEFAULT_TARGET_DURATION = 16666666L;
     private static final long CONCURRENCY_TEST_DURATION_SEC = 10;
@@ -91,11 +103,11 @@
     private static final long[] TIMESTAMPS_ZERO = new long[] {};
     private static final long[] TIMESTAMPS_TWO = new long[] {1L, 2L};
     private static final WorkDuration[] WORK_DURATIONS_FIVE = new WorkDuration[] {
-        new WorkDuration(1L, 11L, 8L, 4L, 1L),
-        new WorkDuration(2L, 13L, 8L, 6L, 2L),
-        new WorkDuration(3L, 333333333L, 8L, 333333333L, 3L),
-        new WorkDuration(2L, 13L, 0L, 6L, 2L),
-        new WorkDuration(2L, 13L, 8L, 0L, 2L),
+        makeWorkDuration(1L, 11L, 1L, 8L, 4L),
+        makeWorkDuration(2L, 13L, 2L, 8L, 6L),
+        makeWorkDuration(3L, 333333333L, 3L, 8L, 333333333L),
+        makeWorkDuration(2L, 13L, 2L, 0L, 6L),
+        makeWorkDuration(2L, 13L, 2L, 8L, 0L),
     };
 
     @Mock private Context mContext;
@@ -621,20 +633,20 @@
 
         assertThrows(IllegalArgumentException.class, () -> {
             a.reportActualWorkDuration2(
-                    new WorkDuration[] {new WorkDuration(-1L, 11L, 8L, 4L, 1L)});
+                    new WorkDuration[] {makeWorkDuration(1L, 11L, -1L, 8L, 4L)});
         });
 
         assertThrows(IllegalArgumentException.class, () -> {
-            a.reportActualWorkDuration2(new WorkDuration[] {new WorkDuration(1L, 0L, 8L, 4L, 1L)});
+            a.reportActualWorkDuration2(new WorkDuration[] {makeWorkDuration(1L, 0L, 1L, 8L, 4L)});
         });
 
         assertThrows(IllegalArgumentException.class, () -> {
-            a.reportActualWorkDuration2(new WorkDuration[] {new WorkDuration(1L, 11L, 0L, 0L, 1L)});
+            a.reportActualWorkDuration2(new WorkDuration[] {makeWorkDuration(1L, 11L, 1L, 0L, 0L)});
         });
 
         assertThrows(IllegalArgumentException.class, () -> {
             a.reportActualWorkDuration2(
-                    new WorkDuration[] {new WorkDuration(1L, 11L, 8L, -1L, 1L)});
+                    new WorkDuration[] {makeWorkDuration(1L, 11L, 1L, 8L, -1L)});
         });
 
         reset(mNativeWrapperMock);