Merge "Camera: Improve reference docs for lensShadingApplied" into main
diff --git a/media/liberror/include/error/BinderResult.h b/media/liberror/include/error/BinderResult.h
new file mode 100644
index 0000000..1f1211c
--- /dev/null
+++ b/media/liberror/include/error/BinderResult.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <binder/Status.h>
+#include <error/expected_utils.h>
+#include <utils/Errors.h>
+
+namespace android {
+namespace error {
+
+/**
+ * A convenience short-hand for base::expected, where the error type is a binder::Status, for use
+ * when implementing binder services.
+ * Clients need to link against libbinder, since this library is header only.
+ */
+template <typename T>
+using BinderResult = base::expected<T, binder::Status>;
+
+inline base::unexpected<binder::Status> unexpectedExceptionCode(int32_t exceptionCode,
+                                                                const char* s) {
+    return base::unexpected{binder::Status::fromExceptionCode(exceptionCode, s)};
+}
+
+inline base::unexpected<binder::Status> unexpectedServiceException(int32_t serviceSpecificCode,
+                                                                   const char* s) {
+    return base::unexpected{binder::Status::fromServiceSpecificError(serviceSpecificCode, s)};
+}
+
+}  // namespace error
+}  // namespace android
+
+inline std::string errorToString(const ::android::binder::Status& status) {
+    return std::string{status.toString8().c_str()};
+}
diff --git a/media/liberror/include/error/BinderStatusMatcher.h b/media/liberror/include/error/BinderStatusMatcher.h
new file mode 100644
index 0000000..11d9e65
--- /dev/null
+++ b/media/liberror/include/error/BinderStatusMatcher.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <ostream>
+
+#include <binder/Status.h>
+
+namespace android::error {
+
+class BinderStatusMatcher {
+  public:
+    using is_gtest_matcher = void;
+
+    explicit BinderStatusMatcher(binder::Status status) : status_(std::move(status)) {}
+
+    static BinderStatusMatcher hasException(binder::Status::Exception ex) {
+        return BinderStatusMatcher(binder::Status::fromExceptionCode(ex));
+    }
+
+    static BinderStatusMatcher isOk() { return BinderStatusMatcher(binder::Status::ok()); }
+
+    bool MatchAndExplain(const binder::Status& value,
+                         ::testing::MatchResultListener* listener) const {
+        if (status_.exceptionCode() == value.exceptionCode() &&
+            status_.transactionError() == value.transactionError() &&
+            status_.serviceSpecificErrorCode() == value.serviceSpecificErrorCode()) {
+            return true;
+        }
+        *listener << "received binder status: " << value;
+        return false;
+    }
+
+    void DescribeTo(std::ostream* os) const { *os << "contains binder status " << status_; }
+
+    void DescribeNegationTo(std::ostream* os) const {
+        *os << "does not contain binder status " << status_;
+    }
+
+  private:
+    const binder::Status status_;
+};
+}  // namespace android::error
diff --git a/media/liberror/include/error/ExpectedMatchers.h b/media/liberror/include/error/ExpectedMatchers.h
new file mode 100644
index 0000000..b81adbf
--- /dev/null
+++ b/media/liberror/include/error/ExpectedMatchers.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <ostream>
+#include <type_traits>
+
+namespace android::error {
+
+/**
+ * Example Usage:
+ * Given a function with signature
+ *       Result<T, U> foo()
+ * Matchers can be used as follows:
+ *       EXPECT_THAT(foo(), IsOkAnd(Eq(T{})));
+ *       EXPECT_THAT(foo(), IsErrorAnd(Eq(U{})));
+ */
+template <typename ExpectedT>
+class IsOkAndImpl : public ::testing::MatcherInterface<ExpectedT> {
+  public:
+    using ValueT = std::remove_reference_t<ExpectedT>::value_type;
+
+    template <typename InnerMatcher>
+    explicit IsOkAndImpl(InnerMatcher innerMatcher)
+        : inner_matcher_(::testing::SafeMatcherCast<const ValueT&>(
+                  std::forward<InnerMatcher>(innerMatcher))) {}
+
+    bool MatchAndExplain(ExpectedT val, ::testing::MatchResultListener* listener) const {
+        if (!val.has_value()) {
+            *listener << "which has error " << ::testing::PrintToString(val.error());
+            return false;
+        }
+        const auto res = inner_matcher_.MatchAndExplain(val.value(), listener);
+        if (!res) {
+            *listener << "which has value " << ::testing::PrintToString(val.value());
+        }
+        return res;
+    }
+
+    void DescribeTo(std::ostream* os) const {
+        *os << "contains expected value which ";
+        inner_matcher_.DescribeTo(os);
+    }
+
+    void DescribeNegationTo(std::ostream* os) const {
+        *os << "does not contain expected, or contains expected value which ";
+        inner_matcher_.DescribeNegationTo(os);
+    }
+
+  private:
+    ::testing::Matcher<const ValueT&> inner_matcher_;
+};
+
+template <typename InnerMatcher>
+class IsOkAnd {
+  public:
+    explicit IsOkAnd(InnerMatcher innerMatcher) : inner_matcher_(std::move(innerMatcher)) {}
+
+    template <typename T>
+    operator ::testing::Matcher<T>() const {
+        return ::testing::Matcher<T>{new IsOkAndImpl<const T&>(inner_matcher_)};
+    }
+
+  private:
+    InnerMatcher inner_matcher_;
+};
+
+template <typename ExpectedT>
+class IsErrorAndImpl : public ::testing::MatcherInterface<ExpectedT> {
+  public:
+    using ErrorT = typename std::remove_reference_t<ExpectedT>::error_type;
+
+    template <typename InnerMatcher>
+    explicit IsErrorAndImpl(InnerMatcher innerMatcher)
+        : inner_matcher_(::testing::SafeMatcherCast<const ErrorT&>(
+                  std::forward<InnerMatcher>(innerMatcher))) {}
+
+    bool MatchAndExplain(ExpectedT val, ::testing::MatchResultListener* listener) const {
+        if (val.has_value()) {
+            *listener << "which has value " << ::testing::PrintToString(val.value());
+            return false;
+        }
+
+        const auto res = inner_matcher_.MatchAndExplain(val.error(), listener);
+        if (!res) {
+            *listener << "which has error " << ::testing::PrintToString(val.error());
+        }
+        return res;
+    }
+
+    void DescribeTo(std::ostream* os) const {
+        *os << "contains error value which ";
+        inner_matcher_.DescribeTo(os);
+    }
+
+    void DescribeNegationTo(std::ostream* os) const {
+        *os << "does not contain error value, or contains error value which ";
+        inner_matcher_.DescribeNegationTo(os);
+    }
+
+  private:
+    ::testing::Matcher<const ErrorT&> inner_matcher_;
+};
+
+template <typename InnerMatcher>
+class IsErrorAnd {
+  public:
+    explicit IsErrorAnd(InnerMatcher innerMatcher) : inner_matcher_(std::move(innerMatcher)) {}
+
+    template <typename T>
+    operator ::testing::Matcher<T>() const {
+        return ::testing::Matcher<T>{new IsErrorAndImpl<const T&>(inner_matcher_)};
+    }
+
+  private:
+    InnerMatcher inner_matcher_;
+};
+
+}  // namespace android::error
diff --git a/services/audiopolicy/permission/NativePermissionController.cpp b/services/audiopolicy/permission/NativePermissionController.cpp
index 9fcf22d..8659f2c 100644
--- a/services/audiopolicy/permission/NativePermissionController.cpp
+++ b/services/audiopolicy/permission/NativePermissionController.cpp
@@ -24,9 +24,9 @@
 #include <cutils/android_filesystem_config.h>
 #include <utils/Errors.h>
 
-using ::android::base::unexpected;
 using ::android::binder::Status;
-using ::android::error::Result;
+using ::android::error::BinderResult;
+using ::android::error::unexpectedExceptionCode;
 
 namespace com::android::media::permission {
 static std::optional<std::string> getFixedPackageName(uid_t uid) {
@@ -103,23 +103,31 @@
 
 // -- End Binder methods
 
-Result<std::vector<std::string>> NativePermissionController::getPackagesForUid(uid_t uid) const {
+BinderResult<std::vector<std::string>> NativePermissionController::getPackagesForUid(
+        uid_t uid) const {
     uid = uid % AID_USER_OFFSET;
     const auto fixed_package_opt = getFixedPackageName(uid);
     if (fixed_package_opt.has_value()) {
-        return Result<std::vector<std::string>>{std::in_place_t{}, {fixed_package_opt.value()}};
+        return BinderResult<std::vector<std::string>>{std::in_place_t{},
+                                                      {fixed_package_opt.value()}};
     }
     std::lock_guard l{m_};
-    if (!is_package_populated_) return unexpected{::android::NO_INIT};
+    if (!is_package_populated_) {
+        return unexpectedExceptionCode(
+                Status::EX_ILLEGAL_STATE,
+                "NPC::getPackagesForUid: controller never populated by system_server");
+    }
     const auto cursor = package_map_.find(uid);
     if (cursor != package_map_.end()) {
         return cursor->second;
     } else {
-        return unexpected{::android::BAD_VALUE};
+        return unexpectedExceptionCode(
+                Status::EX_ILLEGAL_ARGUMENT,
+                ("NPC::getPackagesForUid: uid not found: " + std::to_string(uid)).c_str());
     }
 }
 
-Result<bool> NativePermissionController::validateUidPackagePair(
+BinderResult<bool> NativePermissionController::validateUidPackagePair(
         uid_t uid, const std::string& packageName) const {
     uid = uid % AID_USER_OFFSET;
     const auto fixed_package_opt = getFixedPackageName(uid);
@@ -127,20 +135,27 @@
         return packageName == fixed_package_opt.value();
     }
     std::lock_guard l{m_};
-    if (!is_package_populated_) return unexpected{::android::NO_INIT};
+    if (!is_package_populated_) {
+        return unexpectedExceptionCode(
+                Status::EX_ILLEGAL_STATE,
+                "NPC::validatedUidPackagePair: controller never populated by system_server");
+    }
     const auto cursor = package_map_.find(uid);
     return (cursor != package_map_.end()) &&
            (std::find(cursor->second.begin(), cursor->second.end(), packageName) !=
             cursor->second.end());
 }
 
-Result<bool> NativePermissionController::checkPermission(PermissionEnum perm, uid_t uid) const {
+BinderResult<bool> NativePermissionController::checkPermission(PermissionEnum perm,
+                                                               uid_t uid) const {
     std::lock_guard l{m_};
     const auto& uids = permission_map_[static_cast<size_t>(perm)];
     if (!uids.empty()) {
         return std::binary_search(uids.begin(), uids.end(), uid);
     } else {
-        return unexpected{::android::NO_INIT};
+        return unexpectedExceptionCode(
+                Status::EX_ILLEGAL_STATE,
+                "NPC::checkPermission: controller never populated by system_server");
     }
 }
 
diff --git a/services/audiopolicy/permission/ValidatedAttributionSourceState.cpp b/services/audiopolicy/permission/ValidatedAttributionSourceState.cpp
index 2c32289..f313422 100644
--- a/services/audiopolicy/permission/ValidatedAttributionSourceState.cpp
+++ b/services/audiopolicy/permission/ValidatedAttributionSourceState.cpp
@@ -20,31 +20,39 @@
 #include <error/expected_utils.h>
 #include <utils/Log.h>
 
+using ::android::binder::Status;
+using ::android::error::BinderResult;
+using ::android::error::unexpectedExceptionCode;
+
 namespace com::android::media::permission {
 
-using ::android::base::unexpected;
-
-Result<ValidatedAttributionSourceState> ValidatedAttributionSourceState::createFromBinderContext(
-        AttributionSourceState attr, const IPermissionProvider& provider) {
+BinderResult<ValidatedAttributionSourceState>
+ValidatedAttributionSourceState::createFromBinderContext(AttributionSourceState attr,
+                                                         const IPermissionProvider& provider) {
     attr.pid = ::android::IPCThreadState::self()->getCallingPid();
     attr.uid = ::android::IPCThreadState::self()->getCallingUid();
     return createFromTrustedUidNoPackage(std::move(attr), provider);
 }
 
-Result<ValidatedAttributionSourceState>
+BinderResult<ValidatedAttributionSourceState>
 ValidatedAttributionSourceState::createFromTrustedUidNoPackage(
         AttributionSourceState attr, const IPermissionProvider& provider) {
     if (attr.packageName.has_value() && attr.packageName->size() != 0) {
         if (VALUE_OR_RETURN(provider.validateUidPackagePair(attr.uid, attr.packageName.value()))) {
             return ValidatedAttributionSourceState{std::move(attr)};
         } else {
-            return unexpected{::android::PERMISSION_DENIED};
+            return unexpectedExceptionCode(Status::EX_SECURITY,
+                                           attr.toString()
+                                                   .insert(0, ": invalid attr ")
+                                                   .insert(0, __PRETTY_FUNCTION__)
+                                                   .c_str());
         }
     } else {
         // For APIs which don't appropriately pass attribution sources or packages, we need
         // to populate the package name with our best guess.
         const auto packageNames = VALUE_OR_RETURN(provider.getPackagesForUid(attr.uid));
-        LOG_ALWAYS_FATAL_IF(packageNames.empty());
+        LOG_ALWAYS_FATAL_IF(packageNames.empty(), "%s BUG: empty package list from controller",
+                            __PRETTY_FUNCTION__);
         attr.packageName = std::move(packageNames[0]);
         return ValidatedAttributionSourceState{std::move(attr)};
     }
diff --git a/services/audiopolicy/permission/include/media/IPermissionProvider.h b/services/audiopolicy/permission/include/media/IPermissionProvider.h
index 27a61ea..8d90543 100644
--- a/services/audiopolicy/permission/include/media/IPermissionProvider.h
+++ b/services/audiopolicy/permission/include/media/IPermissionProvider.h
@@ -22,7 +22,7 @@
 #include <vector>
 
 #include <com/android/media/permission/PermissionEnum.h>
-#include <error/Result.h>
+#include <error/BinderResult.h>
 
 namespace com::android::media::permission {
 
@@ -31,19 +31,20 @@
     // Get all package names which run under a certain app-id. Returns non-empty.
     // Not user specific, since packages are across users. Special app-ids (system,
     // shell, etc.) are handled.  Fails if the provider does not know about the
-    // app-id.
-    virtual ::android::error::Result<std::vector<std::string>> getPackagesForUid(
+    // app-id or if the provider has not been initialized.
+    virtual ::android::error::BinderResult<std::vector<std::string>> getPackagesForUid(
             uid_t uid) const = 0;
     // True iff the provided package name runs under the app-id of uid.
     // Special app-ids (system, shell, etc.) are handled.
-    // Fails if the provider does not know about the app-id.
-    virtual ::android::error::Result<bool> validateUidPackagePair(
+    // Fails if the provider does not know about the app-id or if the provider has not been
+    // initialized.
+    virtual ::android::error::BinderResult<bool> validateUidPackagePair(
             uid_t uid, const std::string& packageName) const = 0;
 
     // True iff the uid holds the permission (user aware).
     // Fails with NO_INIT if cache hasn't been populated.
-    virtual ::android::error::Result<bool> checkPermission(PermissionEnum permission,
-                                                           uid_t uid) const = 0;
+    virtual ::android::error::BinderResult<bool> checkPermission(PermissionEnum permission,
+                                                                 uid_t uid) const = 0;
     virtual ~IPermissionProvider() = default;
 };
 }  // namespace com::android::media::permission
diff --git a/services/audiopolicy/permission/include/media/NativePermissionController.h b/services/audiopolicy/permission/include/media/NativePermissionController.h
index d464023..a81c7a2 100644
--- a/services/audiopolicy/permission/include/media/NativePermissionController.h
+++ b/services/audiopolicy/permission/include/media/NativePermissionController.h
@@ -24,6 +24,7 @@
 
 #include <android-base/thread_annotations.h>
 #include <com/android/media/permission/BnNativePermissionController.h>
+#include <error/BinderResult.h>
 
 namespace com::android::media::permission {
 
@@ -36,11 +37,12 @@
     Status populatePermissionState(PermissionEnum permission, const std::vector<int>& uids) final;
     // end binder methods
 
-    ::android::error::Result<std::vector<std::string>> getPackagesForUid(uid_t uid) const final;
-    ::android::error::Result<bool> validateUidPackagePair(
+    ::android::error::BinderResult<std::vector<std::string>> getPackagesForUid(
+            uid_t uid) const final;
+    ::android::error::BinderResult<bool> validateUidPackagePair(
             uid_t uid, const std::string& packageName) const final;
-    ::android::error::Result<bool> checkPermission(PermissionEnum permission,
-                                                   uid_t uid) const final;
+    ::android::error::BinderResult<bool> checkPermission(PermissionEnum permission,
+                                                         uid_t uid) const final;
 
   private:
     mutable std::mutex m_;
diff --git a/services/audiopolicy/permission/include/media/ValidatedAttributionSourceState.h b/services/audiopolicy/permission/include/media/ValidatedAttributionSourceState.h
index 8d9da05..46f7d0a 100644
--- a/services/audiopolicy/permission/include/media/ValidatedAttributionSourceState.h
+++ b/services/audiopolicy/permission/include/media/ValidatedAttributionSourceState.h
@@ -17,22 +17,22 @@
 #pragma once
 
 #include <android/content/AttributionSourceState.h>
-#include <error/Result.h>
+#include <error/BinderResult.h>
 
 #include "IPermissionProvider.h"
 
 namespace com::android::media::permission {
 
 using ::android::content::AttributionSourceState;
-using ::android::error::Result;
 
 class ValidatedAttributionSourceState {
   public:
     /**
      * Validates an attribution source from within the context of a binder transaction.
-     * Overwrites the uid/pid and validates the packageName
+     * Overwrites the uid/pid and validates the packageName.
+     * Returns EX_SECURITY on package validation fail.
      */
-    static Result<ValidatedAttributionSourceState> createFromBinderContext(
+    static ::android::error::BinderResult<ValidatedAttributionSourceState> createFromBinderContext(
             AttributionSourceState attr, const IPermissionProvider& provider);
 
     /**
@@ -47,9 +47,10 @@
      * Create a ValidatedAttribubtionSourceState in cases where the uid/pid is trusted, but the
      * packages have not been validated. Proper use of the previous two methods should avoid the
      * necessity of this, but it is useful for migration purposes as well as testing this class.
+     * Returns EX_SECURITY on package validation fail.
      */
-    static Result<ValidatedAttributionSourceState> createFromTrustedUidNoPackage(
-            AttributionSourceState attr, const IPermissionProvider& provider);
+    static ::android::error::BinderResult<ValidatedAttributionSourceState>
+    createFromTrustedUidNoPackage(AttributionSourceState attr, const IPermissionProvider& provider);
 
     operator AttributionSourceState() const { return state_; }
 
diff --git a/services/audiopolicy/permission/tests/NativePermissionControllerTest.cpp b/services/audiopolicy/permission/tests/NativePermissionControllerTest.cpp
index 3f6b787..f2423c1 100644
--- a/services/audiopolicy/permission/tests/NativePermissionControllerTest.cpp
+++ b/services/audiopolicy/permission/tests/NativePermissionControllerTest.cpp
@@ -19,14 +19,22 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
-#include <android-base/expected.h>
+#include <error/BinderStatusMatcher.h>
+#include <error/ExpectedMatchers.h>
 
-using ::android::base::unexpected;
-using ::android::binder::Status;
+using android::binder::Status::EX_ILLEGAL_ARGUMENT;
+using android::binder::Status::EX_ILLEGAL_STATE;
+using android::error::BinderStatusMatcher;
+using android::error::IsErrorAnd;
+using android::error::IsOkAnd;
 using com::android::media::permission::NativePermissionController;
 using com::android::media::permission::PermissionEnum;
 using com::android::media::permission::UidPackageState;
 
+using ::testing::ElementsAre;
+using ::testing::IsFalse;
+using ::testing::IsTrue;
+
 class NativePermissionControllerTest : public ::testing::Test {
   protected:
     android::sp<NativePermissionController> holder_ =
@@ -40,50 +48,37 @@
     return out;
 }
 
-static std::vector<std::string> makeVector(const char* one) {
-    return {one};
-}
-
-static std::vector<std::string> makeVector(const char* one, const char* two) {
-    return {one, two};
-}
-
-#define UNWRAP_EQ(expr, desired_expr)                         \
-    do {                                                      \
-        auto tmp_ = (expr);                                   \
-        EXPECT_TRUE(tmp_.has_value());                        \
-        if (tmp_.has_value()) EXPECT_EQ(*tmp_, desired_expr); \
-    } while (0)
-
 // ---  Tests for non-populated ----
 TEST_F(NativePermissionControllerTest, getPackagesForUid_NotPopulated) {
     // Verify errors are returned
-    EXPECT_EQ(controller_.getPackagesForUid(10000), unexpected{android::NO_INIT});
-    EXPECT_EQ(controller_.getPackagesForUid(10001), unexpected{android::NO_INIT});
+    EXPECT_THAT(controller_.getPackagesForUid(10000),
+                IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_STATE)));
+    EXPECT_THAT(controller_.getPackagesForUid(10001),
+                IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_STATE)));
 
     // fixed uids should work
-    UNWRAP_EQ(controller_.getPackagesForUid(1000), makeVector("system"));
+    EXPECT_THAT(controller_.getPackagesForUid(1000), IsOkAnd(ElementsAre(std::string{"system"})));
 }
 
 TEST_F(NativePermissionControllerTest, validateUidPackagePair_NotPopulated) {
     // Verify errors are returned
-    EXPECT_EQ(controller_.validateUidPackagePair(10000, "com.package"),
-              unexpected{android::NO_INIT});
+    EXPECT_THAT(controller_.validateUidPackagePair(10000, "com.package"),
+                IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_STATE)));
 
     // fixed uids should work
-    UNWRAP_EQ(controller_.validateUidPackagePair(1000, "system"), true);
+    EXPECT_THAT(controller_.validateUidPackagePair(1000, "system"), IsOkAnd(IsTrue()));
 }
+
 // ---  Tests for populatePackagesForUids ----
 TEST_F(NativePermissionControllerTest, populatePackages_EmptyInput) {
     std::vector<UidPackageState> input;
 
     // succeeds
-    EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+    EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
 
     // Verify unknown uid behavior
-    const auto res1 = controller_.getPackagesForUid(10000);
-    ASSERT_FALSE(res1.has_value());
-    EXPECT_EQ(res1.error(), ::android::BAD_VALUE);
+    EXPECT_THAT(controller_.getPackagesForUid(10000),
+                IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_ARGUMENT)));
 }
 
 TEST_F(NativePermissionControllerTest, populatePackages_ValidInput) {
@@ -92,11 +87,11 @@
             createState(10001, {"com.example2.app1"}),
     };
 
-    EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+    EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
 
-    UNWRAP_EQ(controller_.getPackagesForUid(10000),
-              makeVector("com.example.app1", "com.example.app2"));
-    UNWRAP_EQ(controller_.getPackagesForUid(10001), makeVector("com.example2.app1"));
+    EXPECT_THAT(controller_.getPackagesForUid(10000),
+                IsOkAnd(ElementsAre("com.example.app1", "com.example.app2")));
+    EXPECT_THAT(controller_.getPackagesForUid(10001), IsOkAnd(ElementsAre("com.example2.app1")));
 }
 
 // --- Tests for updatePackagesForUid ---
@@ -107,14 +102,14 @@
     };
     UidPackageState newState = createState(12000, {"com.example.other"});
 
-    EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
-    EXPECT_TRUE(controller_.updatePackagesForUid(newState).isOk());
+    EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
+    EXPECT_THAT(controller_.updatePackagesForUid(newState), BinderStatusMatcher::isOk());
 
     // Verify the results: only the updated package should be changed
-    UNWRAP_EQ(controller_.getPackagesForUid(10000),
-              makeVector("com.example.app1", "com.example.app2"));
-    UNWRAP_EQ(controller_.getPackagesForUid(10001), makeVector("com.example2.app1"));
-    UNWRAP_EQ(controller_.getPackagesForUid(12000), makeVector("com.example.other"));
+    EXPECT_THAT(controller_.getPackagesForUid(10000),
+                IsOkAnd(ElementsAre("com.example.app1", "com.example.app2")));
+    EXPECT_THAT(controller_.getPackagesForUid(10001), IsOkAnd(ElementsAre("com.example2.app1")));
+    EXPECT_THAT(controller_.getPackagesForUid(12000), IsOkAnd(ElementsAre("com.example.other")));
 }
 
 TEST_F(NativePermissionControllerTest, updatePackages_ExistingUid) {
@@ -123,14 +118,14 @@
             createState(10001, {"com.example2.app1"}),
     };
 
-    EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+    EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
     // Update packages for existing uid
     UidPackageState newState = createState(10000, {"com.example.other", "com.example.new"});
-    EXPECT_TRUE(controller_.updatePackagesForUid(newState).isOk());
+    EXPECT_THAT(controller_.updatePackagesForUid(newState), BinderStatusMatcher::isOk());
 
     // Verify update
-    UNWRAP_EQ(controller_.getPackagesForUid(10000),
-              makeVector("com.example.other", "com.example.new"));
+    EXPECT_THAT(controller_.getPackagesForUid(10000),
+                IsOkAnd(ElementsAre("com.example.other", "com.example.new")));
 }
 
 TEST_F(NativePermissionControllerTest, updatePackages_EmptyRemovesEntry) {
@@ -138,15 +133,14 @@
             createState(10000, {"com.example.app1"}),
     };
 
-    EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+    EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
 
     UidPackageState newState{};  // Empty package list
     newState.uid = 10000;
-    EXPECT_TRUE(controller_.updatePackagesForUid(newState).isOk());
+    EXPECT_THAT(controller_.updatePackagesForUid(newState), BinderStatusMatcher::isOk());
     // getPackages for unknown UID should error out
-    const auto res = controller_.getPackagesForUid(10000);
-    ASSERT_FALSE(res.has_value());
-    EXPECT_EQ(res.error(), ::android::BAD_VALUE);
+    EXPECT_THAT(controller_.getPackagesForUid(10000),
+                IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_ARGUMENT)));
 }
 
 TEST_F(NativePermissionControllerTest, validateUidPackagePair_ValidPair) {
@@ -154,9 +148,9 @@
             createState(10000, {"com.example.app1", "com.example.app2"}),
     };
 
-    EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+    EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
 
-    UNWRAP_EQ(controller_.validateUidPackagePair(10000, "com.example.app1"), true);
+    EXPECT_THAT(controller_.validateUidPackagePair(10000, "com.example.app1"), IsOkAnd(IsTrue()));
 }
 
 TEST_F(NativePermissionControllerTest, validateUidPackagePair_InvalidPackage) {
@@ -164,9 +158,9 @@
             createState(10000, {"com.example.app1", "com.example.app2"}),
     };
 
-    EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+    EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
 
-    UNWRAP_EQ(controller_.validateUidPackagePair(10000, "com.example.other"), false);
+    EXPECT_THAT(controller_.validateUidPackagePair(10000, "com.example.other"), IsOkAnd(IsFalse()));
 }
 
 TEST_F(NativePermissionControllerTest, validateUidPackagePair_UnknownUid) {
@@ -174,45 +168,44 @@
             createState(10000, {"com.example.app1", "com.example.app2"}),
     };
 
-    EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+    EXPECT_THAT(controller_.populatePackagesForUids(input), BinderStatusMatcher::isOk());
 
-    UNWRAP_EQ(controller_.validateUidPackagePair(12000, "any.package"), false);
+    EXPECT_THAT(controller_.validateUidPackagePair(12000, "any.package"), IsOkAnd(IsFalse()));
 }
 
 TEST_F(NativePermissionControllerTest, populatePermissionState_InvalidPermission) {
-    EXPECT_EQ(controller_.populatePermissionState(PermissionEnum::ENUM_SIZE, {}).exceptionCode(),
-              Status::EX_ILLEGAL_ARGUMENT);
-    EXPECT_EQ(controller_
-                      .populatePermissionState(
-                              static_cast<PermissionEnum>(
-                                      static_cast<int>(PermissionEnum::ENUM_SIZE) + 1),
-                              {})
-                      .exceptionCode(),
-              Status::EX_ILLEGAL_ARGUMENT);
+    EXPECT_THAT(controller_.populatePermissionState(PermissionEnum::ENUM_SIZE, {}),
+                BinderStatusMatcher::hasException(EX_ILLEGAL_ARGUMENT));
+    EXPECT_THAT(
+            controller_.populatePermissionState(
+                    static_cast<PermissionEnum>(static_cast<int>(PermissionEnum::ENUM_SIZE) + 1),
+                    {}),
+            BinderStatusMatcher::hasException(EX_ILLEGAL_ARGUMENT));
 }
 
 TEST_F(NativePermissionControllerTest, populatePermissionState_HoldsPermission) {
     // Unsorted
     std::vector<int> uids{3, 1, 2, 4, 5};
 
-    EXPECT_TRUE(
-            controller_.populatePermissionState(PermissionEnum::MODIFY_AUDIO_ROUTING, uids).isOk());
+    EXPECT_THAT(controller_.populatePermissionState(PermissionEnum::MODIFY_AUDIO_ROUTING, uids),
+                BinderStatusMatcher::isOk());
 
-    EXPECT_TRUE(*controller_.checkPermission(PermissionEnum::MODIFY_AUDIO_ROUTING, 3));
+    EXPECT_THAT(controller_.checkPermission(PermissionEnum::MODIFY_AUDIO_ROUTING, 3),
+                IsOkAnd(IsTrue()));
 }
 
 TEST_F(NativePermissionControllerTest, populatePermissionState_DoesNotHoldPermission) {
     // Unsorted
     std::vector<int> uids{3, 1, 2, 4, 5};
 
-    EXPECT_TRUE(
-            controller_.populatePermissionState(PermissionEnum::MODIFY_AUDIO_ROUTING, uids).isOk());
+    EXPECT_THAT(controller_.populatePermissionState(PermissionEnum::MODIFY_AUDIO_ROUTING, uids),
+                BinderStatusMatcher::isOk());
 
-    EXPECT_FALSE(*controller_.checkPermission(PermissionEnum::MODIFY_AUDIO_ROUTING, 6));
+    EXPECT_THAT(controller_.checkPermission(PermissionEnum::MODIFY_AUDIO_ROUTING, 6),
+                IsOkAnd(IsFalse()));
 }
 
 TEST_F(NativePermissionControllerTest, populatePermissionState_NotInitialized) {
-    const auto res = controller_.checkPermission(PermissionEnum::MODIFY_AUDIO_ROUTING, 3);
-    ASSERT_FALSE(res.has_value());
-    EXPECT_EQ(res.error(), ::android::NO_INIT);
+    EXPECT_THAT(controller_.checkPermission(PermissionEnum::MODIFY_AUDIO_ROUTING, 3),
+                IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_STATE)));
 }
diff --git a/services/audiopolicy/permission/tests/ValidatedAttributionSourceStateTest.cpp b/services/audiopolicy/permission/tests/ValidatedAttributionSourceStateTest.cpp
index efc318b..0dd8814 100644
--- a/services/audiopolicy/permission/tests/ValidatedAttributionSourceStateTest.cpp
+++ b/services/audiopolicy/permission/tests/ValidatedAttributionSourceStateTest.cpp
@@ -20,24 +20,35 @@
 #include <gtest/gtest.h>
 
 #include <android-base/expected.h>
+#include <error/ExpectedMatchers.h>
 #include <media/IPermissionProvider.h>
+#include "error/BinderStatusMatcher.h"
 
 using ::android::base::unexpected;
 using ::android::binder::Status;
+using ::android::binder::Status::EX_ILLEGAL_ARGUMENT;
+using ::android::binder::Status::EX_ILLEGAL_STATE;
+using ::android::binder::Status::EX_SECURITY;
 using ::android::content::AttributionSourceState;
-using ::android::error::Result;
+using ::android::error::BinderResult;
+using ::android::error::BinderStatusMatcher;
+using ::android::error::IsErrorAnd;
+using ::android::error::IsOkAnd;
 using ::com::android::media::permission::IPermissionProvider;
 using ::com::android::media::permission::PermissionEnum;
 using ::com::android::media::permission::ValidatedAttributionSourceState;
+
+using ::testing::Eq;
 using ::testing::Return;
 
 class MockPermissionProvider : public IPermissionProvider {
   public:
-    MOCK_METHOD(Result<std::vector<std::string>>, getPackagesForUid, (uid_t uid),
+    MOCK_METHOD(BinderResult<std::vector<std::string>>, getPackagesForUid, (uid_t uid),
                 (override, const));
-    MOCK_METHOD(Result<bool>, validateUidPackagePair, (uid_t uid, const std::string&),
+    MOCK_METHOD(BinderResult<bool>, validateUidPackagePair, (uid_t uid, const std::string&),
                 (override, const));
-    MOCK_METHOD(Result<bool>, checkPermission, (PermissionEnum perm, uid_t), (override, const));
+    MOCK_METHOD(BinderResult<bool>, checkPermission, (PermissionEnum perm, uid_t),
+                (override, const));
 };
 
 class ValidatedAttributionSourceStateTest : public ::testing::Test {
@@ -47,21 +58,14 @@
     const std::vector<std::string> mPackageList{"com.package1", "com.package2"};
 };
 
-#define UNWRAP_EQ(expr, desired_expr)                         \
-    do {                                                      \
-        auto tmp_ = (expr);                                   \
-        EXPECT_TRUE(tmp_.has_value());                        \
-        if (tmp_.has_value()) EXPECT_EQ(*tmp_, desired_expr); \
-    } while (0)
-
 TEST_F(ValidatedAttributionSourceStateTest, providedPackageValid) {
     const std::string package = "com.package1";
     EXPECT_CALL(mMockProvider, validateUidPackagePair(mUid, package)).WillOnce(Return(true));
     AttributionSourceState attr;
     attr.uid = mUid;
     attr.packageName = package;
-    UNWRAP_EQ(ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider),
-              attr);
+    EXPECT_THAT(ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider),
+                IsOkAnd(Eq(attr)));
 }
 
 TEST_F(ValidatedAttributionSourceStateTest, providedPackageInvalid) {
@@ -70,10 +74,8 @@
     AttributionSourceState attr;
     attr.uid = mUid;
     attr.packageName = package;
-    const auto res =
-            ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider);
-    ASSERT_FALSE(res.has_value());
-    EXPECT_EQ(res.error(), ::android::PERMISSION_DENIED);
+    EXPECT_THAT(ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider),
+                IsErrorAnd(BinderStatusMatcher::hasException(EX_SECURITY)));
 }
 
 TEST_F(ValidatedAttributionSourceStateTest, packageLookup_whenMissingPackage) {
@@ -83,8 +85,8 @@
     AttributionSourceState expectedAttr;
     expectedAttr.uid = mUid;
     expectedAttr.packageName = "com.package1";
-    UNWRAP_EQ(ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider),
-              expectedAttr);
+    EXPECT_THAT(ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider),
+                IsOkAnd(Eq(expectedAttr)));
 }
 
 TEST_F(ValidatedAttributionSourceStateTest, packageLookup_whenEmptyPackage) {
@@ -95,33 +97,29 @@
     AttributionSourceState expectedAttr;
     expectedAttr.uid = mUid;
     expectedAttr.packageName = "com.package1";
-    UNWRAP_EQ(ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider),
-              expectedAttr);
+    EXPECT_THAT(ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider),
+                IsOkAnd(Eq(expectedAttr)));
 }
 
 TEST_F(ValidatedAttributionSourceStateTest, controllerNotInitialized) {
     EXPECT_CALL(mMockProvider, getPackagesForUid(mUid))
-            .WillOnce(Return(unexpected{::android::NO_INIT}));
+            .WillOnce(Return(unexpected{Status::fromExceptionCode(EX_ILLEGAL_STATE)}));
     AttributionSourceState attr;
     attr.uid = mUid;
     attr.packageName = std::string{};
     AttributionSourceState expectedAttr;
     expectedAttr.uid = mUid;
     expectedAttr.packageName = "com.package1";
-    const auto res =
-            ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider);
-    ASSERT_FALSE(res.has_value());
-    EXPECT_EQ(res.error(), ::android::NO_INIT);
+    EXPECT_THAT(ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider),
+                IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_STATE)));
 }
 
 TEST_F(ValidatedAttributionSourceStateTest, uidNotFound) {
     EXPECT_CALL(mMockProvider, getPackagesForUid(mUid))
-            .WillOnce(Return(unexpected{::android::BAD_VALUE}));
+            .WillOnce(Return(unexpected{Status::fromExceptionCode(EX_ILLEGAL_ARGUMENT)}));
     AttributionSourceState attr;
     attr.uid = mUid;
     attr.packageName = std::string{};
-    const auto res =
-            ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider);
-    ASSERT_FALSE(res.has_value());
-    EXPECT_EQ(res.error(), ::android::BAD_VALUE);
+    EXPECT_THAT(ValidatedAttributionSourceState::createFromTrustedUidNoPackage(attr, mMockProvider),
+                IsErrorAnd(BinderStatusMatcher::hasException(EX_ILLEGAL_ARGUMENT)));
 }