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)));
}