Loading camera/ndk/include/camera/NdkCameraMetadataTags.h +22 −16 Original line number Diff line number Diff line Loading @@ -2428,27 +2428,27 @@ typedef enum acamera_metadata_tag { * </ul></p> * * <p>Flash strength level to use in capture mode i.e. when the applications control * flash with either SINGLE or TORCH mode.</p> * flash with either <code>SINGLE</code> or <code>TORCH</code> mode.</p> * <p>Use ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL and * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL to check whether the device supports * flash strength control or not. * If the values of android.flash.info.singleStrengthMaxLevel and * If the values of ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL and * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL are greater than 1, * then the device supports manual flash strength control.</p> * <p>If the ACAMERA_FLASH_MODE <code>==</code> TORCH the value must be >= 1 * <p>If the ACAMERA_FLASH_MODE <code>==</code> <code>TORCH</code> the value must be >= 1 * and <= ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL. * If the application doesn't set the key and * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL > 1, * then the flash will be fired at the default level set by HAL in * ACAMERA_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL. * If the ACAMERA_FLASH_MODE <code>==</code> SINGLE, then the value must be >= 1 * If the ACAMERA_FLASH_MODE <code>==</code> <code>SINGLE</code>, then the value must be >= 1 * and <= ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL. * If the application does not set this key and * ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL > 1, * then the flash will be fired at the default level set by HAL * in ACAMERA_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL. * If ACAMERA_CONTROL_AE_MODE is set to any of ON_AUTO_FLASH, ON_ALWAYS_FLASH, * ON_AUTO_FLASH_REDEYE, ON_EXTERNAL_FLASH values, then the strengthLevel will be ignored.</p> * If ACAMERA_CONTROL_AE_MODE is set to any of <code>ON_AUTO_FLASH</code>, <code>ON_ALWAYS_FLASH</code>, * <code>ON_AUTO_FLASH_REDEYE</code>, <code>ON_EXTERNAL_FLASH</code> values, then the strengthLevel will be ignored.</p> * * @see ACAMERA_CONTROL_AE_MODE * @see ACAMERA_FLASH_MODE Loading @@ -2460,7 +2460,7 @@ typedef enum acamera_metadata_tag { ACAMERA_FLASH_STRENGTH_LEVEL = // int32 ACAMERA_FLASH_START + 6, /** * <p>Maximum flash brightness level for manual flash control in SINGLE mode.</p> * <p>Maximum flash brightness level for manual flash control in <code>SINGLE</code> mode.</p> * * <p>Type: int32</p> * Loading @@ -2470,7 +2470,7 @@ typedef enum acamera_metadata_tag { * </ul></p> * * <p>Maximum flash brightness level in camera capture mode and * ACAMERA_FLASH_MODE set to SINGLE. * ACAMERA_FLASH_MODE set to <code>SINGLE</code>. * Value will be > 1 if the manual flash strength control feature is supported, * otherwise the value will be equal to 1. * Note that this level is just a number of supported levels (the granularity of control). Loading @@ -2481,7 +2481,7 @@ typedef enum acamera_metadata_tag { ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL = // int32 ACAMERA_FLASH_START + 7, /** * <p>Default flash brightness level for manual flash control in SINGLE mode.</p> * <p>Default flash brightness level for manual flash control in <code>SINGLE</code> mode.</p> * * <p>Type: int32</p> * Loading @@ -2500,7 +2500,7 @@ typedef enum acamera_metadata_tag { ACAMERA_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL = // int32 ACAMERA_FLASH_START + 8, /** * <p>Maximum flash brightness level for manual flash control in TORCH mode</p> * <p>Maximum flash brightness level for manual flash control in <code>TORCH</code> mode</p> * * <p>Type: int32</p> * Loading @@ -2510,7 +2510,7 @@ typedef enum acamera_metadata_tag { * </ul></p> * * <p>Maximum flash brightness level in camera capture mode and * ACAMERA_FLASH_MODE set to TORCH. * ACAMERA_FLASH_MODE set to <code>TORCH</code>. * Value will be > 1 if the manual flash strength control feature is supported, * otherwise the value will be equal to 1.</p> * <p>Note that this level is just a number of supported levels(the granularity of control). Loading @@ -2527,7 +2527,7 @@ typedef enum acamera_metadata_tag { ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL = // int32 ACAMERA_FLASH_START + 9, /** * <p>Default flash brightness level for manual flash control in TORCH mode</p> * <p>Default flash brightness level for manual flash control in <code>TORCH</code> mode</p> * * <p>Type: int32</p> * Loading Loading @@ -5875,10 +5875,16 @@ typedef enum acamera_metadata_tag { * <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li> * </ul></p> * * <p>If TRUE, all images produced by the camera device in the RAW image formats will * have lens shading correction already applied to it. If FALSE, the images will * not be adjusted for lens shading correction. * See android.request.maxNumOutputRaw for a list of RAW image formats.</p> * <p>If <code>true</code>, all images produced by the camera device in the <code>RAW</code> image formats will have * at least some lens shading correction already applied to it. If <code>false</code>, the images will * not be adjusted for lens shading correction. See android.request.maxNumOutputRaw for a * list of RAW image formats.</p> * <p>When <code>true</code>, the <code>lensShadingCorrectionMap</code> key may still have values greater than 1.0, * and those will need to be applied to any captured RAW frames for them to match the shading * correction of processed buffers such as <code>YUV</code> or <code>JPEG</code> images. This may occur, for * example, when some basic fixed lens shading correction is applied by hardware to RAW data, * and additional correction is done dynamically in the camera processing pipeline after * demosaicing.</p> * <p>This key will be <code>null</code> for all devices do not report this information. * Devices with RAW capability will always report this information in this key.</p> */ Loading media/liberror/include/error/BinderResult.h 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * 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()}; } media/liberror/include/error/BinderStatusMatcher.h 0 → 100644 +60 −0 Original line number Diff line number Diff line /* * 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 media/liberror/include/error/ExpectedMatchers.h 0 → 100644 +136 −0 Original line number Diff line number Diff line /* * 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 services/audiopolicy/permission/NativePermissionController.cpp +25 −10 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -103,23 +103,31 @@ Status NativePermissionController::populatePermissionState(PermissionEnum perm, // -- 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); Loading @@ -127,20 +135,27 @@ Result<bool> NativePermissionController::validateUidPackagePair( 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"); } } Loading Loading
camera/ndk/include/camera/NdkCameraMetadataTags.h +22 −16 Original line number Diff line number Diff line Loading @@ -2428,27 +2428,27 @@ typedef enum acamera_metadata_tag { * </ul></p> * * <p>Flash strength level to use in capture mode i.e. when the applications control * flash with either SINGLE or TORCH mode.</p> * flash with either <code>SINGLE</code> or <code>TORCH</code> mode.</p> * <p>Use ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL and * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL to check whether the device supports * flash strength control or not. * If the values of android.flash.info.singleStrengthMaxLevel and * If the values of ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL and * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL are greater than 1, * then the device supports manual flash strength control.</p> * <p>If the ACAMERA_FLASH_MODE <code>==</code> TORCH the value must be >= 1 * <p>If the ACAMERA_FLASH_MODE <code>==</code> <code>TORCH</code> the value must be >= 1 * and <= ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL. * If the application doesn't set the key and * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL > 1, * then the flash will be fired at the default level set by HAL in * ACAMERA_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL. * If the ACAMERA_FLASH_MODE <code>==</code> SINGLE, then the value must be >= 1 * If the ACAMERA_FLASH_MODE <code>==</code> <code>SINGLE</code>, then the value must be >= 1 * and <= ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL. * If the application does not set this key and * ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL > 1, * then the flash will be fired at the default level set by HAL * in ACAMERA_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL. * If ACAMERA_CONTROL_AE_MODE is set to any of ON_AUTO_FLASH, ON_ALWAYS_FLASH, * ON_AUTO_FLASH_REDEYE, ON_EXTERNAL_FLASH values, then the strengthLevel will be ignored.</p> * If ACAMERA_CONTROL_AE_MODE is set to any of <code>ON_AUTO_FLASH</code>, <code>ON_ALWAYS_FLASH</code>, * <code>ON_AUTO_FLASH_REDEYE</code>, <code>ON_EXTERNAL_FLASH</code> values, then the strengthLevel will be ignored.</p> * * @see ACAMERA_CONTROL_AE_MODE * @see ACAMERA_FLASH_MODE Loading @@ -2460,7 +2460,7 @@ typedef enum acamera_metadata_tag { ACAMERA_FLASH_STRENGTH_LEVEL = // int32 ACAMERA_FLASH_START + 6, /** * <p>Maximum flash brightness level for manual flash control in SINGLE mode.</p> * <p>Maximum flash brightness level for manual flash control in <code>SINGLE</code> mode.</p> * * <p>Type: int32</p> * Loading @@ -2470,7 +2470,7 @@ typedef enum acamera_metadata_tag { * </ul></p> * * <p>Maximum flash brightness level in camera capture mode and * ACAMERA_FLASH_MODE set to SINGLE. * ACAMERA_FLASH_MODE set to <code>SINGLE</code>. * Value will be > 1 if the manual flash strength control feature is supported, * otherwise the value will be equal to 1. * Note that this level is just a number of supported levels (the granularity of control). Loading @@ -2481,7 +2481,7 @@ typedef enum acamera_metadata_tag { ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL = // int32 ACAMERA_FLASH_START + 7, /** * <p>Default flash brightness level for manual flash control in SINGLE mode.</p> * <p>Default flash brightness level for manual flash control in <code>SINGLE</code> mode.</p> * * <p>Type: int32</p> * Loading @@ -2500,7 +2500,7 @@ typedef enum acamera_metadata_tag { ACAMERA_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL = // int32 ACAMERA_FLASH_START + 8, /** * <p>Maximum flash brightness level for manual flash control in TORCH mode</p> * <p>Maximum flash brightness level for manual flash control in <code>TORCH</code> mode</p> * * <p>Type: int32</p> * Loading @@ -2510,7 +2510,7 @@ typedef enum acamera_metadata_tag { * </ul></p> * * <p>Maximum flash brightness level in camera capture mode and * ACAMERA_FLASH_MODE set to TORCH. * ACAMERA_FLASH_MODE set to <code>TORCH</code>. * Value will be > 1 if the manual flash strength control feature is supported, * otherwise the value will be equal to 1.</p> * <p>Note that this level is just a number of supported levels(the granularity of control). Loading @@ -2527,7 +2527,7 @@ typedef enum acamera_metadata_tag { ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL = // int32 ACAMERA_FLASH_START + 9, /** * <p>Default flash brightness level for manual flash control in TORCH mode</p> * <p>Default flash brightness level for manual flash control in <code>TORCH</code> mode</p> * * <p>Type: int32</p> * Loading Loading @@ -5875,10 +5875,16 @@ typedef enum acamera_metadata_tag { * <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li> * </ul></p> * * <p>If TRUE, all images produced by the camera device in the RAW image formats will * have lens shading correction already applied to it. If FALSE, the images will * not be adjusted for lens shading correction. * See android.request.maxNumOutputRaw for a list of RAW image formats.</p> * <p>If <code>true</code>, all images produced by the camera device in the <code>RAW</code> image formats will have * at least some lens shading correction already applied to it. If <code>false</code>, the images will * not be adjusted for lens shading correction. See android.request.maxNumOutputRaw for a * list of RAW image formats.</p> * <p>When <code>true</code>, the <code>lensShadingCorrectionMap</code> key may still have values greater than 1.0, * and those will need to be applied to any captured RAW frames for them to match the shading * correction of processed buffers such as <code>YUV</code> or <code>JPEG</code> images. This may occur, for * example, when some basic fixed lens shading correction is applied by hardware to RAW data, * and additional correction is done dynamically in the camera processing pipeline after * demosaicing.</p> * <p>This key will be <code>null</code> for all devices do not report this information. * Devices with RAW capability will always report this information in this key.</p> */ Loading
media/liberror/include/error/BinderResult.h 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * 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()}; }
media/liberror/include/error/BinderStatusMatcher.h 0 → 100644 +60 −0 Original line number Diff line number Diff line /* * 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
media/liberror/include/error/ExpectedMatchers.h 0 → 100644 +136 −0 Original line number Diff line number Diff line /* * 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
services/audiopolicy/permission/NativePermissionController.cpp +25 −10 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -103,23 +103,31 @@ Status NativePermissionController::populatePermissionState(PermissionEnum perm, // -- 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); Loading @@ -127,20 +135,27 @@ Result<bool> NativePermissionController::validateUidPackagePair( 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"); } } Loading