Merge changes from topic "cherrypicker-L89600000960032981:N30900001359241375" into udc-dev
* changes:
Skip setting the state for paused binder thread invocations in waitUntilStateThenRelock
Revert "Add mInterfaceLock back to Camera3Device methods called by RequestThread."
diff --git a/media/audioaidlconversion/AidlConversionNdkCpp.cpp b/media/audioaidlconversion/AidlConversionNdkCpp.cpp
new file mode 100644
index 0000000..36f6128
--- /dev/null
+++ b/media/audioaidlconversion/AidlConversionNdkCpp.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <type_traits>
+
+#define LOG_TAG "AidlConversionNdkCpp"
+#include <utils/Log.h>
+
+#include <android-base/expected.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_enums.h>
+#include <android/binder_parcel.h>
+#include <binder/Enums.h>
+#include <media/AidlConversionNdkCpp.h>
+#include <media/AidlConversionUtil.h>
+
+using aidl::android::aidl_utils::statusTFromBinderStatusT;
+
+namespace android {
+
+namespace {
+
+// cpp2ndk and ndk2cpp are universal converters which work for any type,
+// however they are not the most efficient way to convert due to extra
+// marshaling / unmarshaling step.
+
+template<typename NdkType, typename CppType>
+ConversionResult<NdkType> cpp2ndk(const CppType& cpp) {
+ Parcel cppParcel;
+ RETURN_IF_ERROR(cpp.writeToParcel(&cppParcel));
+ ::ndk::ScopedAParcel ndkParcel(AParcel_create());
+ const int32_t ndkParcelBegin = AParcel_getDataPosition(ndkParcel.get());
+ RETURN_IF_ERROR(statusTFromBinderStatusT(AParcel_unmarshal(
+ ndkParcel.get(), cppParcel.data(), cppParcel.dataSize())));
+ RETURN_IF_ERROR(statusTFromBinderStatusT(AParcel_setDataPosition(
+ ndkParcel.get(), ndkParcelBegin)));
+ NdkType ndk;
+ RETURN_IF_ERROR(statusTFromBinderStatusT(ndk.readFromParcel(ndkParcel.get())));
+ return ndk;
+}
+
+template<typename CppType, typename NdkType>
+ConversionResult<CppType> ndk2cpp(const NdkType& ndk) {
+ ::ndk::ScopedAParcel ndkParcel(AParcel_create());
+ RETURN_IF_ERROR(statusTFromBinderStatusT(ndk.writeToParcel(ndkParcel.get())));
+ const int32_t ndkParcelDataSize = AParcel_getDataSize(ndkParcel.get());
+ if (ndkParcelDataSize < 0) {
+ return base::unexpected(BAD_VALUE);
+ }
+ // Parcel does not expose its data in a mutable form, we have to use an intermediate buffer.
+ std::vector<uint8_t> parcelData(static_cast<size_t>(ndkParcelDataSize));
+ RETURN_IF_ERROR(statusTFromBinderStatusT(AParcel_marshal(
+ ndkParcel.get(), parcelData.data(), 0, ndkParcelDataSize)));
+ Parcel cppParcel;
+ RETURN_IF_ERROR(cppParcel.setData(parcelData.data(), parcelData.size()));
+ CppType cpp;
+ RETURN_IF_ERROR(cpp.readFromParcel(&cppParcel));
+ return cpp;
+}
+
+// cpp2ndk_Enum and ndk2cpp_Enum are more efficient implementations specifically for enums.
+
+template<typename OutEnum, typename OutEnumRange, typename InEnum>
+ ConversionResult<OutEnum> convertEnum(const OutEnumRange& range, InEnum e) {
+ using InIntType = std::underlying_type_t<InEnum>;
+ static_assert(std::is_same_v<InIntType, std::underlying_type_t<OutEnum>>);
+
+ InIntType inEnumIndex = static_cast<InIntType>(e);
+ OutEnum outEnum = static_cast<OutEnum>(inEnumIndex);
+ if (std::find(range.begin(), range.end(), outEnum) == range.end()) {
+ return base::unexpected(BAD_VALUE);
+ }
+ return outEnum;
+}
+
+template<typename NdkEnum, typename CppEnum>
+ ConversionResult<NdkEnum> cpp2ndk_Enum(CppEnum cpp) {
+ return convertEnum<NdkEnum>(::ndk::enum_range<NdkEnum>(), cpp);
+}
+
+template<typename CppEnum, typename NdkEnum>
+ ConversionResult<CppEnum> ndk2cpp_Enum(NdkEnum ndk) {
+ return convertEnum<CppEnum>(enum_range<CppEnum>(), ndk);
+}
+
+} // namespace
+
+#define GENERATE_CONVERTERS(packageName, className) \
+ ConversionResult<::aidl::packageName::className> cpp2ndk_##className( \
+ const ::packageName::className& cpp) { \
+ return cpp2ndk<::aidl::packageName::className>(cpp); \
+ } \
+ ConversionResult<::packageName::className> ndk2cpp_##className( \
+ const ::aidl::packageName::className& ndk) { \
+ return ndk2cpp<::packageName::className>(ndk); \
+ }
+
+#define GENERATE_ENUM_CONVERTERS(packageName, className) \
+ ConversionResult<::aidl::packageName::className> cpp2ndk_##className( \
+ const ::packageName::className& cpp) { \
+ return cpp2ndk_Enum<::aidl::packageName::className>(cpp); \
+ } \
+ ConversionResult<::packageName::className> ndk2cpp_##className( \
+ const ::aidl::packageName::className& ndk) { \
+ return ndk2cpp_Enum<::packageName::className>(ndk); \
+}
+
+GENERATE_CONVERTERS(android::media::audio::common, AudioFormatDescription);
+GENERATE_CONVERTERS(android::media::audio::common, AudioHalEngineConfig);
+GENERATE_CONVERTERS(android::media::audio::common, AudioMMapPolicyInfo);
+GENERATE_ENUM_CONVERTERS(android::media::audio::common, AudioMMapPolicyType);
+GENERATE_CONVERTERS(android::media::audio::common, AudioPort);
+
+} // namespace android
diff --git a/media/audioaidlconversion/Android.bp b/media/audioaidlconversion/Android.bp
index 1ec4849..d3a5755 100644
--- a/media/audioaidlconversion/Android.bp
+++ b/media/audioaidlconversion/Android.bp
@@ -212,3 +212,27 @@
],
min_sdk_version: "31", //AParcelableHolder has been introduced in 31
}
+
+/**
+ * Conversions between the NDK and CPP backends for common types.
+ */
+cc_library {
+ name: "libaudio_aidl_conversion_common_ndk_cpp",
+ srcs: [
+ "AidlConversionNdkCpp.cpp",
+ ],
+ defaults: [
+ "audio_aidl_conversion_common_default",
+ "audio_aidl_conversion_common_util_default",
+ "latest_android_media_audio_common_types_cpp_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libbase",
+ ],
+ cflags: [
+ "-DBACKEND_CPP_NDK",
+ ],
+ min_sdk_version: "33", //AParcel_unmarshal has been introduced in 33
+}
diff --git a/media/audioaidlconversion/TEST_MAPPING b/media/audioaidlconversion/TEST_MAPPING
index a0c9759..903b88a 100644
--- a/media/audioaidlconversion/TEST_MAPPING
+++ b/media/audioaidlconversion/TEST_MAPPING
@@ -1,7 +1,8 @@
{
"presubmit": [
{
- "name": "audio_aidl_ndk_conversion_tests"
+ "name": "audio_aidl_ndk_conversion_tests",
+ "name": "audio_aidl_ndk_cpp_conversion_tests"
}
]
}
diff --git a/media/audioaidlconversion/include/media/AidlConversionNdkCpp.h b/media/audioaidlconversion/include/media/AidlConversionNdkCpp.h
new file mode 100644
index 0000000..09f1c22
--- /dev/null
+++ b/media/audioaidlconversion/include/media/AidlConversionNdkCpp.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+/**
+ * Conversions between the NDK and CPP backends for common types.
+ */
+#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <aidl/android/media/audio/common/AudioMMapPolicyInfo.h>
+#include <aidl/android/media/audio/common/AudioMMapPolicyType.h>
+#include <aidl/android/media/audio/common/AudioPort.h>
+#include <android/media/audio/common/AudioFormatDescription.h>
+#include <android/media/audio/common/AudioHalEngineConfig.h>
+#include <android/media/audio/common/AudioMMapPolicyInfo.h>
+#include <android/media/audio/common/AudioMMapPolicyType.h>
+#include <android/media/audio/common/AudioPort.h>
+#include <media/AidlConversionUtil.h>
+
+namespace android {
+
+#define DECLARE_CONVERTERS(packageName, className) \
+ ConversionResult<::aidl::packageName::className> \
+ cpp2ndk_##className(const ::packageName::className& cpp); \
+ ConversionResult<::packageName::className> \
+ ndk2cpp_##className(const ::aidl::packageName::className& ndk);
+
+DECLARE_CONVERTERS(android::media::audio::common, AudioFormatDescription);
+DECLARE_CONVERTERS(android::media::audio::common, AudioHalEngineConfig);
+DECLARE_CONVERTERS(android::media::audio::common, AudioMMapPolicyInfo);
+DECLARE_CONVERTERS(android::media::audio::common, AudioMMapPolicyType);
+DECLARE_CONVERTERS(android::media::audio::common, AudioPort);
+
+#undef DECLARE_CONVERTERS
+
+} // namespace android
diff --git a/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h b/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h
index b179cbb..f49f681 100644
--- a/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h
+++ b/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h
@@ -389,6 +389,10 @@
?: statusTFromExceptionCode(status.getExceptionCode()); // a service-side error with a
// standard Java exception (fromExceptionCode)
}
+
+static inline ::android::status_t statusTFromBinderStatusT(binder_status_t status) {
+ return statusTFromBinderStatus(::ndk::ScopedAStatus::fromStatus(status));
+}
#endif
/**
diff --git a/media/audioaidlconversion/tests/Android.bp b/media/audioaidlconversion/tests/Android.bp
index de7c8a2..88b2cc9 100644
--- a/media/audioaidlconversion/tests/Android.bp
+++ b/media/audioaidlconversion/tests/Android.bp
@@ -44,3 +44,27 @@
"-DBACKEND_NDK",
],
}
+
+cc_test {
+ name: "audio_aidl_ndk_cpp_conversion_tests",
+
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_static",
+ "latest_android_media_audio_common_types_ndk_static",
+ "libaudio_aidl_conversion_tests_defaults",
+ ],
+ srcs: ["audio_aidl_ndk_cpp_conversion_tests.cpp"],
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: [
+ "libaudio_aidl_conversion_common_ndk_cpp",
+ ],
+ cflags: [
+ "-DBACKEND_CPP_NDK",
+ ],
+}
diff --git a/media/audioaidlconversion/tests/audio_aidl_ndk_cpp_conversion_tests.cpp b/media/audioaidlconversion/tests/audio_aidl_ndk_cpp_conversion_tests.cpp
new file mode 100644
index 0000000..735a14b
--- /dev/null
+++ b/media/audioaidlconversion/tests/audio_aidl_ndk_cpp_conversion_tests.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include <type_traits>
+
+#include <gtest/gtest.h>
+
+#include <media/AidlConversionNdkCpp.h>
+
+namespace {
+template<typename> struct mf_traits {};
+template<class T, class U> struct mf_traits<U T::*> {
+ using member_type = U;
+};
+} // namespace
+
+// Provide value printers for types generated from AIDL
+// They need to be in the same namespace as the types we intend to print
+#define DEFINE_PRINTING_TEMPLATES()
+ template <typename P> \
+ std::enable_if_t<std::is_function_v<typename mf_traits<decltype(&P::toString)>::member_type>, \
+ std::ostream&> operator<<(std::ostream& os, const P& p) { \
+ return os << p.toString(); \
+ } \
+ template <typename E> \
+ std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, const E& e) { \
+ return os << toString(e); \
+ }
+
+namespace aidl::android::media::audio::common {
+DEFINE_PRINTING_TEMPLATES();
+} // namespace aidl::android::media::audio::common
+namespace android::hardware::audio::common {
+DEFINE_PRINTING_TEMPLATES();
+} // namespace android::hardware::audio::common
+#undef DEFINE_PRINTING_TEMPLATES
+
+using namespace android;
+
+namespace {
+
+using namespace ::aidl::android::media::audio::common;
+
+AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
+ AudioFormatDescription result;
+ result.type = type;
+ return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(PcmType pcm) {
+ auto result = make_AudioFormatDescription(AudioFormatType::PCM);
+ result.pcm = pcm;
+ return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(const std::string& encoding) {
+ AudioFormatDescription result;
+ result.encoding = encoding;
+ return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(PcmType transport, const std::string& encoding) {
+ auto result = make_AudioFormatDescription(encoding);
+ result.pcm = transport;
+ return result;
+}
+
+AudioFormatDescription make_AFD_Default() {
+ return AudioFormatDescription{};
+}
+
+AudioFormatDescription make_AFD_Invalid() {
+ return make_AudioFormatDescription(AudioFormatType::SYS_RESERVED_INVALID);
+}
+
+AudioFormatDescription make_AFD_Pcm16Bit() {
+ return make_AudioFormatDescription(PcmType::INT_16_BIT);
+}
+
+AudioFormatDescription make_AFD_Bitstream() {
+ return make_AudioFormatDescription("example");
+}
+
+AudioFormatDescription make_AFD_Encap() {
+ return make_AudioFormatDescription(PcmType::INT_16_BIT, "example.encap");
+}
+
+AudioFormatDescription make_AFD_Encap_with_Enc() {
+ auto afd = make_AFD_Encap();
+ afd.encoding += "+example";
+ return afd;
+}
+
+} // namespace
+
+// There is no reason to write test for every type which gets converted via parcelable
+// since the conversion code is all the same.
+
+class AudioFormatDescriptionRoundTripTest :
+ public testing::TestWithParam<::aidl::android::media::audio::common::AudioFormatDescription>
+{
+};
+TEST_P(AudioFormatDescriptionRoundTripTest, Ndk2Cpp2Ndk) {
+ const auto& initial = GetParam();
+ auto conv = ndk2cpp_AudioFormatDescription(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = cpp2ndk_AudioFormatDescription(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+INSTANTIATE_TEST_SUITE_P(AudioFormatDescriptionRoundTrip, AudioFormatDescriptionRoundTripTest,
+ testing::Values(make_AFD_Invalid(), make_AFD_Default(), make_AFD_Pcm16Bit(),
+ make_AFD_Bitstream(), make_AFD_Encap(), make_AFD_Encap_with_Enc()));
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 8aed623..77296a4 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -726,24 +726,6 @@
}
}
-void C2SoftGav1Dec::setError(const std::unique_ptr<C2Work> &work, c2_status_t error) {
- mSignalledError = true;
- work->result = error;
- work->workletsProcessed = 1u;
-}
-
-bool C2SoftGav1Dec::allocTmpFrameBuffer(size_t size) {
- if (size > mTmpFrameBufferSize) {
- mTmpFrameBuffer = std::make_unique<uint16_t[]>(size);
- if (mTmpFrameBuffer == nullptr) {
- mTmpFrameBufferSize = 0;
- return false;
- }
- mTmpFrameBufferSize = size;
- }
- return true;
-}
-
bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
const std::unique_ptr<C2Work> &work) {
if (!(work && pool)) return false;
@@ -790,6 +772,16 @@
getHDRStaticParams(buffer, work);
getHDR10PlusInfoData(buffer, work);
+ if (buffer->bitdepth == 10 &&
+ !(buffer->image_format == libgav1::kImageFormatYuv420 ||
+ buffer->image_format == libgav1::kImageFormatMonochrome400)) {
+ ALOGE("image_format %d not supported for 10bit", buffer->image_format);
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return false;
+ }
+
const bool isMonochrome =
buffer->image_format == libgav1::kImageFormatMonochrome400;
@@ -862,6 +854,9 @@
uint8_t *dstY = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
uint8_t *dstU = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_U]);
uint8_t *dstV = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_V]);
+ size_t srcYStride = buffer->stride[0];
+ size_t srcUStride = buffer->stride[1];
+ size_t srcVStride = buffer->stride[2];
C2PlanarLayout layout = wView.layout();
size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
@@ -872,88 +867,26 @@
const uint16_t *srcY = (const uint16_t *)buffer->plane[0];
const uint16_t *srcU = (const uint16_t *)buffer->plane[1];
const uint16_t *srcV = (const uint16_t *)buffer->plane[2];
- size_t srcYStride = buffer->stride[0] / 2;
- size_t srcUStride = buffer->stride[1] / 2;
- size_t srcVStride = buffer->stride[2] / 2;
if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
convertYUV420Planar16ToY410OrRGBA1010102(
- (uint32_t *)dstY, srcY, srcU, srcV, srcYStride,
- srcUStride, srcVStride,
+ (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
+ srcUStride / 2, srcVStride / 2,
dstYStride / sizeof(uint32_t), mWidth, mHeight,
std::static_pointer_cast<const C2ColorAspectsStruct>(codedColorAspects));
} else if (format == HAL_PIXEL_FORMAT_YCBCR_P010) {
- dstYStride /= 2;
- dstUStride /= 2;
- dstVStride /= 2;
- if (buffer->image_format == libgav1::kImageFormatYuv444 ||
- buffer->image_format == libgav1::kImageFormatYuv422) {
- // TODO(https://crbug.com/libyuv/952): replace this block with libyuv::I410ToP010 and
- // libyuv::I210ToP010 when they are available.
- // Note it may be safe to alias dstY in I010ToP010, but the libyuv API doesn't make any
- // guarantees.
- const size_t tmpSize = dstYStride * mHeight + dstUStride * align(mHeight, 2);
- if (!allocTmpFrameBuffer(tmpSize)) {
- ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
- setError(work, C2_NO_MEMORY);
- return false;
- }
- uint16_t *const tmpY = mTmpFrameBuffer.get();
- uint16_t *const tmpU = tmpY + dstYStride * mHeight;
- uint16_t *const tmpV = tmpU + dstUStride * align(mHeight, 2) / 2;
- if (buffer->image_format == libgav1::kImageFormatYuv444) {
- libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
- tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride,
- mWidth, mHeight);
- } else {
- libyuv::I210ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
- tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride,
- mWidth, mHeight);
- }
- libyuv::I010ToP010(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstVStride,
- (uint16_t*)dstY, dstYStride, (uint16_t*)dstU, dstUStride,
- mWidth, mHeight);
- } else {
- convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV,
- srcYStride, srcUStride, srcVStride, dstYStride,
- dstUStride, mWidth, mHeight, isMonochrome);
- }
+ convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV,
+ srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / 2,
+ dstUStride / 2, mWidth, mHeight, isMonochrome);
} else {
- if (buffer->image_format == libgav1::kImageFormatYuv444) {
- // TODO(https://crbug.com/libyuv/950): replace this block with libyuv::I410ToI420 when
- // it's available.
- const size_t tmpSize = dstYStride * mHeight + dstUStride * align(mHeight, 2);
- if (!allocTmpFrameBuffer(tmpSize)) {
- ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
- setError(work, C2_NO_MEMORY);
- return false;
- }
- uint16_t *const tmpY = mTmpFrameBuffer.get();
- uint16_t *const tmpU = tmpY + dstYStride * mHeight;
- uint16_t *const tmpV = tmpU + dstUStride * align(mHeight, 2) / 2;
- libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
- tmpY, dstYStride, tmpU, dstUStride, tmpV, dstVStride,
- mWidth, mHeight);
- libyuv::I010ToI420(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride,
- dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
- mWidth, mHeight);
- } else if (buffer->image_format == libgav1::kImageFormatYuv422) {
- libyuv::I210ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
- dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
- mWidth, mHeight);
- } else {
- convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2,
- srcUStride / 2, srcVStride / 2, dstYStride, dstUStride,
- mWidth, mHeight, isMonochrome);
- }
+ convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2,
+ srcUStride / 2, srcVStride / 2, dstYStride, dstUStride, mWidth,
+ mHeight, isMonochrome);
}
} else {
const uint8_t *srcY = (const uint8_t *)buffer->plane[0];
const uint8_t *srcU = (const uint8_t *)buffer->plane[1];
const uint8_t *srcV = (const uint8_t *)buffer->plane[2];
- size_t srcYStride = buffer->stride[0];
- size_t srcUStride = buffer->stride[1];
- size_t srcVStride = buffer->stride[2];
if (buffer->image_format == libgav1::kImageFormatYuv444) {
libyuv::I444ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index c3b27ea..f0e14d7 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -19,8 +19,6 @@
#include <inttypes.h>
-#include <memory>
-
#include <media/stagefright/foundation/ColorUtils.h>
#include <SimpleC2Component.h>
@@ -62,9 +60,6 @@
uint32_t mHeight;
bool mSignalledOutputEos;
bool mSignalledError;
- // Used during 10-bit I444/I422 to 10-bit P010 & 8-bit I420 conversions.
- std::unique_ptr<uint16_t[]> mTmpFrameBuffer;
- size_t mTmpFrameBufferSize = 0;
C2StreamHdrStaticMetadataInfo::output mHdrStaticMetadataInfo;
std::unique_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfo = nullptr;
@@ -102,9 +97,6 @@
void destroyDecoder();
void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
const std::shared_ptr<C2GraphicBlock>& block);
- // Sets |work->result| and mSignalledError. Returns false.
- void setError(const std::unique_ptr<C2Work> &work, c2_status_t error);
- bool allocTmpFrameBuffer(size_t size);
bool outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
const std::unique_ptr<C2Work>& work);
c2_status_t drainInternal(uint32_t drainMode,
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.cpp b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
index c606d6f..9297520 100644
--- a/media/codec2/sfplugin/utils/Codec2Mapper.cpp
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
@@ -119,8 +119,8 @@
{ C2Color::PRIMARIES_BT601_525, ColorAspects::PrimariesBT601_6_525 },
{ C2Color::PRIMARIES_GENERIC_FILM, ColorAspects::PrimariesGenericFilm },
{ C2Color::PRIMARIES_BT2020, ColorAspects::PrimariesBT2020 },
-// { C2Color::PRIMARIES_RP431, ColorAspects::Primaries... },
-// { C2Color::PRIMARIES_EG432, ColorAspects::Primaries... },
+ { C2Color::PRIMARIES_RP431, ColorAspects::PrimariesRP431 },
+ { C2Color::PRIMARIES_EG432, ColorAspects::PrimariesEG432 },
// { C2Color::PRIMARIES_EBU3213, ColorAspects::Primaries... },
{ C2Color::PRIMARIES_OTHER, ColorAspects::PrimariesOther },
};
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index fc8ba9e..67ee42e 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -132,10 +132,11 @@
AAudioConvert_contentTypeToInternal(builder.getContentType());
const audio_usage_t usage =
AAudioConvert_usageToInternal(builder.getUsage());
- const audio_flags_mask_t attributesFlags =
- AAudioConvert_allowCapturePolicyToAudioFlagsMask(builder.getAllowedCapturePolicy(),
- builder.getSpatializationBehavior(),
- builder.isContentSpatialized());
+ const audio_flags_mask_t attributesFlags = AAudio_computeAudioFlagsMask(
+ builder.getAllowedCapturePolicy(),
+ builder.getSpatializationBehavior(),
+ builder.isContentSpatialized(),
+ flags);
const audio_attributes_t attributes = {
.content_type = contentType,
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 8920e53..e8324a8 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -255,10 +255,11 @@
return (audio_source_t) preset; // same value
}
-audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
+audio_flags_mask_t AAudio_computeAudioFlagsMask(
aaudio_allowed_capture_policy_t policy,
aaudio_spatialization_behavior_t spatializationBehavior,
- bool isContentSpatialized) {
+ bool isContentSpatialized,
+ audio_output_flags_t outputFlags) {
audio_flags_mask_t flagsMask = AUDIO_FLAG_NONE;
switch (policy) {
case AAUDIO_UNSPECIFIED:
@@ -295,6 +296,15 @@
flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_CONTENT_SPATIALIZED);
}
+ if ((outputFlags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
+ flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_HW_AV_SYNC);
+ }
+ if ((outputFlags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
+ flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_LOW_LATENCY);
+ } else if ((outputFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
+ flagsMask = static_cast<audio_flags_mask_t>(flagsMask | AUDIO_FLAG_DEEP_BUFFER);
+ }
+
return flagsMask;
}
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index d8e5b00..d44bbab 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -94,10 +94,11 @@
* That is done somewhere else.
* @return internal audio flags mask
*/
-audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
+audio_flags_mask_t AAudio_computeAudioFlagsMask(
aaudio_allowed_capture_policy_t policy,
aaudio_spatialization_behavior_t spatializationBehavior,
- bool isContentSpatialized);
+ bool isContentSpatialized,
+ audio_output_flags_t outputFlags);
audio_flags_mask_t AAudioConvert_privacySensitiveToAudioFlagsMask(
bool privacySensitive);
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 2bbfb76..d5bbb52 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -300,11 +300,14 @@
"aidl/android/media/AudioPortRole.aidl",
"aidl/android/media/AudioPortType.aidl",
"aidl/android/media/AudioProfileSys.aidl",
+ "aidl/android/media/AudioRoute.aidl",
"aidl/android/media/AudioTimestampInternal.aidl",
"aidl/android/media/AudioUniqueIdUse.aidl",
"aidl/android/media/AudioVibratorInfo.aidl",
+ "aidl/android/media/DeviceConnectedState.aidl",
"aidl/android/media/EffectDescriptor.aidl",
"aidl/android/media/TrackSecondaryOutputInfo.aidl",
+ "aidl/android/media/SurroundSoundConfig.aidl",
],
imports: [
"android.media.audio.common.types-V2",
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 620cdc2..4384f97 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -810,10 +810,10 @@
}
status_t AudioFlingerClientAdapter::setDeviceConnectedState(
- const struct audio_port_v7 *port, bool connected) {
+ const struct audio_port_v7 *port, media::DeviceConnectedState state) {
media::AudioPortFw aidlPort = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_port_v7_AudioPortFw(*port));
- return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, connected));
+ return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, state));
}
status_t AudioFlingerClientAdapter::setSimulateDeviceConnections(bool enabled) {
@@ -1369,9 +1369,9 @@
}
Status AudioFlingerServerAdapter::setDeviceConnectedState(
- const media::AudioPortFw& port, bool connected) {
+ const media::AudioPortFw& port, media::DeviceConnectedState state) {
audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPortFw_audio_port_v7(port));
- return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, connected));
+ return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, state));
}
Status AudioFlingerServerAdapter::setSimulateDeviceConnections(bool enabled) {
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index f0b4d11..7c0ce57 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -1306,6 +1306,7 @@
streamType = AUDIO_STREAM_DTMF;
}
attr = AudioSystem::streamTypeToAttributes(streamType);
+ attr.flags = AUDIO_FLAG_LOW_LATENCY;
const size_t frameCount = mProcessSize;
status_t status = mpAudioTrack->set(
@@ -1314,7 +1315,7 @@
AUDIO_FORMAT_PCM_16_BIT,
AUDIO_CHANNEL_OUT_MONO,
frameCount,
- AUDIO_OUTPUT_FLAG_FAST,
+ AUDIO_OUTPUT_FLAG_NONE,
wp<AudioTrack::IAudioTrackCallback>::fromExisting(this),
0, // notificationFrames
0, // sharedBuffer
diff --git a/media/libaudioclient/aidl/android/media/AudioRoute.aidl b/media/libaudioclient/aidl/android/media/AudioRoute.aidl
new file mode 100644
index 0000000..5ee2161
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioRoute.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * TODO(b/280077672): This is a temporary copy of the stable
+ * android.hardware.audio.core.AudioRoute. Interfaces from the Core API do not
+ * support the CPP backend. This copy will be removed either by moving the
+ * AudioRoute from core to a.m.a.common or by switching the framework internal
+ * interfaces to the NDK backend.
+ * {@hide}
+ */
+parcelable AudioRoute {
+ /**
+ * The list of IDs of source audio ports ('AudioPort.id').
+ * There must be at least one source in a valid route and all IDs must be
+ * unique.
+ */
+ int[] sourcePortIds;
+ /** The ID of the sink audio port ('AudioPort.id'). */
+ int sinkPortId;
+ /** If set, only one source can be active, mixing is not supported. */
+ boolean isExclusive;
+}
diff --git a/media/libaudioclient/aidl/android/media/DeviceConnectedState.aidl b/media/libaudioclient/aidl/android/media/DeviceConnectedState.aidl
new file mode 100644
index 0000000..e401384
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/DeviceConnectedState.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media;
+
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum DeviceConnectedState {
+ CONNECTED = 0,
+ DISCONNECTED = 1,
+ PREPARE_TO_DISCONNECT = 2,
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index 4d9fef4..884cd30 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -27,6 +27,7 @@
import android.media.CreateRecordResponse;
import android.media.CreateTrackRequest;
import android.media.CreateTrackResponse;
+import android.media.DeviceConnectedState;
import android.media.OpenInputRequest;
import android.media.OpenInputResponse;
import android.media.OpenOutputRequest;
@@ -227,7 +228,7 @@
int getAAudioHardwareBurstMinUsec();
- void setDeviceConnectedState(in AudioPortFw devicePort, boolean connected);
+ void setDeviceConnectedState(in AudioPortFw devicePort, DeviceConnectedState state);
// Used for tests only. Requires AIDL HAL to work.
void setSimulateDeviceConnections(boolean enabled);
diff --git a/media/libaudioclient/aidl/android/media/ISoundDose.aidl b/media/libaudioclient/aidl/android/media/ISoundDose.aidl
index 0e2a5ab..6cb22ef 100644
--- a/media/libaudioclient/aidl/android/media/ISoundDose.aidl
+++ b/media/libaudioclient/aidl/android/media/ISoundDose.aidl
@@ -49,13 +49,11 @@
oneway void updateAttenuation(float attenuationDB, int device);
/**
- * Disable the calculation of sound dose. This has the effect that no MEL
- * values will be computed on the framework side. The MEL returned from
- * the IHalSoundDoseCallbacks will be ignored.
- * Should only be called once at startup if the AudioService does not
- * support CSD.
+ * Enables/disables the calculation of sound dose. This has the effect that
+ * if disabled no MEL values will be computed on the framework side. The MEL
+ * returned from the IHalSoundDoseCallbacks will be ignored.
*/
- oneway void disableCsd();
+ oneway void setCsdEnabled(boolean enabled);
/* -------------------------- Test API methods --------------------------
/** Get the currently used RS2 upper bound. */
diff --git a/media/libaudioclient/aidl/android/media/SurroundSoundConfig.aidl b/media/libaudioclient/aidl/android/media/SurroundSoundConfig.aidl
new file mode 100644
index 0000000..f83fdef
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/SurroundSoundConfig.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.media.audio.common.AudioFormatDescription;
+
+/**
+ * TODO(b/280077672): This is a temporary copy of the stable
+ * android.hardware.audio.core.SurroundSoundConfig parcelable.
+ * Interfaces from the Core API do not support the CPP backend. This copy will
+ * be removed either by moving the AudioRoute from core to a.m.a.common or by
+ * switching the framework internal interfaces to the NDK backend.
+ * {@hide}
+ */
+parcelable SurroundSoundConfig {
+ parcelable SurroundFormatFamily {
+ /**
+ * A primaryFormat shall get an entry in the Surround Settings dialog on TV
+ * devices. There must be a corresponding Java ENCODING_... constant
+ * defined in AudioFormat.java, and a display name defined in
+ * AudioFormat.toDisplayName.
+ */
+ AudioFormatDescription primaryFormat;
+ /**
+ * List of formats that shall be equivalent to the primaryFormat from the
+ * users' point of view and don't need a dedicated Surround Settings
+ * dialog entry.
+ */
+ AudioFormatDescription[] subFormats;
+ }
+ SurroundFormatFamily[] formatFamilies;
+}
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 1803862..6e28d51 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -361,7 +361,8 @@
virtual int32_t getAAudioHardwareBurstMinUsec() = 0;
- virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
+ virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port,
+ media::DeviceConnectedState state) = 0;
virtual status_t setSimulateDeviceConnections(bool enabled) = 0;
@@ -481,7 +482,8 @@
std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) override;
int32_t getAAudioMixerBurstCount() override;
int32_t getAAudioHardwareBurstMinUsec() override;
- status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) override;
+ status_t setDeviceConnectedState(const struct audio_port_v7 *port,
+ media::DeviceConnectedState state) override;
status_t setSimulateDeviceConnections(bool enabled) override;
status_t setRequestedLatencyMode(audio_io_handle_t output,
audio_latency_mode_t mode) override;
@@ -711,7 +713,8 @@
std::vector<media::audio::common::AudioMMapPolicyInfo> *_aidl_return) override;
Status getAAudioMixerBurstCount(int32_t* _aidl_return) override;
Status getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override;
- Status setDeviceConnectedState(const media::AudioPortFw& port, bool connected) override;
+ Status setDeviceConnectedState(const media::AudioPortFw& port,
+ media::DeviceConnectedState state) override;
Status setSimulateDeviceConnections(bool enabled) override;
Status setRequestedLatencyMode(
int output, media::audio::common::AudioLatencyMode mode) override;
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 1dbcb86..3c05b0b 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -74,6 +74,12 @@
cc_library_headers {
name: "libaudiohal_headers",
+ header_libs: [
+ "libeffectsconfig_headers",
+ ],
+
+ export_header_lib_headers: ["libeffectsconfig_headers"],
+
export_include_dirs: ["include"],
}
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 9dbb591..09e70eb 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -35,6 +35,7 @@
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
"libaudiohal_deathhandler",
+ "libeffectsconfig",
"libhidlbase",
"libhidlmemory",
],
@@ -287,15 +288,17 @@
"android.hardware.common.fmq-V1-ndk",
],
shared_libs: [
- "libbinder_ndk",
"libaudio_aidl_conversion_common_cpp",
"libaudio_aidl_conversion_common_ndk",
+ "libaudio_aidl_conversion_common_ndk_cpp",
"libaudio_aidl_conversion_core_ndk",
"libaudio_aidl_conversion_effect_ndk",
"libaudioaidlcommon",
+ "libbinder_ndk",
],
header_libs: [
"libaudio_system_headers",
+ "libeffectsconfig_headers",
],
cflags: [
"-Wall",
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index aafe6e0..f993907 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -23,10 +23,9 @@
#include <aidl/android/hardware/audio/core/BnStreamCallback.h>
#include <aidl/android/hardware/audio/core/BnStreamOutEventCallback.h>
#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
-#include <android/binder_enums.h>
-#include <binder/Enums.h>
#include <error/expected_utils.h>
#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionNdkCpp.h>
#include <media/AidlConversionUtil.h>
#include <mediautils/TimeCheck.h>
#include <Utils.h>
@@ -96,77 +95,35 @@
portConfig->format = config.base.format;
}
-template<typename OutEnum, typename OutEnumRange, typename InEnum>
-ConversionResult<OutEnum> convertEnum(const OutEnumRange& range, InEnum e) {
- using InIntType = std::underlying_type_t<InEnum>;
- static_assert(std::is_same_v<InIntType, std::underlying_type_t<OutEnum>>);
-
- InIntType inEnumIndex = static_cast<InIntType>(e);
- OutEnum outEnum = static_cast<OutEnum>(inEnumIndex);
- if (std::find(range.begin(), range.end(), outEnum) == range.end()) {
- return ::android::base::unexpected(BAD_VALUE);
- }
- return outEnum;
-}
-
-template<typename NdkEnum, typename CppEnum>
-ConversionResult<NdkEnum> cpp2ndk_Enum(CppEnum e) {
- return convertEnum<NdkEnum>(::ndk::enum_range<NdkEnum>(), e);
-}
-
-template<typename CppEnum, typename NdkEnum>
-ConversionResult<CppEnum> ndk2cpp_Enum(NdkEnum e) {
- return convertEnum<CppEnum>(::android::enum_range<CppEnum>(), e);
-}
-
-ConversionResult<android::media::audio::common::AudioDeviceAddress>
-ndk2cpp_AudioDeviceAddress(const AudioDeviceAddress& ndk) {
- using CppTag = android::media::audio::common::AudioDeviceAddress::Tag;
- using NdkTag = AudioDeviceAddress::Tag;
-
- CppTag cppTag = VALUE_OR_RETURN(ndk2cpp_Enum<CppTag>(ndk.getTag()));
-
- switch (cppTag) {
- case CppTag::id:
- return android::media::audio::common::AudioDeviceAddress::make<CppTag::id>(
- ndk.get<NdkTag::id>());
- case CppTag::mac:
- return android::media::audio::common::AudioDeviceAddress::make<CppTag::mac>(
- ndk.get<NdkTag::mac>());
- case CppTag::ipv4:
- return android::media::audio::common::AudioDeviceAddress::make<CppTag::ipv4>(
- ndk.get<NdkTag::ipv4>());
- case CppTag::ipv6:
- return android::media::audio::common::AudioDeviceAddress::make<CppTag::ipv6>(
- ndk.get<NdkTag::ipv6>());
- case CppTag::alsa:
- return android::media::audio::common::AudioDeviceAddress::make<CppTag::alsa>(
- ndk.get<NdkTag::alsa>());
- }
-
- return ::android::base::unexpected(BAD_VALUE);
-}
-
-ConversionResult<media::audio::common::AudioDevice> ndk2cpp_AudioDevice(const AudioDevice& ndk) {
- media::audio::common::AudioDevice cpp;
- cpp.type.type = VALUE_OR_RETURN(
- ndk2cpp_Enum<media::audio::common::AudioDeviceType>(ndk.type.type));
- cpp.type.connection = ndk.type.connection;
- cpp.address = VALUE_OR_RETURN(ndk2cpp_AudioDeviceAddress(ndk.address));
- return cpp;
-}
-
-ConversionResult<media::audio::common::AudioMMapPolicyInfo>
-ndk2cpp_AudioMMapPolicyInfo(const AudioMMapPolicyInfo& ndk) {
- media::audio::common::AudioMMapPolicyInfo cpp;
- cpp.device = VALUE_OR_RETURN(ndk2cpp_AudioDevice(ndk.device));
- cpp.mmapPolicy = VALUE_OR_RETURN(
- ndk2cpp_Enum<media::audio::common::AudioMMapPolicy>(ndk.mmapPolicy));
+// Note: these converters are for types defined in different AIDL files. Although these
+// AIDL files are copies of each other, however formally these are different types
+// thus we don't use a conversion via a parcelable.
+ConversionResult<media::AudioRoute> ndk2cpp_AudioRoute(const AudioRoute& ndk) {
+ media::AudioRoute cpp;
+ cpp.sourcePortIds.insert(
+ cpp.sourcePortIds.end(), ndk.sourcePortIds.begin(), ndk.sourcePortIds.end());
+ cpp.sinkPortId = ndk.sinkPortId;
+ cpp.isExclusive = ndk.isExclusive;
return cpp;
}
} // namespace
+status_t DeviceHalAidl::getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) {
+ auto convertAudioPortFromMap = [](const Ports::value_type& pair) {
+ return ndk2cpp_AudioPort(pair.second);
+ };
+ return ::aidl::android::convertRange(mPorts.begin(), mPorts.end(), ports->begin(),
+ convertAudioPortFromMap);
+}
+
+status_t DeviceHalAidl::getAudioRoutes(std::vector<media::AudioRoute> *routes) {
+ *routes = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::convertContainer<std::vector<media::AudioRoute>>(
+ mRoutes, ndk2cpp_AudioRoute));
+ return OK;
+}
+
status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
// Obsolete.
return INVALID_OPERATION;
@@ -176,8 +133,7 @@
TIME_CHECK();
if (mModule == nullptr) return NO_INIT;
std::vector<AudioPort> ports;
- RETURN_STATUS_IF_ERROR(
- statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
ALOGW_IF(ports.empty(), "%s: module %s returned an empty list of audio ports",
__func__, mInstance.c_str());
std::transform(ports.begin(), ports.end(), std::inserter(mPorts, mPorts.end()),
@@ -204,6 +160,9 @@
std::transform(portConfigs.begin(), portConfigs.end(),
std::inserter(mPortConfigs, mPortConfigs.end()),
[](const auto& p) { return std::make_pair(p.id, p); });
+ std::transform(mPortConfigs.begin(), mPortConfigs.end(),
+ std::inserter(mInitialPortConfigIds, mInitialPortConfigIds.end()),
+ [](const auto& pcPair) { return pcPair.first; });
std::vector<AudioPatch> patches;
RETURN_STATUS_IF_ERROR(
statusTFromBinderStatus(mModule->getAudioPatches(&patches))); // OK if empty
@@ -357,12 +316,14 @@
this, getClassName().c_str(), __func__, aidlHandle, aidlDevice.toString().c_str(),
aidlFlags.toString().c_str(), toString(aidlSource).c_str(),
aidlConfig->toString().c_str(), mixPortConfig->toString().c_str());
+ resetUnusedPatchesAndPortConfigs();
const bool isInput = aidlFlags.getTag() == AudioIoFlags::Tag::input;
// Find / create AudioPortConfigs for the device port and the mix port,
// then find / create a patch between them, and open a stream on the mix port.
AudioPortConfig devicePortConfig;
bool created = false;
- RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(aidlDevice, &devicePortConfig, &created));
+ RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(aidlDevice, aidlConfig,
+ &devicePortConfig, &created));
if (created) {
cleanups->emplace_front(this, &DeviceHalAidl::resetPortConfig, devicePortConfig.id);
}
@@ -888,8 +849,8 @@
media::audio::common::AudioMMapPolicyType policyType,
std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) {
TIME_CHECK();
- AudioMMapPolicyType mmapPolicyType =
- VALUE_OR_RETURN_STATUS(cpp2ndk_Enum<AudioMMapPolicyType>(policyType));
+ AudioMMapPolicyType mmapPolicyType = VALUE_OR_RETURN_STATUS(
+ cpp2ndk_AudioMMapPolicyType(policyType));
std::vector<AudioMMapPolicyInfo> mmapPolicyInfos;
@@ -966,12 +927,32 @@
return OK;
}
+status_t DeviceHalAidl::prepareToDisconnectExternalDevice(const struct audio_port_v7* port) {
+ // There is not AIDL API defined for `prepareToDisconnectExternalDevice`.
+ // Call `setConnectedState` instead.
+ // TODO(b/279824103): call prepareToDisconnectExternalDevice when it is added.
+ const status_t status = setConnectedState(port, false /*connected*/);
+ if (status == NO_ERROR) {
+ mDeviceDisconnectionNotified.insert(port->id);
+ }
+ return status;
+}
+
status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
TIME_CHECK();
if (!mModule) return NO_INIT;
if (port == nullptr) {
return BAD_VALUE;
}
+ if (!connected && mDeviceDisconnectionNotified.erase(port->id) > 0) {
+ // For device disconnection, APM will first call `prepareToDisconnectExternalDevice`
+ // and then call `setConnectedState`. However, there is no API for
+ // `prepareToDisconnectExternalDevice` yet. In that case, `setConnectedState` will be
+ // called when calling `prepareToDisconnectExternalDevice`. Do not call to the HAL if
+ // previous call is successful. Also remove the cache here to avoid a large cache after
+ // a long run.
+ return NO_ERROR;
+ }
bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(port->role, port->type)) ==
::aidl::android::AudioPortDirection::INPUT;
AudioPort aidlPort = VALUE_OR_RETURN_STATUS(
@@ -1109,7 +1090,7 @@
return OK;
}
-status_t DeviceHalAidl::findOrCreatePortConfig(const AudioDevice& device,
+status_t DeviceHalAidl::findOrCreatePortConfig(const AudioDevice& device, const AudioConfig* config,
AudioPortConfig* portConfig, bool* created) {
auto portConfigIt = findPortConfig(device);
if (portConfigIt == mPortConfigs.end()) {
@@ -1121,6 +1102,9 @@
}
AudioPortConfig requestedPortConfig;
requestedPortConfig.portId = portsIt->first;
+ if (config != nullptr) {
+ setPortConfigFromConfig(&requestedPortConfig, *config);
+ }
RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig, &portConfigIt,
created));
} else {
@@ -1223,7 +1207,8 @@
portConfig, created);
} else if (requestedPortConfig.ext.getTag() == Tag::device) {
return findOrCreatePortConfig(
- requestedPortConfig.ext.get<Tag::device>().device, portConfig, created);
+ requestedPortConfig.ext.get<Tag::device>().device, nullptr /*config*/,
+ portConfig, created);
}
ALOGW("%s: unsupported audio port config: %s",
__func__, requestedPortConfig.toString().c_str());
@@ -1252,7 +1237,6 @@
[&](const auto& pair) { return audioDeviceMatches(device, pair.second); });
}
-
DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(
const AudioConfig& config, const AudioIoFlags& flags,
const std::set<int32_t>& destinationPortIds) {
@@ -1265,10 +1249,20 @@
std::find(prof.sampleRates.begin(), prof.sampleRates.end(),
config.base.sampleRate) != prof.sampleRates.end());
};
+ static const std::vector<AudioOutputFlags> kOptionalOutputFlags{AudioOutputFlags::BIT_PERFECT};
+ int optionalFlags = 0;
+ auto flagMatches = [&flags, &optionalFlags](const AudioIoFlags& portFlags) {
+ // Ports should be able to match if the optional flags are not requested.
+ return portFlags == flags ||
+ (portFlags.getTag() == AudioIoFlags::Tag::output &&
+ AudioIoFlags::make<AudioIoFlags::Tag::output>(
+ portFlags.get<AudioIoFlags::Tag::output>() &
+ ~optionalFlags) == flags);
+ };
auto matcher = [&](const auto& pair) {
const auto& p = pair.second;
return p.ext.getTag() == AudioPortExt::Tag::mix &&
- p.flags == flags &&
+ flagMatches(p.flags) &&
(destinationPortIds.empty() ||
std::any_of(destinationPortIds.begin(), destinationPortIds.end(),
[&](const int32_t destId) { return mRoutingMatrix.count(
@@ -1276,7 +1270,24 @@
(p.profiles.empty() ||
std::find_if(p.profiles.begin(), p.profiles.end(), belongsToProfile) !=
p.profiles.end()); };
- return std::find_if(mPorts.begin(), mPorts.end(), matcher);
+ auto result = std::find_if(mPorts.begin(), mPorts.end(), matcher);
+ if (result == mPorts.end() && flags.getTag() == AudioIoFlags::Tag::output) {
+ auto optionalOutputFlagsIt = kOptionalOutputFlags.begin();
+ while (result == mPorts.end() && optionalOutputFlagsIt != kOptionalOutputFlags.end()) {
+ if (isBitPositionFlagSet(
+ flags.get<AudioIoFlags::Tag::output>(), *optionalOutputFlagsIt)) {
+ // If the flag is set by the request, it must be matched.
+ ++optionalOutputFlagsIt;
+ continue;
+ }
+ optionalFlags |= makeBitPositionFlagMask(*optionalOutputFlagsIt++);
+ result = std::find_if(mPorts.begin(), mPorts.end(), matcher);
+ ALOGI("%s: port for config %s, flags %s was not found in the module %s, "
+ "retried with excluding optional flags %#x", __func__, config.toString().c_str(),
+ flags.toString().c_str(), mInstance.c_str(), optionalFlags);
+ }
+ }
+ return result;
}
DeviceHalAidl::PortConfigs::iterator DeviceHalAidl::findPortConfig(const AudioDevice& device) {
@@ -1358,18 +1369,20 @@
for (int32_t id : p.second.sourcePortConfigIds) portConfigIds.erase(id);
for (int32_t id : p.second.sinkPortConfigIds) portConfigIds.erase(id);
}
+ for (int32_t id : mInitialPortConfigIds) {
+ portConfigIds.erase(id);
+ }
for (int32_t id : portConfigIds) resetPortConfig(id);
}
status_t DeviceHalAidl::updateRoutes() {
TIME_CHECK();
- std::vector<AudioRoute> routes;
RETURN_STATUS_IF_ERROR(
- statusTFromBinderStatus(mModule->getAudioRoutes(&routes)));
- ALOGW_IF(routes.empty(), "%s: module %s returned an empty list of audio routes",
+ statusTFromBinderStatus(mModule->getAudioRoutes(&mRoutes)));
+ ALOGW_IF(mRoutes.empty(), "%s: module %s returned an empty list of audio routes",
__func__, mInstance.c_str());
mRoutingMatrix.clear();
- for (const auto& r : routes) {
+ for (const auto& r : mRoutes) {
for (auto portId : r.sourcePortIds) {
mRoutingMatrix.emplace(r.sinkPortId, portId);
mRoutingMatrix.emplace(portId, r.sinkPortId);
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index e4d5ec6..f2c64de 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -69,6 +69,10 @@
class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl,
public CallbackBroker, public MicrophoneInfoProvider {
public:
+ status_t getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) override;
+
+ status_t getAudioRoutes(std::vector<media::AudioRoute> *routes) override;
+
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
status_t getSupportedDevices(uint32_t *devices) override;
@@ -161,6 +165,8 @@
status_t getSoundDoseInterface(const std::string& module,
::ndk::SpAIBinder* soundDoseBinder) override;
+ status_t prepareToDisconnectExternalDevice(const struct audio_port_v7 *port) override;
+
status_t setConnectedState(const struct audio_port_v7 *port, bool connected) override;
status_t setSimulateDeviceConnections(bool enabled) override;
@@ -185,6 +191,7 @@
using PortConfigs = std::map<int32_t /*port config ID*/,
::aidl::android::media::audio::common::AudioPortConfig>;
using Ports = std::map<int32_t /*port ID*/, ::aidl::android::media::audio::common::AudioPort>;
+ using Routes = std::vector<::aidl::android::hardware::audio::core::AudioRoute>;
// Answers the question "whether portID 'first' is reachable from portID 'second'?"
// It's not a map because both portIDs are known. The matrix is symmetric.
using RoutingMatrix = std::set<std::pair<int32_t, int32_t>>;
@@ -215,6 +222,7 @@
::aidl::android::hardware::audio::core::AudioPatch* patch, bool* created);
status_t findOrCreatePortConfig(
const ::aidl::android::media::audio::common::AudioDevice& device,
+ const ::aidl::android::media::audio::common::AudioConfig* config,
::aidl::android::media::audio::common::AudioPortConfig* portConfig,
bool* created);
status_t findOrCreatePortConfig(
@@ -284,12 +292,15 @@
int32_t mDefaultInputPortId = -1;
int32_t mDefaultOutputPortId = -1;
PortConfigs mPortConfigs;
+ std::set<int32_t> mInitialPortConfigIds;
Patches mPatches;
+ Routes mRoutes;
RoutingMatrix mRoutingMatrix;
Streams mStreams;
Microphones mMicrophones;
std::mutex mLock;
std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock);
+ std::set<audio_port_handle_t> mDeviceDisconnectionNotified;
};
} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index e0b1afb..d67cbdc 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -104,6 +104,15 @@
}
}
+status_t DeviceHalHidl::getAudioPorts(
+ std::vector<media::audio::common::AudioPort> *ports __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t DeviceHalHidl::getAudioRoutes(std::vector<media::AudioRoute> *routes __unused) {
+ return INVALID_OPERATION;
+}
+
status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
// Obsolete.
return INVALID_OPERATION;
@@ -430,6 +439,7 @@
template <typename HalPort>
status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
+ using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
if (mDevice == 0) return NO_INIT;
AudioPort hidlPort;
HidlUtils::audioPortFromHal(*port, &hidlPort);
@@ -472,6 +482,7 @@
}
status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
+ using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPortConfig;
TIME_CHECK();
if (mDevice == 0) return NO_INIT;
AudioPortConfig hidlConfig;
@@ -535,9 +546,29 @@
}
#endif
+status_t DeviceHalHidl::prepareToDisconnectExternalDevice(const struct audio_port_v7* port) {
+ // For HIDL HAL, there is not API to call notify the HAL to prepare for device connected
+ // state changed. Call `setConnectedState` directly.
+ const status_t status = setConnectedState(port, false /*connected*/);
+ if (status == NO_ERROR) {
+ // Cache the port id so that it won't disconnect twice.
+ mDeviceDisconnectionNotified.insert(port->id);
+ }
+ return status;
+}
+
status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
+ using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
TIME_CHECK();
if (mDevice == 0) return NO_INIT;
+ if (!connected && mDeviceDisconnectionNotified.erase(port->id) > 0) {
+ // For device disconnection, APM will first call `prepareToDisconnectExternalDevice` and
+ // then call `setConnectedState`. However, in HIDL HAL, there is no API for
+ // `prepareToDisconnectExternalDevice`. In that case, HIDL HAL will call `setConnectedState`
+ // when calling `prepareToDisconnectExternalDevice`. Do not call to the HAL if previous
+ // call is successful. Also remove the cache here to avoid a large cache after a long run.
+ return NO_ERROR;
+ }
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
if (supportsSetConnectedState7_1) {
AudioPort hidlPort;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index afaad51..7222f03 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -29,6 +29,10 @@
class DeviceHalHidl : public DeviceHalInterface, public CoreConversionHelperHidl
{
public:
+ status_t getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) override;
+
+ status_t getAudioRoutes(std::vector<media::AudioRoute> *routes) override;
+
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
status_t getSupportedDevices(uint32_t *devices) override;
@@ -138,6 +142,8 @@
status_t getSoundDoseInterface(const std::string& module,
::ndk::SpAIBinder* soundDoseBinder) override;
+ status_t prepareToDisconnectExternalDevice(const struct audio_port_v7* port) override;
+
private:
friend class DevicesFactoryHalHidl;
sp<::android::hardware::audio::CPP_VERSION::IDevice> mDevice;
@@ -146,6 +152,7 @@
bool supportsSetConnectedState7_1 = true;
class SoundDoseWrapper;
const std::unique_ptr<SoundDoseWrapper> mSoundDoseWrapper;
+ std::set<audio_port_handle_t> mDeviceDisconnectionNotified;
// Can not be constructed directly by clients.
explicit DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device);
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index 2eaaf5d..8345cd2 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -14,26 +14,67 @@
* limitations under the License.
*/
+#include <memory>
+
#define LOG_TAG "DevicesFactoryHalAidl"
//#define LOG_NDEBUG 0
#include <aidl/android/hardware/audio/core/IModule.h>
#include <android/binder_manager.h>
#include <binder/IServiceManager.h>
-#include <memory>
+#include <media/AidlConversionNdkCpp.h>
+#include <media/AidlConversionUtil.h>
#include <utils/Log.h>
#include "DeviceHalAidl.h"
#include "DevicesFactoryHalAidl.h"
-using namespace ::aidl::android::hardware::audio::core;
+using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::hardware::audio::core::IConfig;
+using aidl::android::hardware::audio::core::IModule;
+using aidl::android::hardware::audio::core::SurroundSoundConfig;
+using aidl::android::media::audio::common::AudioHalEngineConfig;
using ::android::detail::AudioHalVersionInfo;
namespace android {
-DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> iconfig)
- : mIConfig(std::move(iconfig)) {
- ALOG_ASSERT(iconfig != nullptr, "Provided default IConfig service is NULL");
+namespace {
+
+ConversionResult<media::SurroundSoundConfig::SurroundFormatFamily>
+ndk2cpp_SurroundSoundConfigFormatFamily(const SurroundSoundConfig::SurroundFormatFamily& ndk) {
+ media::SurroundSoundConfig::SurroundFormatFamily cpp;
+ cpp.primaryFormat = VALUE_OR_RETURN(ndk2cpp_AudioFormatDescription(ndk.primaryFormat));
+ cpp.subFormats = VALUE_OR_RETURN(::aidl::android::convertContainer<std::vector<
+ media::audio::common::AudioFormatDescription>>(ndk.subFormats,
+ ndk2cpp_AudioFormatDescription));
+ return cpp;
+}
+
+ConversionResult<media::SurroundSoundConfig>
+ndk2cpp_SurroundSoundConfig(const SurroundSoundConfig& ndk) {
+ media::SurroundSoundConfig cpp;
+ cpp.formatFamilies = VALUE_OR_RETURN(::aidl::android::convertContainer<std::vector<
+ media::SurroundSoundConfig::SurroundFormatFamily>>(ndk.formatFamilies,
+ ndk2cpp_SurroundSoundConfigFormatFamily));
+ return cpp;
+}
+
+} // namespace
+
+DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> config)
+ : mConfig(std::move(config)) {
+}
+
+status_t DevicesFactoryHalAidl::getDeviceNames(std::vector<std::string> *names) {
+ if (names == nullptr) {
+ return BAD_VALUE;
+ }
+ AServiceManager_forEachDeclaredInstance(IModule::descriptor, static_cast<void*>(names),
+ [](const char* instance, void* context) {
+ if (strcmp(instance, "default") == 0) instance = "primary";
+ static_cast<decltype(names)>(context)->push_back(instance);
+ });
+ return OK;
}
// Opens a device with the specified name. To close the device, it is
@@ -43,19 +84,22 @@
return BAD_VALUE;
}
+ // FIXME: Remove this call and the check for the supported module names
+ // after implementing retrieval of module names on the framework side.
+ // Currently it is still using the legacy XML config.
+ std::vector<std::string> deviceNames;
+ if (status_t status = getDeviceNames(&deviceNames); status != OK) {
+ return status;
+ }
std::shared_ptr<IModule> service;
- // FIXME: Normally we will list available HAL modules and connect to them,
- // however currently we still get the list of module names from the config.
- // Since the example service does not have all modules, the SM will wait
- // for the missing ones forever.
- if (strcmp(name, "primary") == 0 || strcmp(name, "r_submix") == 0 || strcmp(name, "usb") == 0) {
+ if (std::find(deviceNames.begin(), deviceNames.end(), name) != deviceNames.end()) {
if (strcmp(name, "primary") == 0) name = "default";
auto serviceName = std::string(IModule::descriptor) + "/" + name;
service = IModule::fromBinder(
ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
ALOGE_IF(service == nullptr, "%s fromBinder %s failed", __func__, serviceName.c_str());
}
- // If the service is a nullptr, the device will not be really functional,
+ // If the service is a nullptr, the device object will not be really functional,
// but will not crash either.
*device = sp<DeviceHalAidl>::make(name, service);
return OK;
@@ -97,18 +141,28 @@
AudioHalVersionInfo DevicesFactoryHalAidl::getHalVersion() const {
int32_t versionNumber = 0;
- if (mIConfig != 0) {
- if (ndk::ScopedAStatus status = mIConfig->getInterfaceVersion(&versionNumber);
- !status.isOk()) {
- ALOGE("%s getInterfaceVersion failed: %s", __func__, status.getDescription().c_str());
- }
- } else {
- ALOGW("%s no IConfig instance", __func__);
+ if (ndk::ScopedAStatus status = mConfig->getInterfaceVersion(&versionNumber); !status.isOk()) {
+ ALOGE("%s getInterfaceVersion failed: %s", __func__, status.getDescription().c_str());
}
// AIDL does not have minor version, fill 0 for all versions
return AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, versionNumber);
}
+status_t DevicesFactoryHalAidl::getSurroundSoundConfig(media::SurroundSoundConfig *config) {
+ SurroundSoundConfig ndkConfig;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mConfig->getSurroundSoundConfig(&ndkConfig)));
+ *config = VALUE_OR_RETURN_STATUS(ndk2cpp_SurroundSoundConfig(ndkConfig));
+ return OK;
+}
+
+status_t DevicesFactoryHalAidl::getEngineConfig(
+ media::audio::common::AudioHalEngineConfig *config) {
+ AudioHalEngineConfig ndkConfig;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mConfig->getEngineConfig(&ndkConfig)));
+ *config = VALUE_OR_RETURN_STATUS(ndk2cpp_AudioHalEngineConfig(ndkConfig));
+ return OK;
+}
+
// Main entry-point to the shared library.
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
auto serviceName = std::string(IConfig::descriptor) + "/default";
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.h b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
index cb627bc..21957bc 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
@@ -26,7 +26,9 @@
{
public:
explicit DevicesFactoryHalAidl(
- std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> iConfig);
+ std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> config);
+
+ status_t getDeviceNames(std::vector<std::string> *names) override;
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
@@ -38,8 +40,12 @@
android::detail::AudioHalVersionInfo getHalVersion() const override;
+ status_t getSurroundSoundConfig(media::SurroundSoundConfig *config) override;
+
+ status_t getEngineConfig(media::audio::common::AudioHalEngineConfig *config) override;
+
private:
- const std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> mIConfig;
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> mConfig;
~DevicesFactoryHalAidl() = default;
};
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
index 9f06f83..eef60b5 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
@@ -106,6 +106,10 @@
}
#endif
+status_t DevicesFactoryHalHidl::getDeviceNames(std::vector<std::string> *names __unused) {
+ return INVALID_OPERATION;
+}
+
status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
auto factories = copyDeviceFactories();
if (factories.empty()) return NO_INIT;
@@ -232,6 +236,16 @@
return AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, MAJOR_VERSION, MINOR_VERSION);
}
+status_t DevicesFactoryHalHidl::getSurroundSoundConfig(
+ media::SurroundSoundConfig *config __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t DevicesFactoryHalHidl::getEngineConfig(
+ media::audio::common::AudioHalEngineConfig *config __unused) {
+ return INVALID_OPERATION;
+}
+
// Main entry-point to the shared library.
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.h b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
index 5294728..3285af7 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
@@ -37,6 +37,8 @@
explicit DevicesFactoryHalHidl(sp<IDevicesFactory> devicesFactory);
void onFirstRef() override;
+ status_t getDeviceNames(std::vector<std::string> *names) override;
+
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
status_t openDevice(const char *name, sp<DeviceHalInterface> *device) override;
@@ -47,6 +49,10 @@
android::detail::AudioHalVersionInfo getHalVersion() const override;
+ status_t getSurroundSoundConfig(media::SurroundSoundConfig *config) override;
+
+ status_t getEngineConfig(media::audio::common::AudioHalEngineConfig *config) override;
+
private:
friend class ServiceNotificationListener;
void addDeviceFactory(sp<IDevicesFactory> factory, bool needToNotify);
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index bc05aa0..0dcb8ee 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -23,6 +23,7 @@
//#define LOG_NDEBUG 0
#include <error/expected_utils.h>
+#include <aidl/android/media/audio/common/AudioStreamType.h>
#include <android/binder_manager.h>
#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionEffect.h>
@@ -35,11 +36,13 @@
#include "EffectsFactoryHalAidl.h"
using ::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid;
-using aidl::android::aidl_utils::statusTFromBinderStatus;
-using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::media::audio::common::AudioUuid;
-using android::detail::AudioHalVersionInfo;
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::IFactory;
+using ::aidl::android::hardware::audio::effect::Processing;
+using ::aidl::android::media::audio::common::AudioUuid;
+using ::android::base::unexpected;
+using ::android::detail::AudioHalVersionInfo;
namespace android {
namespace effect {
@@ -92,7 +95,8 @@
[](const Descriptor& desc) { return !desc.common.id.proxy.has_value(); });
return list;
}()),
- mEffectCount(mNonProxyDescList.size() + mProxyDescList.size()) {
+ mEffectCount(mNonProxyDescList.size() + mProxyDescList.size()),
+ mEffectProcessings(nullptr /* TODO: add AIDL implementation */) {
ALOG_ASSERT(mFactory != nullptr, "Provided IEffectsFactory service is NULL");
ALOGI("%s with %zu nonProxyEffects and %zu proxyEffects", __func__, mNonProxyDescList.size(),
mProxyDescList.size());
@@ -269,6 +273,19 @@
return 0 != mUuidProxyMap.count(uuid);
}
+std::shared_ptr<const effectsConfig::Processings> EffectsFactoryHalAidl::getProcessings() const {
+ return mEffectProcessings;
+}
+
+::android::error::Result<size_t> EffectsFactoryHalAidl::getSkippedElements() const {
+ if (!mEffectProcessings) {
+ return ::android::base::unexpected(BAD_VALUE);
+ }
+
+ // Only return 0 for AIDL, because the AIDL interface doesn't aware of configuration file
+ return 0;
+}
+
} // namespace effect
// When a shared library is built from a static library, even explicit
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.h b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
index debfacf..70a7012 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
@@ -62,6 +62,10 @@
detail::AudioHalVersionInfo getHalVersion() const override;
+ std::shared_ptr<const effectsConfig::Processings> getProcessings() const override;
+
+ ::android::error::Result<size_t> getSkippedElements() const override;
+
private:
const std::shared_ptr<IFactory> mFactory;
const detail::AudioHalVersionInfo mHalVersion;
@@ -77,6 +81,8 @@
const std::vector<Descriptor> mNonProxyDescList;
// total number of effects including proxy effects
const size_t mEffectCount;
+ // Query result of pre and post processing from effect factory
+ const std::shared_ptr<const effectsConfig::Processings> mEffectProcessings;
std::mutex mLock;
uint64_t mEffectIdCounter GUARDED_BY(mLock) = 0; // Align with HIDL (0 is INVALID_ID)
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index 172ebdf..210c4b5 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -33,10 +33,11 @@
#include "android/media/AudioHalVersion.h"
+using ::android::base::unexpected;
using ::android::detail::AudioHalVersionInfo;
+using ::android::hardware::Return;
using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils;
-using ::android::hardware::Return;
namespace android {
namespace effect {
@@ -78,9 +79,11 @@
}
EffectsFactoryHalHidl::EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory)
- : EffectConversionHelperHidl("EffectsFactory"), mCache(new EffectDescriptorCache) {
- ALOG_ASSERT(effectsFactory != nullptr, "Provided IEffectsFactory service is NULL");
- mEffectsFactory = std::move(effectsFactory);
+ : EffectConversionHelperHidl("EffectsFactory"),
+ mEffectsFactory(std::move(effectsFactory)),
+ mCache(new EffectDescriptorCache),
+ mParsingResult(effectsConfig::parse()) {
+ ALOG_ASSERT(mEffectsFactory != nullptr, "Provided IEffectsFactory service is NULL");
}
status_t EffectsFactoryHalHidl::queryNumberEffects(uint32_t *pNumEffects) {
@@ -228,6 +231,17 @@
return AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, MAJOR_VERSION, MINOR_VERSION);
}
+std::shared_ptr<const effectsConfig::Processings> EffectsFactoryHalHidl::getProcessings() const {
+ return mParsingResult.parsedConfig;
+}
+
+::android::error::Result<size_t> EffectsFactoryHalHidl::getSkippedElements() const {
+ if (!mParsingResult.parsedConfig) {
+ return ::android::base::unexpected(BAD_VALUE);
+ }
+ return mParsingResult.nbSkippedElement;
+}
+
} // namespace effect
// When a shared library is built from a static library, even explicit
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.h b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
index 9875154..4110ba3 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
@@ -17,6 +17,7 @@
#pragma once
#include <memory>
+#include <vector>
#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h)
#include <media/audiohal/EffectsFactoryHalInterface.h>
@@ -62,9 +63,19 @@
android::detail::AudioHalVersionInfo getHalVersion() const override;
+ std::shared_ptr<const effectsConfig::Processings> getProcessings() const override;
+
+ ::android::error::Result<size_t> getSkippedElements() const override;
+
private:
- sp<IEffectsFactory> mEffectsFactory;
- std::unique_ptr<EffectDescriptorCache> mCache;
+ const sp<IEffectsFactory> mEffectsFactory;
+ const std::unique_ptr<EffectDescriptorCache> mCache;
+ /**
+ * Configuration file parser result, used by getProcessings() and getConfigParseResult().
+ * This struct holds the result of parsing a configuration file. The result includes the parsed
+ * configuration data, as well as any errors that occurred during parsing.
+ */
+ const effectsConfig::ParsingResult mParsingResult;
};
} // namespace effect
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 6c43591..eccdfe8 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -436,8 +436,7 @@
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ return statusTFromBinderStatus(mStream->prepareToClose());
}
status_t StreamHalAidl::createMmapBuffer(int32_t minSizeFrames __unused,
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 192790c..2b0af49 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -979,9 +979,10 @@
}
status_t StreamOutHalHidl::exit() {
- // FIXME this is using hard-coded strings but in the future, this functionality will be
- // converted to use audio HAL extensions required to support tunneling
- return setParameters(String8("exiting=1"));
+ // Signal exiting to remote_submix HAL.
+ AudioParameter param;
+ param.addInt(String8(AudioParameter::keyExiting), 1);
+ return setParameters(param.toString());
}
StreamInHalHidl::StreamInHalHidl(
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp
index 2d5af59..b4440ee 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp
@@ -52,6 +52,7 @@
Parameter aidlParam;
switch (type) {
case VISUALIZER_PARAM_CAPTURE_SIZE: {
+ mCaptureSize = value;
aidlParam = MAKE_SPECIFIC_PARAMETER(Visualizer, visualizer, captureSamples, value);
break;
}
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index e8d8998..45f2922 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -19,6 +19,8 @@
#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <android/media/audio/common/AudioMMapPolicyType.h>
+#include <android/media/audio/common/AudioPort.h>
+#include <android/media/AudioRoute.h>
#include <error/Result.h>
#include <media/audiohal/EffectHalInterface.h>
#include <system/audio.h>
@@ -38,6 +40,10 @@
class DeviceHalInterface : public virtual RefBase
{
public:
+ virtual status_t getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) = 0;
+
+ virtual status_t getAudioRoutes(std::vector<media::AudioRoute> *routes) = 0;
+
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
virtual status_t getSupportedDevices(uint32_t *devices) = 0;
@@ -149,6 +155,8 @@
virtual status_t getSoundDoseInterface(const std::string& module,
::ndk::SpAIBinder* soundDoseBinder) = 0;
+ virtual status_t prepareToDisconnectExternalDevice(const struct audio_port_v7* port) = 0;
+
protected:
// Subclasses can not be constructed directly by clients.
DeviceHalInterface() {}
diff --git a/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
index be3a723..8397e9b 100644
--- a/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
@@ -16,6 +16,8 @@
#pragma once
+#include <android/media/audio/common/AudioHalEngineConfig.h>
+#include <android/media/SurroundSoundConfig.h>
#include <media/audiohal/DeviceHalInterface.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -34,6 +36,8 @@
class DevicesFactoryHalInterface : public RefBase
{
public:
+ virtual status_t getDeviceNames(std::vector<std::string> *names) = 0;
+
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device) = 0;
@@ -46,6 +50,10 @@
virtual android::detail::AudioHalVersionInfo getHalVersion() const = 0;
+ virtual status_t getSurroundSoundConfig(media::SurroundSoundConfig *config) = 0;
+
+ virtual status_t getEngineConfig(media::audio::common::AudioHalEngineConfig *config) = 0;
+
static sp<DevicesFactoryHalInterface> create();
protected:
diff --git a/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
index d740fe9..832df18 100644
--- a/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
@@ -15,8 +15,10 @@
*/
#pragma once
+#include <vector>
#include <media/audiohal/EffectHalInterface.h>
+#include <media/EffectsConfig.h>
#include <system/audio_effect.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -33,21 +35,24 @@
virtual status_t queryNumberEffects(uint32_t *pNumEffects) = 0;
// Returns a descriptor of the next available effect.
- virtual status_t getDescriptor(uint32_t index,
- effect_descriptor_t *pDescriptor) = 0;
+ virtual status_t getDescriptor(uint32_t index, effect_descriptor_t* pDescriptor) = 0;
- virtual status_t getDescriptor(const effect_uuid_t *pEffectUuid,
- effect_descriptor_t *pDescriptor) = 0;
+ virtual status_t getDescriptor(const effect_uuid_t* pEffectUuid,
+ effect_descriptor_t* pDescriptor) = 0;
virtual status_t getDescriptors(const effect_uuid_t *pEffectType,
std::vector<effect_descriptor_t> *descriptors) = 0;
+ virtual std::shared_ptr<const effectsConfig::Processings> getProcessings() const = 0;
+
+ // status_t if parser return error, skipped elements if parsing result is OK (always 0 for AIDL)
+ virtual error::Result<size_t> getSkippedElements() const = 0;
+
// Creates an effect engine of the specified type.
// To release the effect engine, it is necessary to release references
// to the returned effect object.
- virtual status_t createEffect(const effect_uuid_t *pEffectUuid,
- int32_t sessionId, int32_t ioId, int32_t deviceId,
- sp<EffectHalInterface> *effect) = 0;
+ virtual status_t createEffect(const effect_uuid_t* pEffectUuid, int32_t sessionId, int32_t ioId,
+ int32_t deviceId, sp<EffectHalInterface>* effect) = 0;
virtual status_t dumpEffects(int fd) = 0;
diff --git a/media/libaudiousecasevalidation/UsecaseValidator.cpp b/media/libaudiousecasevalidation/UsecaseValidator.cpp
index 0e5a824..d62df3a 100644
--- a/media/libaudiousecasevalidation/UsecaseValidator.cpp
+++ b/media/libaudiousecasevalidation/UsecaseValidator.cpp
@@ -99,10 +99,8 @@
audio_attributes_t attrRet = attributes;
- // Check if attribute usage media or unknown has been set.
- bool isUsageValid = this->isUsageValid(attributes);
-
- if (isUsageValid && m_lookup.isGameStream(streamId)) {
+ if (isUsageValid(attributes.usage) && isContentTypeValid(attributes.content_type)
+ && areFlagsValid(attributes.flags) && m_lookup.isGameStream(streamId)) {
ALOGI("%s update usage: %d to AUDIO_USAGE_GAME for output: %d pid: %d package: %s",
__func__, attributes.usage, streamId, attributionSource.pid,
attributionSource.packageName.value_or("").c_str());
@@ -117,9 +115,9 @@
/**
* Check if attribute usage valid.
*/
- bool isUsageValid(const audio_attributes_t& attr) {
- ALOGV("isUsageValid attr.usage: %d", attr.usage);
- switch (attr.usage) {
+ bool isUsageValid(audio_usage_t usage) {
+ ALOGV("isUsageValid usage: %d", usage);
+ switch (usage) {
case AUDIO_USAGE_MEDIA:
case AUDIO_USAGE_UNKNOWN:
return true;
@@ -129,6 +127,27 @@
return false;
}
+ bool isContentTypeValid(audio_content_type_t contentType) {
+ ALOGV("isContentTypeValid contentType: %d", contentType);
+ switch (contentType) {
+ case AUDIO_CONTENT_TYPE_MUSIC:
+ case AUDIO_CONTENT_TYPE_MOVIE:
+ case AUDIO_CONTENT_TYPE_UNKNOWN:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ bool areFlagsValid(audio_flags_mask_t flags) {
+ ALOGV("areFlagsValid flags: %#x", flags);
+ if ((flags & AUDIO_FLAG_LOW_LATENCY) != 0) {
+ return true;
+ }
+ return false;
+ }
+
protected:
UsecaseLookup m_lookup;
};
diff --git a/media/libaudiousecasevalidation/tests/UsecaseValidator-test.cpp b/media/libaudiousecasevalidation/tests/UsecaseValidator-test.cpp
index d92c8ba..5768a9b 100644
--- a/media/libaudiousecasevalidation/tests/UsecaseValidator-test.cpp
+++ b/media/libaudiousecasevalidation/tests/UsecaseValidator-test.cpp
@@ -52,10 +52,8 @@
*/
error::Result<audio_attributes_t> UsecaseValidatorTest::testStartClient(audio_io_handle_t streamId,
audio_port_handle_t portId,
- audio_usage_t usage) {
+ audio_attributes_t attributes) {
content::AttributionSourceState attributionSource;
- audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
- attributes.usage = usage;
return m_validator->startClient(streamId, portId, attributionSource, attributes, NULL);
}
@@ -141,11 +139,14 @@
mediaPortId = testCreatePortId(mediaStreamId);
EXPECT_NE(mediaPortId, 0);
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ attributes.usage = AUDIO_USAGE_GAME;
// Start client on game stream.
- testStartClient(gameStreamId, gamePortId, AUDIO_USAGE_GAME);
+ testStartClient(gameStreamId, gamePortId, attributes);
+ attributes.usage = AUDIO_USAGE_MEDIA;
// Start client on media stream.
- testStartClient(mediaStreamId, mediaPortId, AUDIO_USAGE_MEDIA);
+ testStartClient(mediaStreamId, mediaPortId, attributes);
// Unregister media stream before stopClient.
EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
@@ -175,18 +176,23 @@
voiceCommPortId = testCreatePortId(gameStreamId);
EXPECT_NE(voiceCommPortId, 0);
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
// Verify attributes on game stream.
- auto attr = testStartClient(gameStreamId, gamePortId, AUDIO_USAGE_GAME);
+ attributes.usage = AUDIO_USAGE_GAME;
+ auto attr = testStartClient(gameStreamId, gamePortId, attributes);
EXPECT_EQ(attr.value().usage, AUDIO_USAGE_GAME);
- attr = testStartClient(gameStreamId, voiceCommPortId, AUDIO_USAGE_VOICE_COMMUNICATION);
+ attributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION;
+ attr = testStartClient(gameStreamId, voiceCommPortId, attributes);
EXPECT_EQ(attr.value().usage, AUDIO_USAGE_VOICE_COMMUNICATION);
// Verify attributes on media stream.
- attr = testStartClient(mediaStreamId, mediaPortId, AUDIO_USAGE_MEDIA);
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attr = testStartClient(mediaStreamId, mediaPortId, attributes);
EXPECT_EQ(attr.value().usage, AUDIO_USAGE_MEDIA);
- attr = testStartClient(mediaStreamId, unknownPortId, AUDIO_USAGE_UNKNOWN);
+ attributes.usage = AUDIO_USAGE_UNKNOWN;
+ attr = testStartClient(mediaStreamId, unknownPortId, attributes);
EXPECT_EQ(attr.value().usage, AUDIO_USAGE_UNKNOWN);
// Stop client on game and media stream.
@@ -215,16 +221,79 @@
unknownPortId = testCreatePortId(gameStreamId);
EXPECT_NE(unknownPortId, 0);
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ attributes.flags = AUDIO_FLAG_LOW_LATENCY;
// Verify attributes on game stream.
- auto attr = testStartClient(gameStreamId, mediaPortId, AUDIO_USAGE_MEDIA);
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ auto attr = testStartClient(gameStreamId, mediaPortId, attributes);
EXPECT_EQ(attr.value().usage, AUDIO_USAGE_GAME);
- attr = testStartClient(gameStreamId, unknownPortId, AUDIO_USAGE_UNKNOWN);
+ attributes.usage = AUDIO_USAGE_UNKNOWN;
+ attr = testStartClient(gameStreamId, unknownPortId, attributes);
EXPECT_EQ(attr.value().usage, AUDIO_USAGE_GAME);
// Unregister game stream.
EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
}
+/**
+ * Verify attributes usage does not change for non low latency clients.
+ */
+TEST_F(UsecaseValidatorTest, testAttributesUsageUnChangedIfNotLowLatency) {
+ audio_io_handle_t gameStreamId;
+ audio_port_handle_t mediaPortId, unknownPortId;
+
+ // Register game and media stream.
+ gameStreamId = testRegisterStream(true);
+ EXPECT_NE(gameStreamId, 0);
+
+ // Assign portId.
+ mediaPortId = testCreatePortId(gameStreamId);
+ EXPECT_NE(mediaPortId, 0);
+ unknownPortId = testCreatePortId(gameStreamId);
+ EXPECT_NE(unknownPortId, 0);
+
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ // Verify attributes on game stream.
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ auto attr = testStartClient(gameStreamId, mediaPortId, attributes);
+ EXPECT_EQ(attr.value().usage, AUDIO_USAGE_MEDIA);
+
+ attributes.usage = AUDIO_USAGE_UNKNOWN;
+ attr = testStartClient(gameStreamId, unknownPortId, attributes);
+ EXPECT_EQ(attr.value().usage, AUDIO_USAGE_UNKNOWN);
+
+ // Unregister game stream.
+ EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
+}
+
+/**
+ * Verify attributes usage does not change for content type speech.
+ */
+TEST_F(UsecaseValidatorTest, testAttributesUsageUnChangedIfSpeech) {
+ audio_io_handle_t gameStreamId;
+ audio_port_handle_t mediaPortId, unknownPortId;
+
+ // Register game and media stream.
+ gameStreamId = testRegisterStream(true);
+ EXPECT_NE(gameStreamId, 0);
+
+ // Assign portId.
+ mediaPortId = testCreatePortId(gameStreamId);
+ EXPECT_NE(mediaPortId, 0);
+ unknownPortId = testCreatePortId(gameStreamId);
+ EXPECT_NE(unknownPortId, 0);
+
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ // Verify attributes on game stream.
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ auto attr = testStartClient(gameStreamId, mediaPortId, attributes);
+ EXPECT_EQ(attr.value().usage, AUDIO_USAGE_MEDIA);
+
+ // Unregister game stream.
+ EXPECT_EQ(m_validator->unregisterStream(gameStreamId), 0);
+}
+
} // namespace media
} // namespace android
diff --git a/media/libaudiousecasevalidation/tests/UsecaseValidator-test.h b/media/libaudiousecasevalidation/tests/UsecaseValidator-test.h
index 3159ab4..8cbd0f0 100644
--- a/media/libaudiousecasevalidation/tests/UsecaseValidator-test.h
+++ b/media/libaudiousecasevalidation/tests/UsecaseValidator-test.h
@@ -69,7 +69,7 @@
audio_port_handle_t testCreatePortId(audio_io_handle_t streamId);
error::Result<audio_attributes_t> testStartClient(audio_io_handle_t streamId,
audio_port_handle_t portId,
- audio_usage_t usage);
+ audio_attributes_t attributes);
error::Result<audio_attributes_t> testVerifyAudioAttributes(audio_io_handle_t streamId,
audio_usage_t usage);
diff --git a/media/libeffects/config/Android.bp b/media/libeffects/config/Android.bp
index b02dcb6..293a9c2 100644
--- a/media/libeffects/config/Android.bp
+++ b/media/libeffects/config/Android.bp
@@ -27,8 +27,21 @@
"libcutils",
],
- header_libs: ["libaudio_system_headers"],
- export_header_lib_headers: ["libaudio_system_headers"],
+ header_libs: [
+ "libaudio_system_headers",
+ "liberror_headers",
+ ],
+
+ export_header_lib_headers: [
+ "libaudio_system_headers",
+ "liberror_headers",
+ ],
+
+ export_include_dirs: ["include"],
+}
+
+cc_library_headers {
+ name: "libeffectsconfig_headers",
export_include_dirs: ["include"],
}
diff --git a/media/libeffects/config/include/media/EffectsConfig.h b/media/libeffects/config/include/media/EffectsConfig.h
index 57d4dd7..a9730e5 100644
--- a/media/libeffects/config/include/media/EffectsConfig.h
+++ b/media/libeffects/config/include/media/EffectsConfig.h
@@ -22,8 +22,10 @@
* @see audio_effects_conf_V2_0.xsd for documentation on each structure
*/
+#include <error/Result.h>
#include <system/audio_effect.h>
+#include <cstddef>
#include <map>
#include <memory>
#include <string>
@@ -75,6 +77,12 @@
std::string address;
};
+struct Processings {
+ std::vector<InputStream> preprocess;
+ std::vector<OutputStream> postprocess;
+ std::vector<DeviceEffects> deviceprocess;
+};
+
/** Parsed configuration.
* Intended to be a transient structure only used for deserialization.
* Note: Everything is copied in the configuration from the xml dom.
@@ -82,19 +90,16 @@
* consider keeping a private handle on the xml dom and replace all strings by dom pointers.
* Or even better, use SAX parsing to avoid the allocations all together.
*/
-struct Config {
+struct Config : public Processings {
float version;
Libraries libraries;
Effects effects;
- std::vector<OutputStream> postprocess;
- std::vector<InputStream> preprocess;
- std::vector<DeviceEffects> deviceprocess;
};
/** Result of `parse(const char*)` */
struct ParsingResult {
/** Parsed config, nullptr if the xml lib could not load the file */
- std::unique_ptr<Config> parsedConfig;
+ std::shared_ptr<const Config> parsedConfig;
size_t nbSkippedElement; //< Number of skipped invalid library, effect or processing chain
const std::string configPath; //< Path to the loaded configuration
};
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 1696233..3096659 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -286,7 +286,7 @@
return {nullptr, 0, std::move(path)};
}
- auto config = std::make_unique<Config>();
+ auto config = std::make_shared<Config>();
size_t nbSkippedElements = 0;
auto registerFailure = [&nbSkippedElements](bool result) {
nbSkippedElements += result ? 0 : 1;
diff --git a/media/libeffects/factory/Android.bp b/media/libeffects/factory/Android.bp
index 22838a3..d94093e 100644
--- a/media/libeffects/factory/Android.bp
+++ b/media/libeffects/factory/Android.bp
@@ -39,6 +39,7 @@
header_libs: [
"libaudioeffects",
"libeffects_headers",
+ "liberror_headers",
],
export_header_lib_headers: ["libeffects_headers"],
}
@@ -56,7 +57,6 @@
"-Werror",
],
-
shared_libs: [
"libeffectsconfig",
"libeffects",
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
index b3371a3..3bc889c 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
@@ -85,9 +85,7 @@
static const std::string kEqualizerEffectName = "EqualizerBundle";
static const Descriptor kEqualizerDesc = {
.common = {.id = {.type = getEffectTypeUuidEqualizer(),
- .uuid = getEffectImplUuidEqualizerBundle(),
- .proxy = getEffectImplUuidEqualizerProxy()},
-
+ .uuid = getEffectImplUuidEqualizerBundle()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
@@ -102,8 +100,7 @@
static const std::string kBassBoostEffectName = "Dynamic Bass Boost";
static const Descriptor kBassBoostDesc = {
.common = {.id = {.type = getEffectTypeUuidBassBoost(),
- .uuid = getEffectImplUuidBassBoostBundle(),
- .proxy = getEffectImplUuidBassBoostProxy()},
+ .uuid = getEffectImplUuidBassBoostBundle()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL,
@@ -121,8 +118,7 @@
static const Descriptor kVirtualizerDesc = {
.common = {.id = {.type = getEffectTypeUuidVirtualizer(),
- .uuid = getEffectImplUuidVirtualizerBundle(),
- .proxy = getEffectImplUuidVirtualizerProxy()},
+ .uuid = getEffectImplUuidVirtualizerBundle()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::LAST,
.volume = Flags::Volume::CTRL,
@@ -139,8 +135,7 @@
static const std::string kVolumeEffectName = "Volume";
static const Descriptor kVolumeDesc = {
.common = {.id = {.type = getEffectTypeUuidVolume(),
- .uuid = getEffectImplUuidVolumeBundle(),
- .proxy = std::nullopt},
+ .uuid = getEffectImplUuidVolumeBundle()},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::LAST,
.volume = Flags::Volume::CTRL},
diff --git a/media/libmediahelper/AudioParameter.cpp b/media/libmediahelper/AudioParameter.cpp
index 9a8156e..e25f9b7 100644
--- a/media/libmediahelper/AudioParameter.cpp
+++ b/media/libmediahelper/AudioParameter.cpp
@@ -32,6 +32,8 @@
const char * const AudioParameter::keyFrameCount = AUDIO_PARAMETER_STREAM_FRAME_COUNT;
const char * const AudioParameter::keyInputSource = AUDIO_PARAMETER_STREAM_INPUT_SOURCE;
const char * const AudioParameter::keyScreenState = AUDIO_PARAMETER_KEY_SCREEN_STATE;
+const char * const AudioParameter::keyClosing = AUDIO_PARAMETER_KEY_CLOSING;
+const char * const AudioParameter::keyExiting = AUDIO_PARAMETER_KEY_EXITING;
const char * const AudioParameter::keyBtNrec = AUDIO_PARAMETER_KEY_BT_NREC;
const char * const AudioParameter::keyHwAvSync = AUDIO_PARAMETER_HW_AV_SYNC;
const char * const AudioParameter::keyPresentationId = AUDIO_PARAMETER_STREAM_PRESENTATION_ID;
diff --git a/media/libmediahelper/include/media/AudioParameter.h b/media/libmediahelper/include/media/AudioParameter.h
index 41aff7c..6c34a4f 100644
--- a/media/libmediahelper/include/media/AudioParameter.h
+++ b/media/libmediahelper/include/media/AudioParameter.h
@@ -49,6 +49,12 @@
static const char * const keyInputSource;
static const char * const keyScreenState;
+ // TODO(b/73175392) consider improvement to AIDL StreamOut interface.
+ // keyClosing: "true" when AudioOutputDescriptor is closing. Used by A2DP HAL.
+ // keyExiting: "1" on AudioFlinger Thread preExit. Used by remote_submix and A2DP HAL.
+ static const char * const keyClosing;
+ static const char * const keyExiting;
+
// keyBtNrec: BT SCO Noise Reduction + Echo Cancellation parameters
// keyHwAvSync: get HW synchronization source identifier from a device
// keyMonoOutput: Enable mono audio playback
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index ec6a00a..569a25f 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -79,7 +79,6 @@
},
}
-// this library gets wrapped into libstagefright as well as modules
cc_library_static {
name: "libstagefright_mpeg2extractor",
apex_available: [
@@ -242,6 +241,7 @@
"CodecErrorLog.cpp",
"CryptoAsync.cpp",
"FrameDecoder.cpp",
+ "HevcUtils.cpp",
"InterfaceUtils.cpp",
"JPEGSource.cpp",
"MPEG2TSWriter.cpp",
@@ -255,6 +255,7 @@
"MediaCodecSource.cpp",
"MediaExtractor.cpp",
"MediaExtractorFactory.cpp",
+ "MediaSource.cpp",
"MediaSync.cpp",
"MediaTrack.cpp",
"MediaMuxer.cpp",
@@ -268,6 +269,7 @@
"StagefrightMediaScanner.cpp",
"SurfaceUtils.cpp",
"ThrottledSource.cpp",
+ "Utils.cpp",
"VideoFrameSchedulerBase.cpp",
"VideoFrameScheduler.cpp",
],
@@ -326,11 +328,6 @@
"libmedia_ndkformatpriv",
],
- // to get Utils, MediaSource, HevcUtils
- whole_static_libs: [
- "libstagefright_mpeg2extractor",
- ],
-
header_libs:[
"libmediadrm_headers",
"libnativeloader-headers",
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 09c5d64..080c3d0 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -118,15 +118,6 @@
static const char *kCodecCaptureRate = "android.media.mediacodec.capture-rate";
static const char *kCodecOperatingRate = "android.media.mediacodec.operating-rate";
static const char *kCodecPriority = "android.media.mediacodec.priority";
-static const char *kCodecConfigColorStandard = "android.media.mediacodec.config-color-standard";
-static const char *kCodecConfigColorRange = "android.media.mediacodec.config-color-range";
-static const char *kCodecConfigColorTransfer = "android.media.mediacodec.config-color-transfer";
-static const char *kCodecParsedColorStandard = "android.media.mediacodec.parsed-color-standard";
-static const char *kCodecParsedColorRange = "android.media.mediacodec.parsed-color-range";
-static const char *kCodecParsedColorTransfer = "android.media.mediacodec.parsed-color-transfer";
-static const char *kCodecHDRStaticInfo = "android.media.mediacodec.hdr-static-info";
-static const char *kCodecHDR10PlusInfo = "android.media.mediacodec.hdr10-plus-info";
-static const char *kCodecHDRFormat = "android.media.mediacodec.hdr-format";
// Min/Max QP before shaping
static const char *kCodecOriginalVideoQPIMin = "android.media.mediacodec.original-video-qp-i-min";
@@ -175,6 +166,29 @@
static const char *kCodecVideoInputBytes = "android.media.mediacodec.video.input.bytes";
static const char *kCodecVideoInputFrames = "android.media.mediacodec.video.input.frames";
static const char *kCodecVideoEncodedDurationUs = "android.media.mediacodec.vencode.durationUs";
+// HDR metrics
+static const char *kCodecConfigColorStandard = "android.media.mediacodec.config-color-standard";
+static const char *kCodecConfigColorRange = "android.media.mediacodec.config-color-range";
+static const char *kCodecConfigColorTransfer = "android.media.mediacodec.config-color-transfer";
+static const char *kCodecParsedColorStandard = "android.media.mediacodec.parsed-color-standard";
+static const char *kCodecParsedColorRange = "android.media.mediacodec.parsed-color-range";
+static const char *kCodecParsedColorTransfer = "android.media.mediacodec.parsed-color-transfer";
+static const char *kCodecHDRStaticInfo = "android.media.mediacodec.hdr-static-info";
+static const char *kCodecHDR10PlusInfo = "android.media.mediacodec.hdr10-plus-info";
+static const char *kCodecHDRFormat = "android.media.mediacodec.hdr-format";
+// array/sync/async/block modes
+static const char *kCodecArrayMode = "android.media.mediacodec.array-mode";
+static const char *kCodecOperationMode = "android.media.mediacodec.operation-mode";
+static const char *kCodecOutputSurface = "android.media.mediacodec.output-surface";
+// max size configured by the app
+static const char *kCodecAppMaxInputSize = "android.media.mediacodec.app-max-input-size";
+// max size actually used
+static const char *kCodecUsedMaxInputSize = "android.media.mediacodec.used-max-input-size";
+// max size suggested by the codec
+static const char *kCodecCodecMaxInputSize = "android.media.mediacodec.codec-max-input-size";
+static const char *kCodecFlushCount = "android.media.mediacodec.flush-count";
+static const char *kCodecSetSurfaceCount = "android.media.mediacodec.set-surface-count";
+static const char *kCodecResolutionChangeCount = "android.media.mediacodec.resolution-change-count";
// the kCodecRecent* fields appear only in getMetrics() results
static const char *kCodecRecentLatencyMax = "android.media.mediacodec.recent.max"; /* in us */
@@ -935,7 +949,6 @@
mWidth(0),
mHeight(0),
mRotationDegrees(0),
- mHdrInfoFlags(0),
mDequeueInputTimeoutGeneration(0),
mDequeueInputReplyID(0),
mDequeueOutputTimeoutGeneration(0),
@@ -1043,6 +1056,14 @@
}
mLifetimeStartNs = systemTime(SYSTEM_TIME_MONOTONIC);
+ resetMetricsFields();
+}
+
+void MediaCodec::resetMetricsFields() {
+ mHdrInfoFlags = 0;
+
+ mApiUsageMetrics = ApiUsageMetrics();
+ mReliabilityContextMetrics = ReliabilityContextMetrics();
}
void MediaCodec::updateMediametrics() {
@@ -1053,6 +1074,28 @@
Mutex::Autolock _lock(mMetricsLock);
+ mediametrics_setInt32(mMetricsHandle, kCodecArrayMode, mApiUsageMetrics.isArrayMode ? 1 : 0);
+ mApiUsageMetrics.operationMode = (mFlags & kFlagIsAsync) ?
+ ((mFlags & kFlagUseBlockModel) ? ApiUsageMetrics::kBlockMode
+ : ApiUsageMetrics::kAsynchronousMode)
+ : ApiUsageMetrics::kSynchronousMode;
+ mediametrics_setInt32(mMetricsHandle, kCodecOperationMode, mApiUsageMetrics.operationMode);
+ mediametrics_setInt32(mMetricsHandle, kCodecOutputSurface,
+ mApiUsageMetrics.isUsingOutputSurface ? 1 : 0);
+
+ mediametrics_setInt32(mMetricsHandle, kCodecAppMaxInputSize,
+ mApiUsageMetrics.inputBufferSize.appMax);
+ mediametrics_setInt32(mMetricsHandle, kCodecUsedMaxInputSize,
+ mApiUsageMetrics.inputBufferSize.usedMax);
+ mediametrics_setInt32(mMetricsHandle, kCodecCodecMaxInputSize,
+ mApiUsageMetrics.inputBufferSize.codecMax);
+
+ mediametrics_setInt32(mMetricsHandle, kCodecFlushCount, mReliabilityContextMetrics.flushCount);
+ mediametrics_setInt32(mMetricsHandle, kCodecSetSurfaceCount,
+ mReliabilityContextMetrics.setOutputSurfaceCount);
+ mediametrics_setInt32(mMetricsHandle, kCodecResolutionChangeCount,
+ mReliabilityContextMetrics.resolutionChangeCount);
+
if (mLatencyHist.getCount() != 0 ) {
mediametrics_setInt64(mMetricsHandle, kCodecLatencyMax, mLatencyHist.getMax());
mediametrics_setInt64(mMetricsHandle, kCodecLatencyMin, mLatencyHist.getMin());
@@ -1295,7 +1338,7 @@
// update does its own mutex locking
updateMediametrics();
- mHdrInfoFlags = 0;
+ resetMetricsFields();
// ensure mutex while we do our own work
Mutex::Autolock _lock(mMetricsLock);
@@ -1967,6 +2010,10 @@
if (format->findInt32("color-format", &colorFormat)) {
mediametrics_setInt32(nextMetricsHandle, kCodecColorFormat, colorFormat);
}
+ int32_t appMaxInputSize = -1;
+ if (format->findInt32(KEY_MAX_INPUT_SIZE, &appMaxInputSize)) {
+ mApiUsageMetrics.inputBufferSize.appMax = appMaxInputSize;
+ }
if (mDomain == DOMAIN_VIDEO) {
float frameRate = -1.0;
if (format->findFloat("frame-rate", &frameRate)) {
@@ -3768,6 +3815,10 @@
mediametrics_setInt32(mMetricsHandle, kCodecLevel, level);
}
updateHdrMetrics(true /* isConfig */);
+ int32_t codecMaxInputSize = -1;
+ if (mInputFormat->findInt32(KEY_MAX_INPUT_SIZE, &codecMaxInputSize)) {
+ mApiUsageMetrics.inputBufferSize.codecMax = codecMaxInputSize;
+ }
// bitrate and bitrate mode, encoder only
if (mFlags & kFlagIsEncoder) {
// encoder specific values
@@ -4168,6 +4219,7 @@
setState(STARTED);
mCodec->signalResume();
}
+ mReliabilityContextMetrics.flushCount++;
postPendingRepliesAndDeferredMessages("kWhatFlushCompleted");
break;
@@ -4328,6 +4380,8 @@
handleSetSurface(NULL);
}
+ mApiUsageMetrics.isUsingOutputSurface = true;
+
uint32_t flags;
CHECK(msg->findInt32("flags", (int32_t *)&flags));
if (flags & CONFIGURE_FLAG_USE_BLOCK_MODEL ||
@@ -4468,6 +4522,7 @@
(void)disconnectFromSurface();
mSurface = surface;
}
+ mReliabilityContextMetrics.setOutputSurfaceCount++;
}
}
break;
@@ -5005,6 +5060,8 @@
}
}
+ mApiUsageMetrics.isArrayMode = true;
+
(new AMessage)->postReply(replyID);
break;
}
@@ -5273,6 +5330,7 @@
ClientConfigParcel clientConfig;
initClientConfigParcel(clientConfig);
mResourceManagerProxy->notifyClientConfigChanged(clientConfig);
+ mReliabilityContextMetrics.resolutionChangeCount++;
}
updateHdrMetrics(false /* isConfig */);
@@ -5708,6 +5766,10 @@
if (err != OK) {
return -EINVAL;
}
+
+ int32_t usedMaxInputSize = mApiUsageMetrics.inputBufferSize.usedMax;
+ mApiUsageMetrics.inputBufferSize.usedMax = size > usedMaxInputSize ? size : usedMaxInputSize;
+
if (hasCryptoOrDescrambler() && !c2Buffer && !memory) {
AString *errorDetailMsg;
CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
index 9d2568e..f91a8b2 100644
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
@@ -733,32 +733,36 @@
const bool is10Bit = (mSrcFormat == COLOR_FormatYUVP010
|| mSrcFormat == OMX_COLOR_FormatYUV420Planar16);
- switch (mSrcColorSpace.mStandard) {
- case ColorUtils::kColorStandardBT601_525:
- case ColorUtils::kColorStandardBT601_625:
+ ColorAspects::Primaries primaries;
+ ColorAspects::MatrixCoeffs matrix;
+ if (ColorUtils::unwrapColorAspectsFromColorStandard(
+ mSrcColorSpace.mStandard, &primaries, &matrix) != OK) {
+ matrix = ColorAspects::MatrixUnspecified;
+ }
+
+ switch (matrix) {
+ case ColorAspects::MatrixBT601_6:
+ case ColorAspects::MatrixBT470_6M: // use 601 matrix as that is the closest for now
+ case ColorAspects::MatrixSMPTE240M: // use 601 matrix as that is the closest for now
return (isFullRange ? &BT601_FULL :
is10Bit ? &BT601_LTD_10BIT : &BT601_LIMITED);
- case ColorUtils::kColorStandardBT709:
+ case ColorAspects::MatrixBT709_5:
return (isFullRange ? &BT709_FULL :
is10Bit ? &BT709_LTD_10BIT : &BT709_LIMITED);
- case ColorUtils::kColorStandardBT2020:
+ case ColorAspects::MatrixBT2020:
+ case ColorAspects::MatrixBT2020Constant: // use 2020 matrix as that is the closest for now
return (isFullRange ? &BT2020_FULL :
is10Bit ? &BT2020_LTD_10BIT : &BT2020_LIMITED);
default:
- // for now use the default matrices for unhandled color spaces
- // TODO: fail?
- // return nullptr;
- [[fallthrough]];
-
- case ColorUtils::kColorStandardUnspecified:
- if (isFullRange) {
- return is10Bit ? &BT2020_FULL : &BT601_FULL;
+ // use BT.2020 for 10-bit and 601 for 8-bit by default
+ if (is10Bit) {
+ return isFullRange ? &BT2020_FULL : &BT2020_LTD_10BIT;
+ } else {
+ return isFullRange ? &BT601_FULL : &BT601_LIMITED;
}
- return is10Bit ? &BT2020_LTD_10BIT : &BT601_LIMITED;
-
}
}
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 1cc281b..3d4b6f8 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -453,6 +453,7 @@
void initMediametrics();
void updateMediametrics();
void flushMediametrics();
+ void resetMetricsFields();
void updateEphemeralMediametrics(mediametrics_handle_t item);
void updateLowLatency(const sp<AMessage> &msg);
void onGetMetrics(const sp<AMessage>& msg);
@@ -492,6 +493,28 @@
const int32_t colorTransfer);
bool profileSupport10Bits(const AString &mime, const int32_t profile);
+ struct ApiUsageMetrics {
+ bool isArrayMode;
+ enum OperationMode {
+ kUnknownMode = 0,
+ kSynchronousMode = 1,
+ kAsynchronousMode = 2,
+ kBlockMode = 3,
+ };
+ OperationMode operationMode;
+ bool isUsingOutputSurface;
+ struct InputBufferSize {
+ int32_t appMax; // max size configured by the app
+ int32_t usedMax; // max size actually used
+ int32_t codecMax; // max size suggested by the codec
+ } inputBufferSize;
+ } mApiUsageMetrics;
+ struct ReliabilityContextMetrics {
+ int32_t flushCount;
+ int32_t setOutputSurfaceCount;
+ int32_t resolutionChangeCount;
+ } mReliabilityContextMetrics;
+
// initial create parameters
AString mInitName;
diff --git a/media/module/foundation/ColorUtils.cpp b/media/module/foundation/ColorUtils.cpp
index 6dc8157..12bffca 100644
--- a/media/module/foundation/ColorUtils.cpp
+++ b/media/module/foundation/ColorUtils.cpp
@@ -60,6 +60,10 @@
{ CU::kColorStandardBT470M, { CA::PrimariesBT470_6M, CA::MatrixBT470_6M } },
// NOTE: there is no close match to the matrix used by standard film, chose closest
{ CU::kColorStandardFilm, { CA::PrimariesGenericFilm, CA::MatrixBT2020 } },
+ // DCI-P3 (in DataSpace that drives this standard) is actually Display P3
+ // ITU does not specify a matrix suitable for P3. The theoretical KR/KB numbers are
+ // 0.229 and 0.079. Assume BT.601 matrix as P3 is commonly used for JPEG with BT.601.
+ { CU::kColorStandardDisplay_P3, { CA::PrimariesEG432, CA::MatrixBT601_6 } },
}
};
@@ -264,6 +268,8 @@
{ 8, ColorAspects::PrimariesGenericFilm },
{ 9, ColorAspects::PrimariesBT2020 },
{ 10, ColorAspects::PrimariesOther /* XYZ */ },
+ { 11, ColorAspects::PrimariesRP431 },
+ { 12, ColorAspects::PrimariesEG432 },
}
};
@@ -438,6 +444,9 @@
{ CU::kColorStandardBT2020, CA::PrimariesBT2020 },
{ CU::kColorStandardBT601_525_Unadjusted, CA::PrimariesBT601_6_525 },
{ CU::kColorStandardBT601_625_Unadjusted, CA::PrimariesBT601_6_625 },
+ { CU::kColorStandardDisplay_P3, CA::PrimariesEG432 },
+ // fall back DCI P3 primaries to Display P3
+ { CU::kColorStandardDisplay_P3, CA::PrimariesRP431 },
}
};
@@ -469,7 +478,8 @@
{ CU::kColorStandardBT2020Constant, GET_HAL_BITFIELD(STANDARD, BT2020_CONSTANT_LUMINANCE) },
{ CU::kColorStandardBT470M, GET_HAL_BITFIELD(STANDARD, BT470M) },
{ CU::kColorStandardFilm, GET_HAL_BITFIELD(STANDARD, FILM) },
- { CU::kColorStandardDCI_P3, GET_HAL_BITFIELD(STANDARD, DCI_P3) },
+ // DCI-P3 (in DataSpace that drives this standard) is actually Display P3
+ { CU::kColorStandardDisplay_P3, GET_HAL_BITFIELD(STANDARD, DCI_P3) },
}
};
diff --git a/media/module/foundation/include/media/stagefright/foundation/ColorUtils.h b/media/module/foundation/include/media/stagefright/foundation/ColorUtils.h
index 72c8074..f4e89bb 100644
--- a/media/module/foundation/include/media/stagefright/foundation/ColorUtils.h
+++ b/media/module/foundation/include/media/stagefright/foundation/ColorUtils.h
@@ -57,7 +57,8 @@
kColorStandardBT2020Constant = 7, // not in SDK
kColorStandardBT470M = 8, // not in SDK
kColorStandardFilm = 9, // not in SDK
- kColorStandardDCI_P3 = 10, // not in SDK, new in Android 8.0
+ kColorStandardDisplay_P3 = 10, // not in SDK, new in Android 8.0
+ kColorStandardDCI_P3 = kColorStandardDisplay_P3, // legacy (incorrect) name for Display P3
/* This marks a section of color-standard values that are not supported by graphics HAL,
but track defined color primaries-matrix coefficient combinations in media.
@@ -211,7 +212,7 @@
case ColorUtils::kColorStandardBT2020Constant: return "BT2020Constant";
case ColorUtils::kColorStandardBT470M: return "BT470M";
case ColorUtils::kColorStandardFilm: return "Film";
- case ColorUtils::kColorStandardDCI_P3: return "DCI_P3";
+ case ColorUtils::kColorStandardDisplay_P3: return "Display_P3";
default: return def;
}
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 3c0f8f3..f69307b 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -485,14 +485,17 @@
return mAAudioHwBurstMinMicros;
}
-status_t AudioFlinger::setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) {
+status_t AudioFlinger::setDeviceConnectedState(const struct audio_port_v7 *port,
+ media::DeviceConnectedState state) {
status_t final_result = NO_INIT;
Mutex::Autolock _l(mLock);
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_SET_CONNECTED_STATE;
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
- status_t result = dev->setConnectedState(port, connected);
+ status_t result = state == media::DeviceConnectedState::PREPARE_TO_DISCONNECT
+ ? dev->prepareToDisconnectExternalDevice(port)
+ : dev->setConnectedState(port, state == media::DeviceConnectedState::CONNECTED);
// Same logic as with setParameter: it's a success if at least one
// HAL module accepts the update.
if (final_result != NO_ERROR) {
@@ -1236,21 +1239,20 @@
output.portId = portId;
if (lStatus == NO_ERROR) {
+ // no risk of deadlock because AudioFlinger::mLock is held
+ Mutex::Autolock _dl(thread->mLock);
// Connect secondary outputs. Failure on a secondary output must not imped the primary
// Any secondary output setup failure will lead to a desync between the AP and AF until
// the track is destroyed.
updateSecondaryOutputsForTrack_l(track.get(), thread, secondaryOutputs);
- }
-
- // move effect chain to this output thread if an effect on same session was waiting
- // for a track to be created
- if (lStatus == NO_ERROR && effectThread != NULL) {
- // no risk of deadlock because AudioFlinger::mLock is held
- Mutex::Autolock _dl(thread->mLock);
- Mutex::Autolock _sl(effectThread->mLock);
- if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) {
- effectThreadId = thread->id();
- effectIds = thread->getEffectIds_l(sessionId);
+ // move effect chain to this output thread if an effect on same session was waiting
+ // for a track to be created
+ if (effectThread != nullptr) {
+ Mutex::Autolock _sl(effectThread->mLock);
+ if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) {
+ effectThreadId = thread->id();
+ effectIds = thread->getEffectIds_l(sessionId);
+ }
}
}
@@ -1861,6 +1863,8 @@
String8(AudioParameter::keyStreamSupportedFormats),
String8(AudioParameter::keyStreamSupportedChannels),
String8(AudioParameter::keyStreamSupportedSamplingRates),
+ String8(AudioParameter::keyClosing),
+ String8(AudioParameter::keyExiting),
};
if (isAudioServerUid(callingUid)) {
@@ -3950,7 +3954,7 @@
patchTrack->setPeerProxy(patchRecord, true /* holdReference */);
patchRecord->setPeerProxy(patchTrack, false /* holdReference */);
}
- track->setTeePatches(std::move(teePatches));
+ track->setTeePatchesToUpdate(std::move(teePatches));
}
sp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 323ce0e..47fa74f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -297,7 +297,8 @@
virtual int32_t getAAudioHardwareBurstMinUsec();
- virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected);
+ virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port,
+ media::DeviceConnectedState state);
virtual status_t setSimulateDeviceConnections(bool enabled);
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 19e4151..f324408 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -3407,12 +3407,20 @@
} else if (patch.isSoftware() || patch.thread().promote() != nullptr) {
sp <ThreadBase> thread;
if (audio_port_config_has_input_direction(port)) {
+ if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
+ ALOGI("%s don't create postprocessing effect on record thread", __func__);
+ return NAME_NOT_FOUND;
+ }
if (patch.isSoftware()) {
thread = patch.mRecord.thread();
} else {
thread = patch.thread().promote();
}
} else {
+ if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC) {
+ ALOGI("%s don't create preprocessing effect on playback thread", __func__);
+ return NAME_NOT_FOUND;
+ }
if (patch.isSoftware()) {
thread = patch.mPlayback.thread();
} else {
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index 496aedc..39f772b 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -81,7 +81,7 @@
}
bool AudioFlinger::MelReporter::shouldComputeMelForDeviceType(audio_devices_t device) {
- if (mSoundDoseManager->isCsdDisabled()) {
+ if (!mSoundDoseManager->isCsdEnabled()) {
ALOGV("%s csd is disabled", __func__);
return false;
}
@@ -95,7 +95,6 @@
// TODO(b/278265907): enable A2DP when we can distinguish A2DP headsets
// case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
- case AUDIO_DEVICE_OUT_HEARING_AID:
case AUDIO_DEVICE_OUT_USB_HEADSET:
case AUDIO_DEVICE_OUT_BLE_HEADSET:
case AUDIO_DEVICE_OUT_BLE_BROADCAST:
@@ -107,7 +106,7 @@
void AudioFlinger::MelReporter::updateMetadataForCsd(audio_io_handle_t streamHandle,
const std::vector<playback_track_metadata_v7_t>& metadataVec) {
- if (mSoundDoseManager->isCsdDisabled()) {
+ if (!mSoundDoseManager->isCsdEnabled()) {
ALOGV("%s csd is disabled", __func__);
return;
}
@@ -143,14 +142,10 @@
void AudioFlinger::MelReporter::onCreateAudioPatch(audio_patch_handle_t handle,
const PatchPanel::Patch& patch) {
- if (mSoundDoseManager->isCsdDisabled()) {
+ if (!mSoundDoseManager->isCsdEnabled()) {
ALOGV("%s csd is disabled", __func__);
return;
}
- if (useHalSoundDoseInterface()) {
- ALOGV("%s using HAL sound dose, ignore new patch", __func__);
- return;
- }
ALOGV("%s: handle %d mHalHandle %d device sink %08x",
__func__, handle, patch.mHalHandle,
@@ -199,7 +194,7 @@
ALOGI("%s add stream %d that uses device %d for CSD, nr of streams: %d", __func__,
patch.streamHandle, deviceHandle, mActiveDevices[deviceHandle]);
- if (outputThread != nullptr) {
+ if (outputThread != nullptr && !useHalSoundDoseInterface_l()) {
outputThread->startMelComputation_l(mSoundDoseManager->getOrCreateProcessorForDevice(
deviceHandle,
patch.streamHandle,
@@ -211,7 +206,7 @@
}
void AudioFlinger::MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) {
- if (mSoundDoseManager->isCsdDisabled()) {
+ if (!mSoundDoseManager->isCsdEnabled()) {
ALOGV("%s csd is disabled", __func__);
return;
}
@@ -271,7 +266,7 @@
}
}
- if (outputThread != nullptr) {
+ if (outputThread != nullptr && !useHalSoundDoseInterface_l()) {
outputThread->stopMelComputation_l();
}
}
@@ -287,13 +282,8 @@
return std::nullopt;
}
-bool AudioFlinger::MelReporter::useHalSoundDoseInterface() {
- bool useHalSoundDoseInterface = !mSoundDoseManager->forceUseFrameworkMel();
- {
- std::lock_guard _l(mLock);
- useHalSoundDoseInterface &= mUseHalSoundDoseInterface;
- }
- return useHalSoundDoseInterface;
+bool AudioFlinger::MelReporter::useHalSoundDoseInterface_l() {
+ return !mSoundDoseManager->forceUseFrameworkMel() & mUseHalSoundDoseInterface;
}
std::string AudioFlinger::MelReporter::dump() {
diff --git a/services/audioflinger/MelReporter.h b/services/audioflinger/MelReporter.h
index 81a307a..2bc33f2 100644
--- a/services/audioflinger/MelReporter.h
+++ b/services/audioflinger/MelReporter.h
@@ -98,7 +98,7 @@
std::optional<audio_patch_handle_t>
activePatchStreamHandle_l(audio_io_handle_t streamHandle) REQUIRES(mLock);
- bool useHalSoundDoseInterface();
+ bool useHalSoundDoseInterface_l() REQUIRES(mLock);
AudioFlinger& mAudioFlinger; // does not own the object
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index ad191b0..0e1a3c9 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -186,7 +186,9 @@
}
sp<os::ExternalVibration> getExternalVibration() const { return mExternalVibration; }
- void setTeePatches(TeePatches teePatches);
+ // This function should be called with holding thread lock.
+ void updateTeePatches();
+ void setTeePatchesToUpdate(TeePatches teePatchesToUpdate);
void tallyUnderrunFrames(size_t frames) override {
if (isOut()) { // we expect this from output tracks only
@@ -369,6 +371,7 @@
bool mPauseHwPending = false; // direct/offload track request for thread pause
audio_output_flags_t mFlags;
TeePatches mTeePatches;
+ std::optional<TeePatches> mTeePatchesToUpdate;
const float mSpeed;
const bool mIsSpatialized;
const bool mIsBitPerfect;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 2d33d3c..8d0c648 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4104,6 +4104,10 @@
setHalLatencyMode_l();
+ for (const auto &track : mActiveTracks ) {
+ track->updateTeePatches();
+ }
+
// signal actual start of output stream when the render position reported by the kernel
// starts moving.
if (!mStandby && !mHalStarted && mKernelPositionOnStandby !=
@@ -6243,12 +6247,12 @@
if (status == NO_ERROR) {
status = mOutput->stream->setParameters(keyValuePair);
if (!mStandby && status == INVALID_OPERATION) {
+ ALOGW("%s: setParameters failed with keyValuePair %s, entering standby",
+ __func__, keyValuePair.c_str());
mOutput->standby();
- if (!mStandby) {
- mThreadMetrics.logEndInterval();
- mThreadSnapshot.onEnd();
- setStandby_l();
- }
+ mThreadMetrics.logEndInterval();
+ mThreadSnapshot.onEnd();
+ setStandby_l();
mBytesWritten = 0;
status = mOutput->stream->setParameters(keyValuePair);
}
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 6b5ddce..7d2c4db 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1491,15 +1491,24 @@
*backInserter++ = metadata;
}
-void AudioFlinger::PlaybackThread::Track::setTeePatches(TeePatches teePatches) {
- forEachTeePatchTrack([](auto patchTrack) { patchTrack->destroy(); });
- mTeePatches = std::move(teePatches);
- if (mState == TrackBase::ACTIVE || mState == TrackBase::RESUMING ||
- mState == TrackBase::STOPPING_1) {
- forEachTeePatchTrack([](auto patchTrack) { patchTrack->start(); });
+void AudioFlinger::PlaybackThread::Track::updateTeePatches() {
+ if (mTeePatchesToUpdate.has_value()) {
+ forEachTeePatchTrack([](auto patchTrack) { patchTrack->destroy(); });
+ mTeePatches = mTeePatchesToUpdate.value();
+ if (mState == TrackBase::ACTIVE || mState == TrackBase::RESUMING ||
+ mState == TrackBase::STOPPING_1) {
+ forEachTeePatchTrack([](auto patchTrack) { patchTrack->start(); });
+ }
+ mTeePatchesToUpdate.reset();
}
}
+void AudioFlinger::PlaybackThread::Track::setTeePatchesToUpdate(TeePatches teePatchesToUpdate) {
+ ALOGW_IF(mTeePatchesToUpdate.has_value(),
+ "%s, existing tee patches to update will be ignored", __func__);
+ mTeePatchesToUpdate = std::move(teePatchesToUpdate);
+}
+
// must be called with player thread lock held
void AudioFlinger::PlaybackThread::Track::processMuteEvent_l(const sp<
IAudioManager>& audioManager, mute_state_t muteState)
diff --git a/services/audioflinger/sounddose/SoundDoseManager.cpp b/services/audioflinger/sounddose/SoundDoseManager.cpp
index 827f7d4..a114a38 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.cpp
+++ b/services/audioflinger/sounddose/SoundDoseManager.cpp
@@ -50,7 +50,7 @@
size_t channelCount, audio_format_t format) {
std::lock_guard _l(mLock);
- if (mHalSoundDose != nullptr && !mDisableCsd) {
+ if (mHalSoundDose != nullptr && mEnabledCsd) {
ALOGD("%s: using HAL MEL computation, no MelProcessor needed.", __func__);
return nullptr;
}
@@ -216,7 +216,7 @@
if (id == AUDIO_PORT_HANDLE_NONE) {
ALOGI("%s: no mapped id for audio device with type %d and address %s",
__func__, in_audioDevice.type.type,
- in_audioDevice.address.get<AudioDeviceAddress::id>().c_str());
+ in_audioDevice.address.toString().c_str());
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
soundDoseManager->onMomentaryExposure(in_currentDbA, id);
@@ -243,7 +243,7 @@
if (id == AUDIO_PORT_HANDLE_NONE) {
ALOGI("%s: no mapped id for audio device with type %d and address %s",
__func__, in_audioDevice.type.type,
- in_audioDevice.address.get<AudioDeviceAddress::id>().c_str());
+ in_audioDevice.address.toString().c_str());
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
// TODO: introduce timestamp in onNewMelValues callback
@@ -290,11 +290,11 @@
return binder::Status::ok();
}
-binder::Status SoundDoseManager::SoundDose::disableCsd() {
+binder::Status SoundDoseManager::SoundDose::setCsdEnabled(bool enabled) {
ALOGV("%s", __func__);
auto soundDoseManager = mSoundDoseManager.promote();
if (soundDoseManager != nullptr) {
- soundDoseManager->disableCsd();
+ soundDoseManager->setCsdEnabled(enabled);
}
return binder::Status::ok();
}
@@ -365,26 +365,27 @@
}
}
-void SoundDoseManager::disableCsd() {
+void SoundDoseManager::setCsdEnabled(bool enabled) {
ALOGV("%s", __func__);
std::lock_guard _l(mLock);
- mDisableCsd = true;
+ mEnabledCsd = enabled;
- // Normally, there should be no active MelProcessors when this method is called
- // We pause however every cached MelProcessor as a defensive mechanism to not
- // have unnecessary processing
for (auto& activeEntry : mActiveProcessors) {
auto melProcessor = activeEntry.second.promote();
if (melProcessor != nullptr) {
- melProcessor->pause();
+ if (enabled) {
+ melProcessor->resume();
+ } else {
+ melProcessor->pause();
+ }
}
}
}
-bool SoundDoseManager::isCsdDisabled() {
+bool SoundDoseManager::isCsdEnabled() {
std::lock_guard _l(mLock);
- return mDisableCsd;
+ return mEnabledCsd;
}
void SoundDoseManager::setUseFrameworkMel(bool useFrameworkMel) {
@@ -411,7 +412,7 @@
}
bool SoundDoseManager::isSoundDoseHalSupported() const {
- if (mDisableCsd) {
+ if (!mEnabledCsd) {
return false;
}
@@ -455,7 +456,7 @@
float currentCsd;
{
std::lock_guard _l(mLock);
- if (mDisableCsd) {
+ if (!mEnabledCsd) {
return;
}
@@ -496,7 +497,7 @@
{
std::lock_guard _l(mLock);
- if (mDisableCsd) {
+ if (!mEnabledCsd) {
return;
}
}
@@ -522,7 +523,7 @@
std::string output;
{
std::lock_guard _l(mLock);
- if (mDisableCsd) {
+ if (!mEnabledCsd) {
base::StringAppendF(&output, "CSD is disabled");
return output;
}
diff --git a/services/audioflinger/sounddose/SoundDoseManager.h b/services/audioflinger/sounddose/SoundDoseManager.h
index 5081ce4..6c02afb 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.h
+++ b/services/audioflinger/sounddose/SoundDoseManager.h
@@ -101,8 +101,8 @@
/** Clear all map entries with passed audio_port_handle_t. */
void clearMapDeviceIdEntries(audio_port_handle_t deviceId);
- /** Returns true if CSD is disabled. */
- bool isCsdDisabled();
+ /** Returns true if CSD is enabled. */
+ bool isCsdEnabled();
std::string dump() const;
@@ -137,7 +137,7 @@
const std::vector<media::SoundDoseRecord>& records) override;
binder::Status updateAttenuation(float attenuationDB, int device) override;
binder::Status getOutputRs2UpperBound(float* value) override;
- binder::Status disableCsd() override;
+ binder::Status setCsdEnabled(bool enabled) override;
binder::Status getCsd(float* value) override;
binder::Status forceUseFrameworkMel(bool useFrameworkMel) override;
@@ -170,7 +170,7 @@
sp<media::ISoundDoseCallback> getSoundDoseCallback() const;
void updateAttenuation(float attenuationDB, audio_devices_t deviceType);
- void disableCsd();
+ void setCsdEnabled(bool enabled);
void setUseFrameworkMel(bool useFrameworkMel);
void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices);
bool isSoundDoseHalSupported() const;
@@ -202,7 +202,7 @@
bool mUseFrameworkMel GUARDED_BY(mLock) = true;
bool mComputeCsdOnAllDevices GUARDED_BY(mLock) = false;
- bool mDisableCsd GUARDED_BY(mLock) = false;
+ bool mEnabledCsd GUARDED_BY(mLock) = true;
};
} // namespace android
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 3d1cf76..134d068 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_AUDIOPOLICY_INTERFACE_H
#define ANDROID_AUDIOPOLICY_INTERFACE_H
+#include <android/media/DeviceConnectedState.h>
#include <media/AudioCommonTypes.h>
#include <media/AudioContainers.h>
#include <media/AudioDeviceTypeAddr.h>
@@ -567,7 +568,8 @@
virtual status_t updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs) = 0;
- virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
+ virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port,
+ media::DeviceConnectedState state) = 0;
virtual status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) = 0;
};
diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp
index 92a5628..1d570b7 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.bp
+++ b/services/audiopolicy/common/managerdefinitions/Android.bp
@@ -15,6 +15,7 @@
"src/AudioInputDescriptor.cpp",
"src/AudioOutputDescriptor.cpp",
"src/AudioPatch.cpp",
+ "src/AudioPolicyConfig.cpp",
"src/AudioPolicyMix.cpp",
"src/AudioProfileVectorHelper.cpp",
"src/AudioRoute.cpp",
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index a62d3f0..b24fce8 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -16,62 +16,56 @@
#pragma once
+#include <string>
#include <unordered_map>
#include <unordered_set>
+#include <vector>
-#include <AudioPatch.h>
#include <DeviceDescriptor.h>
-#include <IOProfile.h>
#include <HwModule.h>
-#include <PolicyAudioPort.h>
-#include <AudioInputDescriptor.h>
-#include <AudioOutputDescriptor.h>
-#include <AudioPolicyMix.h>
-#include <EffectDescriptor.h>
-#include <SoundTriggerSession.h>
-#include <media/AudioProfile.h>
+#include <error/Result.h>
+#include <utils/StrongPointer.h>
+#include <utils/RefBase.h>
namespace android {
-// This class gathers together various bits of AudioPolicyManager
-// configuration, which are usually filled out as a result of parsing
-// the audio_policy_configuration.xml file.
+// This class gathers together various bits of AudioPolicyManager configuration. It can be filled
+// out either as a result of parsing the audio_policy_configuration.xml file, from the HAL data, or
+// to default fallback data.
//
-// Note that AudioPolicyConfig doesn't own some of the data,
-// it simply proxies access to the fields of AudioPolicyManager
-// class. Be careful about the fields that are references,
-// e.g. 'mOutputDevices'. This also means that it's impossible
-// to implement "deep copying" of this class without re-designing it.
-class AudioPolicyConfig
+// The data in this class is immutable once loaded, this is why a pointer to a const is returned
+// from the factory methods. However, this does not prevent modifications of data bits that
+// are held inside collections, for example, individual modules, devices, etc.
+class AudioPolicyConfig : public RefBase
{
public:
- AudioPolicyConfig(HwModuleCollection &hwModules,
- DeviceVector &outputDevices,
- DeviceVector &inputDevices,
- sp<DeviceDescriptor> &defaultOutputDevice)
- : mHwModules(hwModules),
- mOutputDevices(outputDevices),
- mInputDevices(inputDevices),
- mDefaultOutputDevice(defaultOutputDevice) {
- clear();
- }
+ // Surround formats, with an optional list of subformats that are equivalent from users' POV.
+ using SurroundFormats = std::unordered_map<audio_format_t, std::unordered_set<audio_format_t>>;
- void clear() {
- mSource = {};
- mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
- mHwModules.clear();
- mOutputDevices.clear();
- mInputDevices.clear();
- mDefaultOutputDevice.clear();
- mIsSpeakerDrcEnabled = false;
- mIsCallScreenModeSupported = false;
- mSurroundFormats.clear();
- }
+ // The source used to indicate the default fallback configuration.
+ static const constexpr char* const kDefaultConfigSource = "AudioPolicyConfig::setDefault";
+
+ // Creates the default (fallback) configuration.
+ static sp<const AudioPolicyConfig> createDefault();
+ // Attempts to load the configuration from the XML file, falls back to default on failure.
+ // If the XML file path is not provided, uses `audio_get_audio_policy_config_file` function.
+ static sp<const AudioPolicyConfig> loadFromApmXmlConfigWithFallback(
+ const std::string& xmlFilePath = "");
+ // The factory method to use in APM tests which craft the configuration manually.
+ static sp<AudioPolicyConfig> createWritableForTests();
+ // The factory method to use in APM tests which use a custom XML file.
+ static error::Result<sp<AudioPolicyConfig>> loadFromCustomXmlConfigForTests(
+ const std::string& xmlFilePath);
+ // The factory method to use in VTS tests. If the 'configPath' is empty,
+ // it is determined automatically from the list of known config paths.
+ static error::Result<sp<AudioPolicyConfig>> loadFromCustomXmlConfigForVtsTests(
+ const std::string& configPath, const std::string& xmlFileName);
+
+ ~AudioPolicyConfig() = default;
const std::string& getSource() const {
return mSource;
}
-
void setSource(const std::string& file) {
mSource = file;
}
@@ -79,16 +73,24 @@
const std::string& getEngineLibraryNameSuffix() const {
return mEngineLibraryNameSuffix;
}
-
void setEngineLibraryNameSuffix(const std::string& suffix) {
mEngineLibraryNameSuffix = suffix;
}
+ const HwModuleCollection& getHwModules() const { return mHwModules; }
void setHwModules(const HwModuleCollection &hwModules)
{
mHwModules = hwModules;
}
+ const DeviceVector& getInputDevices() const
+ {
+ return mInputDevices;
+ }
+ const DeviceVector& getOutputDevices() const
+ {
+ return mOutputDevices;
+ }
void addDevice(const sp<DeviceDescriptor> &device)
{
if (audio_is_output_device(device->type())) {
@@ -97,128 +99,70 @@
mInputDevices.add(device);
}
}
-
void addInputDevices(const DeviceVector &inputDevices)
{
mInputDevices.add(inputDevices);
}
-
void addOutputDevices(const DeviceVector &outputDevices)
{
mOutputDevices.add(outputDevices);
}
- bool isSpeakerDrcEnabled() const { return mIsSpeakerDrcEnabled; }
+ const sp<DeviceDescriptor>& getDefaultOutputDevice() const { return mDefaultOutputDevice; }
+ void setDefaultOutputDevice(const sp<DeviceDescriptor> &defaultDevice)
+ {
+ mDefaultOutputDevice = defaultDevice;
+ }
+ bool isSpeakerDrcEnabled() const { return mIsSpeakerDrcEnabled; }
void setSpeakerDrcEnabled(bool isSpeakerDrcEnabled)
{
mIsSpeakerDrcEnabled = isSpeakerDrcEnabled;
}
bool isCallScreenModeSupported() const { return mIsCallScreenModeSupported; }
-
void setCallScreenModeSupported(bool isCallScreenModeSupported)
{
mIsCallScreenModeSupported = isCallScreenModeSupported;
}
-
- const HwModuleCollection getHwModules() const { return mHwModules; }
-
- const DeviceVector &getInputDevices() const
- {
- return mInputDevices;
- }
-
- const DeviceVector &getOutputDevices() const
- {
- return mOutputDevices;
- }
-
- void setDefaultOutputDevice(const sp<DeviceDescriptor> &defaultDevice)
- {
- mDefaultOutputDevice = defaultDevice;
- }
-
- const sp<DeviceDescriptor> &getDefaultOutputDevice() const { return mDefaultOutputDevice; }
-
- void setDefault(void)
- {
- mSource = "AudioPolicyConfig::setDefault";
- mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
- mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
- mDefaultOutputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat));
- sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
- defaultInputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat));
- sp<AudioProfile> micProfile = new AudioProfile(
- AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000);
- defaultInputDevice->addAudioProfile(micProfile);
- mOutputDevices.add(mDefaultOutputDevice);
- mInputDevices.add(defaultInputDevice);
-
- sp<HwModule> module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY, 2 /*halVersionMajor*/);
- mHwModules.add(module);
-
- sp<OutputProfile> outProfile = new OutputProfile("primary");
- outProfile->addAudioProfile(
- new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100));
- outProfile->addSupportedDevice(mDefaultOutputDevice);
- outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY);
- module->addOutputProfile(outProfile);
-
- sp<InputProfile> inProfile = new InputProfile("primary");
- inProfile->addAudioProfile(micProfile);
- inProfile->addSupportedDevice(defaultInputDevice);
- module->addInputProfile(inProfile);
-
- setDefaultSurroundFormats();
- }
-
- // Surround formats, with an optional list of subformats that are equivalent from users' POV.
- using SurroundFormats = std::unordered_map<audio_format_t, std::unordered_set<audio_format_t>>;
-
const SurroundFormats &getSurroundFormats() const
{
return mSurroundFormats;
}
-
+ void setDefaultSurroundFormats();
void setSurroundFormats(const SurroundFormats &surroundFormats)
{
mSurroundFormats = surroundFormats;
}
-
- void setDefaultSurroundFormats()
+ void setSurroundFormats(SurroundFormats &&surroundFormats)
{
- mSurroundFormats = {
- {AUDIO_FORMAT_AC3, {}},
- {AUDIO_FORMAT_E_AC3, {}},
- {AUDIO_FORMAT_DTS, {}},
- {AUDIO_FORMAT_DTS_HD, {}},
- {AUDIO_FORMAT_DTS_HD_MA, {}},
- {AUDIO_FORMAT_DTS_UHD, {}},
- {AUDIO_FORMAT_DTS_UHD_P2, {}},
- {AUDIO_FORMAT_AAC_LC, {
- AUDIO_FORMAT_AAC_HE_V1, AUDIO_FORMAT_AAC_HE_V2, AUDIO_FORMAT_AAC_ELD,
- AUDIO_FORMAT_AAC_XHE}},
- {AUDIO_FORMAT_DOLBY_TRUEHD, {}},
- {AUDIO_FORMAT_E_AC3_JOC, {}},
- {AUDIO_FORMAT_AC4, {}}};
+ mSurroundFormats = std::move(surroundFormats);
}
+ void setDefault();
+
private:
+ friend class sp<AudioPolicyConfig>;
+
static const constexpr char* const kDefaultEngineLibraryNameSuffix = "default";
- std::string mSource;
- std::string mEngineLibraryNameSuffix;
- HwModuleCollection &mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */
- DeviceVector &mOutputDevices;
- DeviceVector &mInputDevices;
- sp<DeviceDescriptor> &mDefaultOutputDevice;
+ AudioPolicyConfig() = default;
+
+ void augmentData();
+ status_t loadFromXml(const std::string& xmlFilePath, bool forVts);
+
+ std::string mSource; // Not kDefaultConfigSource. Empty source means an empty config.
+ std::string mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
+ HwModuleCollection mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */
+ DeviceVector mOutputDevices;
+ DeviceVector mInputDevices;
+ sp<DeviceDescriptor> mDefaultOutputDevice;
// TODO: remove when legacy conf file is removed. true on devices that use DRC on the
// DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
// Note: remove also speaker_drc_enabled from global configuration of XML config file.
- bool mIsSpeakerDrcEnabled;
- bool mIsCallScreenModeSupported;
+ bool mIsSpeakerDrcEnabled = false;
+ bool mIsCallScreenModeSupported = false;
SurroundFormats mSurroundFormats;
};
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 7ee6566..09ca989 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -701,8 +701,10 @@
}
}
+ // TODO(b/73175392) consider improving the AIDL interface.
+ // Signal closing to A2DP HAL.
AudioParameter param;
- param.add(String8("closing"), String8("true"));
+ param.add(String8(AudioParameter::keyClosing), String8("true"));
mClientInterface->setParameters(mIoHandle, param.toString());
mClientInterface->closeOutput(mIoHandle);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
new file mode 100644
index 0000000..575a6c5
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+#define LOG_TAG "APM_Config"
+
+#include <AudioPolicyConfig.h>
+#include <IOProfile.h>
+#include <Serializer.h>
+#include <media/AudioProfile.h>
+#include <system/audio.h>
+#include <system/audio_config.h>
+#include <utils/Log.h>
+
+namespace android {
+
+// static
+sp<const AudioPolicyConfig> AudioPolicyConfig::createDefault() {
+ auto config = sp<AudioPolicyConfig>::make();
+ config->setDefault();
+ return config;
+}
+
+// static
+sp<const AudioPolicyConfig> AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
+ const std::string& xmlFilePath) {
+ const std::string filePath =
+ xmlFilePath.empty() ? audio_get_audio_policy_config_file() : xmlFilePath;
+ auto config = sp<AudioPolicyConfig>::make();
+ if (status_t status = config->loadFromXml(filePath, false /*forVts*/); status == NO_ERROR) {
+ return config;
+ } else {
+ return createDefault();
+ }
+}
+
+// static
+sp<AudioPolicyConfig> AudioPolicyConfig::createWritableForTests() {
+ return sp<AudioPolicyConfig>::make();
+}
+
+// static
+error::Result<sp<AudioPolicyConfig>> AudioPolicyConfig::loadFromCustomXmlConfigForTests(
+ const std::string& xmlFilePath) {
+ auto config = sp<AudioPolicyConfig>::make();
+ if (status_t status = config->loadFromXml(xmlFilePath, false /*forVts*/); status == NO_ERROR) {
+ return config;
+ } else {
+ return base::unexpected(status);
+ }
+}
+
+// static
+error::Result<sp<AudioPolicyConfig>> AudioPolicyConfig::loadFromCustomXmlConfigForVtsTests(
+ const std::string& configPath, const std::string& xmlFileName) {
+ auto filePath = configPath;
+ if (filePath.empty()) {
+ for (const auto& location : audio_get_configuration_paths()) {
+ std::string path = location + '/' + xmlFileName;
+ if (access(path.c_str(), F_OK) == 0) {
+ filePath = location;
+ break;
+ }
+ }
+ }
+ if (filePath.empty()) {
+ ALOGE("Did not find a config file \"%s\" among known config paths", xmlFileName.c_str());
+ return base::unexpected(BAD_VALUE);
+ }
+ auto config = sp<AudioPolicyConfig>::make();
+ if (status_t status = config->loadFromXml(filePath + "/" + xmlFileName, true /*forVts*/);
+ status == NO_ERROR) {
+ return config;
+ } else {
+ return base::unexpected(status);
+ }
+}
+
+void AudioPolicyConfig::augmentData() {
+ // If microphones address is empty, set it according to device type
+ for (size_t i = 0; i < mInputDevices.size(); i++) {
+ if (mInputDevices[i]->address().empty()) {
+ if (mInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ mInputDevices[i]->setAddress(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+ } else if (mInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
+ mInputDevices[i]->setAddress(AUDIO_BACK_MICROPHONE_ADDRESS);
+ }
+ }
+ }
+}
+
+status_t AudioPolicyConfig::loadFromXml(const std::string& xmlFilePath, bool forVts) {
+ if (xmlFilePath.empty()) {
+ ALOGE("Audio policy configuration file name is empty");
+ return BAD_VALUE;
+ }
+ status_t status = forVts ? deserializeAudioPolicyFileForVts(xmlFilePath.c_str(), this)
+ : deserializeAudioPolicyFile(xmlFilePath.c_str(), this);
+ if (status == NO_ERROR) {
+ mSource = xmlFilePath;
+ augmentData();
+ } else {
+ ALOGE("Could not load audio policy from the configuration file \"%s\": %d",
+ xmlFilePath.c_str(), status);
+ }
+ return status;
+}
+
+void AudioPolicyConfig::setDefault() {
+ mSource = kDefaultConfigSource;
+ mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
+
+ mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
+ mDefaultOutputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat));
+ sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
+ defaultInputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat));
+ sp<AudioProfile> micProfile = new AudioProfile(
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000);
+ defaultInputDevice->addAudioProfile(micProfile);
+ mOutputDevices.add(mDefaultOutputDevice);
+ mInputDevices.add(defaultInputDevice);
+
+ sp<HwModule> module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY, 2 /*halVersionMajor*/);
+ mHwModules.add(module);
+
+ sp<OutputProfile> outProfile = new OutputProfile("primary");
+ outProfile->addAudioProfile(
+ new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100));
+ outProfile->addSupportedDevice(mDefaultOutputDevice);
+ outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY);
+ module->addOutputProfile(outProfile);
+
+ sp<InputProfile> inProfile = new InputProfile("primary");
+ inProfile->addAudioProfile(micProfile);
+ inProfile->addSupportedDevice(defaultInputDevice);
+ module->addInputProfile(inProfile);
+
+ setDefaultSurroundFormats();
+ augmentData();
+}
+
+void AudioPolicyConfig::setDefaultSurroundFormats() {
+ mSurroundFormats = {
+ {AUDIO_FORMAT_AC3, {}},
+ {AUDIO_FORMAT_E_AC3, {}},
+ {AUDIO_FORMAT_DTS, {}},
+ {AUDIO_FORMAT_DTS_HD, {}},
+ {AUDIO_FORMAT_DTS_HD_MA, {}},
+ {AUDIO_FORMAT_DTS_UHD, {}},
+ {AUDIO_FORMAT_DTS_UHD_P2, {}},
+ {AUDIO_FORMAT_AAC_LC, {
+ AUDIO_FORMAT_AAC_HE_V1, AUDIO_FORMAT_AAC_HE_V2, AUDIO_FORMAT_AAC_ELD,
+ AUDIO_FORMAT_AAC_XHE}},
+ {AUDIO_FORMAT_DOLBY_TRUEHD, {}},
+ {AUDIO_FORMAT_E_AC3_JOC, {}},
+ {AUDIO_FORMAT_AC4, {}}};
+}
+
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index d446e96..1b48dc3 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -29,6 +29,7 @@
#include <utils/StrongPointer.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
+#include "IOProfile.h"
#include "Serializer.h"
#include "TypeConverter.h"
@@ -907,7 +908,6 @@
{
PolicySerializer serializer;
status_t status = serializer.deserialize(fileName, config);
- if (status != OK) config->clear();
return status;
}
@@ -915,7 +915,6 @@
{
PolicySerializer serializer;
status_t status = serializer.deserialize(fileName, config, true /*ignoreVendorExtensions*/);
- if (status != OK) config->clear();
return status;
}
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index 7ff0301..bac51f5 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -113,7 +113,7 @@
status_t getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role,
AudioDeviceTypeAddrVector &devices) const override;
- engineConfig::ParsingResult loadAudioPolicyEngineConfig();
+ engineConfig::ParsingResult loadAudioPolicyEngineConfig(const std::string& xmlFilePath = "");
const ProductStrategyMap &getProductStrategies() const { return mProductStrategies; }
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 5769a97..7d6a308 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -115,7 +115,7 @@
return PRODUCT_STRATEGY_NONE;
}
-engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig()
+engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig(const std::string& xmlFilePath)
{
auto loadVolumeConfig = [](auto &volumeGroups, auto &volumeConfig) {
// Ensure name unicity to prevent duplicate
@@ -163,8 +163,9 @@
return stat(path, &fileStat) == 0 && S_ISREG(fileStat.st_mode);
};
- auto result = fileExists(engineConfig::DEFAULT_PATH) ?
- engineConfig::parse(engineConfig::DEFAULT_PATH) : engineConfig::ParsingResult{};
+ const std::string filePath = xmlFilePath.empty() ? engineConfig::DEFAULT_PATH : xmlFilePath;
+ auto result = fileExists(filePath.c_str()) ?
+ engineConfig::parse(filePath.c_str()) : engineConfig::ParsingResult{};
if (result.parsedConfig == nullptr) {
ALOGD("%s: No configuration found, using default matching phone experience.", __FUNCTION__);
engineConfig::Config config = gDefaultEngineConfig;
diff --git a/services/audiopolicy/engine/interface/EngineInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
index ea8fc41..dd7ac1a 100644
--- a/services/audiopolicy/engine/interface/EngineInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -16,6 +16,7 @@
#pragma once
+#include <string>
#include <utility>
#include <AudioPolicyManagerObserver.h>
@@ -46,6 +47,13 @@
{
public:
/**
+ * Loads the engine configuration from the specified or the default config file.
+ * If loading failed, tries to fall back to some default configuration. If fallback
+ * is impossible, returns an error.
+ */
+ virtual status_t loadFromXmlConfigWithFallback(const std::string& xmlFilePath = "") = 0;
+
+ /**
* Checks if the engine was correctly initialized.
*
* @return NO_ERROR if initialization has been done correctly, error code otherwise..
diff --git a/services/audiopolicy/engineconfigurable/src/Collection.h b/services/audiopolicy/engineconfigurable/src/Collection.h
index 02b41cb..4640515 100644
--- a/services/audiopolicy/engineconfigurable/src/Collection.h
+++ b/services/audiopolicy/engineconfigurable/src/Collection.h
@@ -53,6 +53,10 @@
{
collectionSupported();
}
+ ~Collection()
+ {
+ clear();
+ }
/**
* Add a policy element to the collection. Policy elements are streams, strategies, input
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index a7f92cd..dad663e 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -68,16 +68,15 @@
Engine::Engine() : mPolicyParameterMgr(new ParameterManagerWrapper())
{
- status_t loadResult = loadAudioPolicyEngineConfig();
+}
+
+status_t Engine::loadFromXmlConfigWithFallback(const std::string& xmlFilePath)
+{
+ status_t loadResult = loadAudioPolicyEngineConfig(xmlFilePath);
if (loadResult < 0) {
ALOGE("Policy Engine configuration is invalid.");
}
-}
-
-Engine::~Engine()
-{
- mStreamCollection.clear();
- mInputSourceCollection.clear();
+ return loadResult;
}
status_t Engine::initCheck()
@@ -194,9 +193,9 @@
return EngineBase::setDeviceConnectionState(device, state);
}
-status_t Engine::loadAudioPolicyEngineConfig()
+status_t Engine::loadAudioPolicyEngineConfig(const std::string& xmlFilePath)
{
- auto result = EngineBase::loadAudioPolicyEngineConfig();
+ auto result = EngineBase::loadAudioPolicyEngineConfig(xmlFilePath);
// Custom XML Parsing
auto loadCriteria= [this](const auto& configCriteria, const auto& configCriterionTypes) {
@@ -531,5 +530,3 @@
} // namespace audio_policy
} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index 8ea8052..b964cd6 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -33,12 +33,17 @@
{
public:
Engine();
- virtual ~Engine();
+ virtual ~Engine() = default;
template <class RequestedInterface>
RequestedInterface *queryInterface();
///
+ /// from EngineInterface
+ ///
+ android::status_t loadFromXmlConfigWithFallback(const std::string& xmlFilePath = "") override;
+
+ ///
/// from EngineBase
///
android::status_t initCheck() override;
@@ -132,7 +137,7 @@
template <typename Property, typename Key>
bool setPropertyForKey(const Property &property, const Key &key);
- status_t loadAudioPolicyEngineConfig();
+ status_t loadAudioPolicyEngineConfig(const std::string& xmlFilePath);
DeviceVector getCachedDevices(product_strategy_t ps) const;
@@ -150,4 +155,3 @@
} // namespace audio_policy
} // namespace android
-
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 84e7cb8..88cbb7d 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -59,9 +59,8 @@
return legacyStrategy;
}
-Engine::Engine()
-{
- auto result = EngineBase::loadAudioPolicyEngineConfig();
+status_t Engine::loadFromXmlConfigWithFallback(const std::string& xmlFilePath) {
+ auto result = EngineBase::loadAudioPolicyEngineConfig(xmlFilePath);
ALOGE_IF(result.nbSkippedElement != 0,
"Policy Engine configuration is partially invalid, skipped %zu elements",
result.nbSkippedElement);
@@ -70,6 +69,8 @@
for (const auto &strategy : legacyStrategy) {
mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
}
+
+ return OK;
}
status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
@@ -845,5 +846,3 @@
} // namespace audio_policy
} // namespace android
-
-
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index 2e4decf..8410560 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -45,9 +45,14 @@
class Engine : public EngineBase
{
public:
- Engine();
+ Engine() = default;
virtual ~Engine() = default;
+ ///
+ /// from EngineInterface
+ ///
+ status_t loadFromXmlConfigWithFallback(const std::string& xmlFilePath = "") override;
+
private:
///
/// from EngineBase, so from EngineInterface
@@ -105,4 +110,3 @@
};
} // namespace audio_policy
} // namespace android
-
diff --git a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
index 14f565b..8793085 100644
--- a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
+++ b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
@@ -216,8 +216,9 @@
virtual void process();
protected:
+ sp<AudioPolicyConfig> mConfig{AudioPolicyConfig::createWritableForTests()};
std::unique_ptr<AudioPolicyManagerTestClient> mClient{new AudioPolicyManagerTestClient};
- std::unique_ptr<AudioPolicyTestManager> mManager{new AudioPolicyTestManager(mClient.get())};
+ std::unique_ptr<AudioPolicyTestManager> mManager;
FuzzedDataProvider *mFdp;
};
@@ -230,7 +231,10 @@
}
// init code
SetUpManagerConfig();
-
+ if (mConfig == nullptr) {
+ return false;
+ }
+ mManager.reset(new AudioPolicyTestManager(mConfig, mClient.get()));
if (mManager->initialize() != NO_ERROR) {
return false;
}
@@ -240,7 +244,7 @@
return true;
}
-void AudioPolicyManagerFuzzer::SetUpManagerConfig() { mManager->getConfig().setDefault(); }
+void AudioPolicyManagerFuzzer::SetUpManagerConfig() { mConfig->setDefault(); }
bool AudioPolicyManagerFuzzer::getOutputForAttr(
audio_port_handle_t *selectedDeviceId, audio_format_t format, audio_channel_mask_t channelMask,
@@ -408,7 +412,11 @@
}
void AudioPolicyManagerFuzzerWithConfigurationFile::SetUpManagerConfig() {
- deserializeAudioPolicyFile(getConfigFile().c_str(), &mManager->getConfig());
+ const std::string configFilePath = getConfigFile();
+ auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(configFilePath);
+ mConfig = result.ok() ? mConfig = result.value() : nullptr;
+ ALOGE_IF(!result.ok(), "%s: Failed to deserialize \"%s\": %d",
+ __func__, configFilePath.c_str(), result.error());
}
void AudioPolicyManagerFuzzerWithConfigurationFile::traverseAndFuzzXML(xmlDocPtr pDoc,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 56a692b..e087d8a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -116,14 +116,13 @@
}
void AudioPolicyManager::broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
- audio_policy_dev_state_t state)
+ media::DeviceConnectedState state)
{
audio_port_v7 devicePort;
device->toAudioPort(&devicePort);
- if (status_t status = mpClientInterface->setDeviceConnectedState(
- &devicePort, state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
+ if (status_t status = mpClientInterface->setDeviceConnectedState(&devicePort, state);
status != OK) {
- ALOGE("Error %d while setting connected state for device %s", status,
+ ALOGE("Error %d while setting connected state for device %s", state,
device->getDeviceTypeAddr().toString(false).c_str());
}
}
@@ -206,14 +205,14 @@
// Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the outputs...)
- broadcastDeviceConnectionState(device, state);
+ broadcastDeviceConnectionState(device, media::DeviceConnectedState::CONNECTED);
if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) {
mAvailableOutputDevices.remove(device);
mHwModules.cleanUpForDevice(device);
- broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
+ broadcastDeviceConnectionState(device, media::DeviceConnectedState::DISCONNECTED);
return INVALID_OPERATION;
}
@@ -235,8 +234,9 @@
ALOGV("%s() disconnecting output device %s", __func__, device->toString().c_str());
- // Send Disconnect to HALs
- broadcastDeviceConnectionState(device, state);
+ // Notify the HAL to prepare to disconnect device
+ broadcastDeviceConnectionState(
+ device, media::DeviceConnectedState::PREPARE_TO_DISCONNECT);
// remove device from available output devices
mAvailableOutputDevices.remove(device);
@@ -245,6 +245,9 @@
checkOutputsForDevice(device, state, outputs);
+ // Send Disconnect to HALs
+ broadcastDeviceConnectionState(device, media::DeviceConnectedState::DISCONNECTED);
+
// Reset active device codec
device->setEncodedFormat(AUDIO_FORMAT_DEFAULT);
@@ -384,12 +387,12 @@
// Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the inputs...)
- broadcastDeviceConnectionState(device, state);
+ broadcastDeviceConnectionState(device, media::DeviceConnectedState::CONNECTED);
if (checkInputsForDevice(device, state) != NO_ERROR) {
mAvailableInputDevices.remove(device);
- broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
+ broadcastDeviceConnectionState(device, media::DeviceConnectedState::DISCONNECTED);
mHwModules.cleanUpForDevice(device);
@@ -407,13 +410,17 @@
ALOGV("%s() disconnecting input device %s", __func__, device->toString().c_str());
- // Set Disconnect to HALs
- broadcastDeviceConnectionState(device, state);
+ // Notify the HAL to prepare to disconnect device
+ broadcastDeviceConnectionState(
+ device, media::DeviceConnectedState::PREPARE_TO_DISCONNECT);
mAvailableInputDevices.remove(device);
checkInputsForDevice(device, state);
+ // Set Disconnect to HALs
+ broadcastDeviceConnectionState(device, media::DeviceConnectedState::DISCONNECTED);
+
// remove device from mReportedFormatsMap cache
mReportedFormatsMap.erase(device);
} break;
@@ -1323,7 +1330,7 @@
*selectedDeviceId = getFirstDeviceId(outputDevices);
for (auto &outputDevice : outputDevices) {
- if (outputDevice->getId() == getConfig().getDefaultOutputDevice()->getId()) {
+ if (outputDevice->getId() == mConfig->getDefaultOutputDevice()->getId()) {
*selectedDeviceId = outputDevice->getId();
break;
}
@@ -1908,7 +1915,8 @@
}
bool AudioPolicyManager::msdHasPatchesToAllDevices(const AudioDeviceTypeAddrVector& devices) {
- DeviceVector devicesToCheck = mOutputDevicesAll.getDevicesFromDeviceTypeAddrVec(devices);
+ DeviceVector devicesToCheck =
+ mConfig->getOutputDevices().getDevicesFromDeviceTypeAddrVec(devices);
AudioPatchCollection msdPatches = getMsdOutputPatches();
for (size_t i = 0; i < msdPatches.size(); i++) {
const auto& patch = msdPatches[i];
@@ -4099,13 +4107,13 @@
dst->appendFormat(" TTS output %savailable\n", mTtsOutputAvailable ? "" : "not ");
dst->appendFormat(" Master mono: %s\n", mMasterMono ? "on" : "off");
dst->appendFormat(" Communication Strategy id: %d\n", mCommunnicationStrategy);
- dst->appendFormat(" Config source: %s\n", mConfig.getSource().c_str()); // getConfig not const
+ dst->appendFormat(" Config source: %s\n", mConfig->getSource().c_str());
dst->append("\n");
mAvailableOutputDevices.dump(dst, String8("Available output"), 1);
dst->append("\n");
mAvailableInputDevices.dump(dst, String8("Available input"), 1);
- mHwModulesAll.dump(dst);
+ mHwModules.dump(dst);
mOutputs.dump(dst);
mInputs.dump(dst);
mEffects.dump(dst, 1);
@@ -4612,7 +4620,7 @@
return OK;
};
- for (const auto& module : mHwModulesAll) {
+ for (const auto& module : mHwModules) {
for (const auto& dev : module->getDeclaredDevices()) {
if (role == media::AudioPortRole::NONE ||
((role == media::AudioPortRole::SOURCE)
@@ -5519,10 +5527,10 @@
size_t formatsWritten = 0;
size_t formatsMax = *numSurroundFormats;
- *numSurroundFormats = mConfig.getSurroundFormats().size();
+ *numSurroundFormats = mConfig->getSurroundFormats().size();
audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
- for (const auto& format: mConfig.getSurroundFormats()) {
+ for (const auto& format: mConfig->getSurroundFormats()) {
if (formatsWritten < formatsMax) {
surroundFormats[formatsWritten] = format.first;
bool formatEnabled = true;
@@ -5575,10 +5583,10 @@
formatset.insert(encodedFormats.begin(), encodedFormats.end());
// Filter the formats which are supported by the vendor hardware.
for (auto it = formatset.begin(); it != formatset.end(); ++it) {
- if (mConfig.getSurroundFormats().count(*it) != 0) {
+ if (mConfig->getSurroundFormats().count(*it) != 0) {
formats.insert(*it);
} else {
- for (const auto& pair : mConfig.getSurroundFormats()) {
+ for (const auto& pair : mConfig->getSurroundFormats()) {
if (pair.second.count(*it) != 0) {
formats.insert(pair.first);
break;
@@ -5599,8 +5607,8 @@
status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
{
ALOGV("%s() format 0x%X enabled %d", __func__, audioFormat, enabled);
- const auto& formatIter = mConfig.getSurroundFormats().find(audioFormat);
- if (formatIter == mConfig.getSurroundFormats().end()) {
+ const auto& formatIter = mConfig->getSurroundFormats().find(audioFormat);
+ if (formatIter == mConfig->getSurroundFormats().end()) {
ALOGW("%s() format 0x%X is not a known surround format", __func__, audioFormat);
return BAD_VALUE;
}
@@ -5755,7 +5763,7 @@
bool AudioPolicyManager::isCallScreenModeSupported()
{
- return getConfig().isCallScreenModeSupported();
+ return mConfig->isCallScreenModeSupported();
}
@@ -5988,26 +5996,16 @@
return mAudioPortGeneration++;
}
-static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
- if (std::string audioPolicyXmlConfigFile = audio_get_audio_policy_config_file();
- !audioPolicyXmlConfigFile.empty()) {
- status_t ret = deserializeAudioPolicyFile(audioPolicyXmlConfigFile.c_str(), &config);
- if (ret == NO_ERROR) {
- config.setSource(audioPolicyXmlConfigFile);
- }
- return ret;
- }
- return BAD_VALUE;
-}
-
-AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
- bool /*forTesting*/)
+AudioPolicyManager::AudioPolicyManager(const sp<const AudioPolicyConfig>& config,
+ EngineInstance&& engine,
+ AudioPolicyClientInterface *clientInterface)
:
mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.
+ mConfig(config),
+ mEngine(std::move(engine)),
mpClientInterface(clientInterface),
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false),
- mConfig(mHwModulesAll, mOutputDevicesAll, mInputDevicesAll, mDefaultOutputDevice),
mAudioPortGeneration(1),
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
@@ -6018,32 +6016,9 @@
{
}
-AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
- : AudioPolicyManager(clientInterface, false /*forTesting*/)
-{
- loadConfig();
-}
-
-void AudioPolicyManager::loadConfig() {
- if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
- ALOGE("could not load audio policy configuration file, setting defaults");
- getConfig().setDefault();
- }
-}
-
status_t AudioPolicyManager::initialize() {
- {
- auto engLib = EngineLibrary::load(
- "libaudiopolicyengine" + getConfig().getEngineLibraryNameSuffix() + ".so");
- if (!engLib) {
- ALOGE("%s: Failed to load the engine library", __FUNCTION__);
- return NO_INIT;
- }
- mEngine = engLib->createEngine();
- if (mEngine == nullptr) {
- ALOGE("%s: Failed to instantiate the APM engine", __FUNCTION__);
- return NO_INIT;
- }
+ if (mEngine == nullptr) {
+ return NO_INIT;
}
mEngine->setObserver(this);
status_t status = mEngine->initCheck();
@@ -6052,31 +6027,22 @@
return status;
}
- // If microphones address is empty, set it according to device type
- for (size_t i = 0; i < mInputDevicesAll.size(); i++) {
- if (mInputDevicesAll[i]->address().empty()) {
- if (mInputDevicesAll[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
- mInputDevicesAll[i]->setAddress(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
- } else if (mInputDevicesAll[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
- mInputDevicesAll[i]->setAddress(AUDIO_BACK_MICROPHONE_ADDRESS);
- }
- }
- }
-
// The actual device selection cache will be updated when calling `updateDevicesAndOutputs`
// at the end of this function.
mEngine->initializeDeviceSelectionCache();
mCommunnicationStrategy = mEngine->getProductStrategyForAttributes(
mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL));
- // after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
+ // after parsing the config, mConfig contain all known devices;
// open all output streams needed to access attached devices
onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
// make sure default device is reachable
- if (mDefaultOutputDevice == 0 || !mAvailableOutputDevices.contains(mDefaultOutputDevice)) {
- ALOGE_IF(mDefaultOutputDevice != 0, "Default device %s is unreachable",
- mDefaultOutputDevice->toString().c_str());
+ if (const auto defaultOutputDevice = mConfig->getDefaultOutputDevice();
+ defaultOutputDevice == nullptr ||
+ !mAvailableOutputDevices.contains(defaultOutputDevice)) {
+ ALOGE_IF(defaultOutputDevice != nullptr, "Default device %s is unreachable",
+ defaultOutputDevice->toString().c_str());
status = NO_INIT;
}
ALOGW_IF(mPrimaryOutput == nullptr, "The policy configuration does not declare a primary output");
@@ -6101,8 +6067,8 @@
mOutputs.clear();
mInputs.clear();
mHwModules.clear();
- mHwModulesAll.clear();
mManualSurroundFormats.clear();
+ mConfig.clear();
}
status_t AudioPolicyManager::initCheck()
@@ -6124,7 +6090,7 @@
void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
{
- for (const auto& hwModule : mHwModulesAll) {
+ for (const auto& hwModule : mConfig->getHwModules()) {
if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
continue;
}
@@ -6153,10 +6119,10 @@
}
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
- DeviceVector availProfileDevices = supportedDevices.filter(mOutputDevicesAll);
+ DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getOutputDevices());
sp<DeviceDescriptor> supportedDevice = 0;
- if (supportedDevices.contains(mDefaultOutputDevice)) {
- supportedDevice = mDefaultOutputDevice;
+ if (supportedDevices.contains(mConfig->getDefaultOutputDevice())) {
+ supportedDevice = mConfig->getDefaultOutputDevice();
} else {
// choose first device present in profile's SupportedDevices also part of
// mAvailableOutputDevices.
@@ -6165,7 +6131,7 @@
}
supportedDevice = availProfileDevices.itemAt(0);
}
- if (!mOutputDevicesAll.contains(supportedDevice)) {
+ if (!mConfig->getOutputDevices().contains(supportedDevice)) {
continue;
}
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
@@ -6220,7 +6186,7 @@
// chose first device present in profile's SupportedDevices also part of
// available input devices
const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
- DeviceVector availProfileDevices = supportedDevices.filter(mInputDevicesAll);
+ DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getInputDevices());
if (availProfileDevices.isEmpty()) {
ALOGV("%s: Input device list is empty! for profile %s",
__func__, inProfile->getTagName().c_str());
@@ -7980,7 +7946,7 @@
std::unordered_set<audio_format_t> enforcedSurround(
devDesc->encodedFormats().begin(), devDesc->encodedFormats().end());
std::unordered_set<audio_format_t> allSurround; // A flat set of all known surround formats
- for (const auto& pair : mConfig.getSurroundFormats()) {
+ for (const auto& pair : mConfig->getSurroundFormats()) {
allSurround.insert(pair.first);
for (const auto& subformat : pair.second) allSurround.insert(subformat);
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 2924ee1..88bafef 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -35,6 +35,7 @@
#include <media/PatchBuilder.h>
#include "AudioPolicyInterface.h"
+#include <android/media/DeviceConnectedState.h>
#include <android/media/audio/common/AudioPort.h>
#include <AudioPolicyManagerObserver.h>
#include <AudioPolicyConfig.h>
@@ -93,7 +94,9 @@
{
public:
- explicit AudioPolicyManager(AudioPolicyClientInterface *clientInterface);
+ AudioPolicyManager(const sp<const AudioPolicyConfig>& config,
+ EngineInstance&& engine,
+ AudioPolicyClientInterface *clientInterface);
virtual ~AudioPolicyManager();
// AudioPolicyInterface
@@ -426,19 +429,7 @@
status_t initialize();
protected:
- // A constructor that allows more fine-grained control over initialization process,
- // used in automatic tests.
- AudioPolicyManager(AudioPolicyClientInterface *clientInterface, bool forTesting);
-
- // These methods should be used when finer control over APM initialization
- // is needed, e.g. in tests. Must be used in conjunction with the constructor
- // that only performs fields initialization. The public constructor comprises
- // these steps in the following sequence:
- // - field initializing constructor;
- // - loadConfig;
- // - initialize.
- AudioPolicyConfig& getConfig() { return mConfig; }
- void loadConfig();
+ const AudioPolicyConfig& getConfig() const { return *(mConfig.get()); }
// From AudioPolicyManagerObserver
virtual const AudioPatchCollection &getAudioPatches() const
@@ -472,7 +463,7 @@
}
virtual const sp<DeviceDescriptor> &getDefaultOutputDevice() const
{
- return mDefaultOutputDevice;
+ return mConfig->getDefaultOutputDevice();
}
std::vector<volume_group_t> getVolumeGroups() const
@@ -931,6 +922,8 @@
sp<SwAudioOutputDescriptor> ignoredOutput, uint32_t delayMs);
const uid_t mUidCached; // AID_AUDIOSERVER
+ sp<const AudioPolicyConfig> mConfig;
+ EngineInstance mEngine; // Audio Policy Engine instance
AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
sp<SwAudioOutputDescriptor> mPrimaryOutput; // primary output descriptor
// list of descriptors for outputs currently opened
@@ -943,8 +936,6 @@
SwAudioOutputCollection mPreviousOutputs;
AudioInputCollection mInputs; // list of input descriptors
- DeviceVector mOutputDevicesAll; // all output devices from the config
- DeviceVector mInputDevicesAll; // all input devices from the config
DeviceVector mAvailableOutputDevices; // all available output devices
DeviceVector mAvailableInputDevices; // all available input devices
@@ -954,11 +945,7 @@
bool mA2dpSuspended; // true if A2DP output is suspended
EffectDescriptorCollection mEffects; // list of registered audio effects
- sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
HwModuleCollection mHwModules; // contains modules that have been loaded successfully
- HwModuleCollection mHwModulesAll; // contains all modules declared in the config
-
- AudioPolicyConfig mConfig;
std::atomic<uint32_t> mAudioPortGeneration;
@@ -989,9 +976,6 @@
uint32_t nextAudioPortGeneration();
- // Audio Policy Engine Interface.
- EngineInstance mEngine;
-
// Surround formats that are enabled manually. Taken into account when
// "encoded surround" is forced into "manual" mode.
std::unordered_set<audio_format_t> mManualSurroundFormats;
@@ -1060,13 +1044,16 @@
void updateAudioProfiles(const sp<DeviceDescriptor>& devDesc, audio_io_handle_t ioHandle,
AudioProfileVector &profiles);
+ // Notify the policy client to prepare for disconnecting external device.
+ void prepareToDisconnectExternalDevice(const sp<DeviceDescriptor> &device);
+
// Notify the policy client of any change of device state with AUDIO_IO_HANDLE_NONE,
// so that the client interprets it as global to audio hardware interfaces.
// It can give a chance to HAL implementer to retrieve dynamic capabilities associated
// to this device for example.
// TODO avoid opening stream to retrieve capabilities of a profile.
void broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
- audio_policy_dev_state_t state);
+ media::DeviceConnectedState state);
// updates device caching and output for streams that can influence the
// routing of notifications
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.cpp b/services/audiopolicy/managerdefault/EngineLibrary.cpp
index ef699aa..939fbc5 100644
--- a/services/audiopolicy/managerdefault/EngineLibrary.cpp
+++ b/services/audiopolicy/managerdefault/EngineLibrary.cpp
@@ -23,9 +23,27 @@
namespace android {
-// static
-std::shared_ptr<EngineLibrary> EngineLibrary::load(std::string libraryPath)
+EngineInstance loadApmEngineLibraryAndCreateEngine(const std::string& librarySuffix,
+ const std::string& configXmlFilePath)
{
+ auto engLib = EngineLibrary::load(librarySuffix);
+ if (!engLib) {
+ ALOGE("%s: Failed to load the engine library, suffix \"%s\"",
+ __func__, librarySuffix.c_str());
+ return nullptr;
+ }
+ auto engine = engLib->createEngineUsingXmlConfig(configXmlFilePath);
+ if (engine == nullptr) {
+ ALOGE("%s: Failed to instantiate the APM engine", __func__);
+ return nullptr;
+ }
+ return engine;
+}
+
+// static
+std::shared_ptr<EngineLibrary> EngineLibrary::load(const std::string& librarySuffix)
+{
+ std::string libraryPath = "libaudiopolicyengine" + librarySuffix + ".so";
std::shared_ptr<EngineLibrary> engLib(new EngineLibrary());
return engLib->init(std::move(libraryPath)) ? engLib : nullptr;
}
@@ -35,6 +53,20 @@
close();
}
+EngineInstance EngineLibrary::createEngineUsingXmlConfig(const std::string& xmlFilePath) {
+ auto instance = createEngine();
+ if (instance != nullptr) {
+ if (status_t status = instance->loadFromXmlConfigWithFallback(xmlFilePath);
+ status == OK) {
+ return instance;
+ } else {
+ ALOGE("%s: loading of the engine config with XML configuration file \"%s\" failed: %d",
+ __func__, xmlFilePath.empty() ? "default" : xmlFilePath.c_str(), status);
+ }
+ }
+ return nullptr;
+}
+
bool EngineLibrary::init(std::string libraryPath)
{
mLibraryHandle = dlopen(libraryPath.c_str(), 0);
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.h b/services/audiopolicy/managerdefault/EngineLibrary.h
index f143916..dc138a1 100644
--- a/services/audiopolicy/managerdefault/EngineLibrary.h
+++ b/services/audiopolicy/managerdefault/EngineLibrary.h
@@ -26,9 +26,12 @@
using EngineInstance = std::unique_ptr<EngineInterface, std::function<void (EngineInterface*)>>;
+EngineInstance loadApmEngineLibraryAndCreateEngine(const std::string& librarySuffix,
+ const std::string& configXmlFilePath = "");
+
class EngineLibrary : public std::enable_shared_from_this<EngineLibrary> {
public:
- static std::shared_ptr<EngineLibrary> load(std::string libraryPath);
+ static std::shared_ptr<EngineLibrary> load(const std::string& librarySuffix);
~EngineLibrary();
EngineLibrary(const EngineLibrary&) = delete;
@@ -36,11 +39,12 @@
EngineLibrary& operator=(const EngineLibrary&) = delete;
EngineLibrary& operator=(EngineLibrary&&) = delete;
- EngineInstance createEngine();
+ EngineInstance createEngineUsingXmlConfig(const std::string& xmlFilePath);
private:
EngineLibrary() = default;
bool init(std::string libraryPath);
+ EngineInstance createEngine();
void close();
void *mLibraryHandle = nullptr;
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index 10403fa..2f677da 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -52,8 +52,9 @@
"libsensor",
"libsensorprivacy",
"libshmemcompat",
- "libutils",
"libstagefright_foundation",
+ "libutils",
+ "libxml2",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 1bb89df..887f210 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -309,13 +309,13 @@
}
status_t AudioPolicyService::AudioPolicyClient::setDeviceConnectedState(
- const struct audio_port_v7 *port, bool connected) {
+ const struct audio_port_v7 *port, media::DeviceConnectedState state) {
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == nullptr) {
ALOGW("%s: could not get AudioFlinger", __func__);
return PERMISSION_DENIED;
}
- return af->setDeviceConnectedState(port, connected);
+ return af->setDeviceConnectedState(port, state);
}
status_t AudioPolicyService::AudioPolicyClient::invalidateTracks(
@@ -328,5 +328,4 @@
return af->invalidateTracks(portIds);
}
-
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index c7a60c2..b111865 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -41,26 +41,25 @@
// AudioPolicyEffects Implementation
// ----------------------------------------------------------------------------
-AudioPolicyEffects::AudioPolicyEffects()
-{
- status_t loadResult = loadAudioEffectXmlConfig();
+AudioPolicyEffects::AudioPolicyEffects(const sp<EffectsFactoryHalInterface>& effectsFactoryHal) {
+ // load xml config with effectsFactoryHal
+ status_t loadResult = loadAudioEffectConfig(effectsFactoryHal);
if (loadResult == NO_ERROR) {
- mDefaultDeviceEffectFuture = std::async(
- std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
+ mDefaultDeviceEffectFuture =
+ std::async(std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
} else if (loadResult < 0) {
- ALOGW("Failed to load XML effect configuration, fallback to .conf");
+ ALOGW("Failed to query effect configuration, fallback to load .conf");
// load automatic audio effect modules
if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
- loadAudioEffectConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
+ loadAudioEffectConfigLegacy(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
} else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
- loadAudioEffectConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+ loadAudioEffectConfigLegacy(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
}
} else if (loadResult > 0) {
ALOGE("Effect config is partially invalid, skipped %d elements", loadResult);
}
}
-
AudioPolicyEffects::~AudioPolicyEffects()
{
size_t i = 0;
@@ -907,10 +906,18 @@
return NO_ERROR;
}
-status_t AudioPolicyEffects::loadAudioEffectXmlConfig() {
- auto result = effectsConfig::parse();
- if (result.parsedConfig == nullptr) {
- return -ENOENT;
+status_t AudioPolicyEffects::loadAudioEffectConfig(
+ const sp<EffectsFactoryHalInterface>& effectsFactoryHal) {
+ if (!effectsFactoryHal) {
+ ALOGE("%s Null EffectsFactoryHalInterface", __func__);
+ return UNEXPECTED_NULL;
+ }
+
+ const auto skippedElements = VALUE_OR_RETURN_STATUS(effectsFactoryHal->getSkippedElements());
+ const auto processings = effectsFactoryHal->getProcessings();
+ if (!processings) {
+ ALOGE("%s Null processings with %zu skipped elements", __func__, skippedElements);
+ return UNEXPECTED_NULL;
}
auto loadProcessingChain = [](auto& processingChain, auto& streams) {
@@ -924,9 +931,8 @@
}
};
- auto loadDeviceProcessingChain = [](auto &processingChain, auto& devicesEffects) {
+ auto loadDeviceProcessingChain = [](auto& processingChain, auto& devicesEffects) {
for (auto& deviceProcess : processingChain) {
-
auto effectDescs = std::make_unique<EffectDescVector>();
for (auto& effect : deviceProcess.effects) {
effectDescs->mEffects.add(
@@ -938,17 +944,18 @@
}
};
- loadProcessingChain(result.parsedConfig->preprocess, mInputSources);
- loadProcessingChain(result.parsedConfig->postprocess, mOutputStreams);
+ loadProcessingChain(processings->preprocess, mInputSources);
+ loadProcessingChain(processings->postprocess, mOutputStreams);
+
{
Mutex::Autolock _l(mLock);
- loadDeviceProcessingChain(result.parsedConfig->deviceprocess, mDeviceEffects);
+ loadDeviceProcessingChain(processings->deviceprocess, mDeviceEffects);
}
- // Casting from ssize_t to status_t is probably safe, there should not be more than 2^31 errors
- return result.nbSkippedElement;
+
+ return skippedElements;
}
-status_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)
+status_t AudioPolicyEffects::loadAudioEffectConfigLegacy(const char *path)
{
cnode *root;
char *data;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 13d5d0c..9f65a96 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -20,22 +20,33 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <future>
+
+#include <android-base/thread_annotations.h>
#include <cutils/misc.h>
#include <media/AudioEffect.h>
+#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <system/audio.h>
#include <utils/Vector.h>
#include <utils/SortedVector.h>
-#include <android-base/thread_annotations.h>
-
-#include <future>
namespace android {
// ----------------------------------------------------------------------------
-// AudioPolicyEffects class
-// This class will manage all effects attached to input and output streams in
-// AudioPolicyService as configured in audio_effects.conf.
+/**
+ * AudioPolicyEffects class.
+ *
+ * This class manages all effects attached to input and output streams in AudioPolicyService.
+ * The effect configurations can be queried in several ways:
+ *
+ * With HIDL HAL, the configuration file `audio_effects.xml` will be loaded by libAudioHal. If this
+ * file does not exist, AudioPolicyEffects class will fallback to load configuration from
+ * `/vendor/etc/audio_effects.conf` (AUDIO_EFFECT_VENDOR_CONFIG_FILE). If this file also does not
+ * exist, the configuration will be loaded from the file `/system/etc/audio_effects.conf`.
+ *
+ * With AIDL HAL, the configuration will be queried with the method `IFactory::queryProcessing()`.
+ */
class AudioPolicyEffects : public RefBase
{
@@ -44,7 +55,7 @@
// The constructor will parse audio_effects.conf
// First it will look whether vendor specific file exists,
// otherwise it will parse the system default file.
- AudioPolicyEffects();
+ explicit AudioPolicyEffects(const sp<EffectsFactoryHalInterface>& effectsFactoryHal);
virtual ~AudioPolicyEffects();
// NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService
@@ -218,7 +229,6 @@
};
-
static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1];
static audio_source_t inputSourceNameToEnum(const char *name);
@@ -226,8 +236,8 @@
audio_stream_type_t streamNameToEnum(const char *name);
// Parse audio_effects.conf
- status_t loadAudioEffectConfig(const char *path); // TODO: add legacy in the name
- status_t loadAudioEffectXmlConfig(); // TODO: remove "Xml" in the name
+ status_t loadAudioEffectConfigLegacy(const char *path);
+ status_t loadAudioEffectConfig(const sp<EffectsFactoryHalInterface>& effectsFactoryHal);
// Load all effects descriptors in configuration file
status_t loadEffects(cnode *root, Vector <EffectDesc *>& effects);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index af7be52..0d12060 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -476,14 +476,14 @@
}
ALOGV("startOutput()");
sp<AudioPlaybackClient> client;
- sp<AudioPolicyEffects>audioPolicyEffects;
+ sp<AudioPolicyEffects> audioPolicyEffects;
getPlaybackClientAndEffects(portId, client, audioPolicyEffects, __func__);
if (audioPolicyEffects != 0) {
// create audio processors according to stream
- status_t status = audioPolicyEffects->addOutputSessionEffects(
- client->io, client->stream, client->session);
+ status_t status = audioPolicyEffects->addOutputSessionEffects(client->io, client->stream,
+ client->session);
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGW("Failed to add effects on session %d", client->session);
}
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 974ae38..bc3c199 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -46,6 +46,7 @@
#include <system/audio.h>
#include <system/audio_policy.h>
+#include <AudioPolicyConfig.h>
#include <AudioPolicyManager.h>
namespace android {
@@ -185,7 +186,10 @@
static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
- AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);
+ auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(); // This can't fail.
+ AudioPolicyManager *apm = new AudioPolicyManager(
+ config, loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
+ clientInterface);
status_t status = apm->initialize();
if (status != NO_ERROR) {
delete apm;
@@ -259,7 +263,8 @@
}
// load audio processing modules
- sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();
+ const sp<EffectsFactoryHalInterface> effectsFactoryHal = EffectsFactoryHalInterface::create();
+ sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects(effectsFactoryHal);
sp<UidPolicy> uidPolicy = new UidPolicy(this);
sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this);
{
@@ -278,7 +283,7 @@
AudioDeviceTypeAddrVector devices;
bool hasSpatializer = mAudioPolicyManager->canBeSpatialized(&attr, nullptr, devices);
if (hasSpatializer) {
- mSpatializer = Spatializer::create(this);
+ mSpatializer = Spatializer::create(this, effectsFactoryHal);
}
if (mSpatializer == nullptr) {
// No spatializer created, signal the reason: NO_INIT a failure, OK means intended.
@@ -1694,7 +1699,7 @@
}
}
-void AudioPolicyService::UidPolicy::onUidProcAdjChanged(uid_t uid __unused) {
+void AudioPolicyService::UidPolicy::onUidProcAdjChanged(uid_t uid __unused, int32_t adj __unused) {
}
void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 59aabac..981951a 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -484,7 +484,7 @@
void onUidIdle(uid_t uid, bool disabled) override;
void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
int32_t capability) override;
- void onUidProcAdjChanged(uid_t uid) override;
+ void onUidProcAdjChanged(uid_t uid, int32_t adj) override;
void addOverrideUid(uid_t uid, bool active) { updateOverrideUid(uid, active, true); }
void removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); }
@@ -847,7 +847,7 @@
const TrackSecondaryOutputsMap& trackSecondaryOutputs) override;
status_t setDeviceConnectedState(
- const struct audio_port_v7 *port, bool connected) override;
+ const struct audio_port_v7 *port, media::DeviceConnectedState state) override;
status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 95b8e7c..ee2e0eb 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -30,7 +30,6 @@
#include <audio_utils/fixedfft.h>
#include <cutils/bitops.h>
#include <hardware/sensors.h>
-#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/MediaMetricsItem.h>
@@ -215,18 +214,17 @@
};
// ---------------------------------------------------------------------------
-sp<Spatializer> Spatializer::create(SpatializerPolicyCallback *callback) {
+sp<Spatializer> Spatializer::create(SpatializerPolicyCallback* callback,
+ const sp<EffectsFactoryHalInterface>& effectsFactoryHal) {
sp<Spatializer> spatializer;
- sp<EffectsFactoryHalInterface> effectsFactoryHal = EffectsFactoryHalInterface::create();
if (effectsFactoryHal == nullptr) {
ALOGW("%s failed to create effect factory interface", __func__);
return spatializer;
}
std::vector<effect_descriptor_t> descriptors;
- status_t status =
- effectsFactoryHal->getDescriptors(FX_IID_SPATIALIZER, &descriptors);
+ status_t status = effectsFactoryHal->getDescriptors(FX_IID_SPATIALIZER, &descriptors);
if (status != NO_ERROR) {
ALOGW("%s failed to get spatializer descriptor, error %d", __func__, status);
return spatializer;
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index 23de0c0..0d4d3f6 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -27,6 +27,7 @@
#include <audio_utils/SimpleLog.h>
#include <math.h>
#include <media/AudioEffect.h>
+#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <media/VectorRecorder.h>
#include <media/audiohal/EffectHalInterface.h>
#include <media/stagefright/foundation/ALooper.h>
@@ -95,7 +96,8 @@
private SpatializerPoseController::Listener,
public virtual AudioSystem::SupportedLatencyModesCallback {
public:
- static sp<Spatializer> create(SpatializerPolicyCallback *callback);
+ static sp<Spatializer> create(SpatializerPolicyCallback* callback,
+ const sp<EffectsFactoryHalInterface>& effectsFactoryHal);
~Spatializer() override;
diff --git a/services/audiopolicy/service/SpatializerPoseController.h b/services/audiopolicy/service/SpatializerPoseController.h
index 9d78188..7fa4f86 100644
--- a/services/audiopolicy/service/SpatializerPoseController.h
+++ b/services/audiopolicy/service/SpatializerPoseController.h
@@ -121,9 +121,7 @@
mutable std::timed_mutex mMutex;
Listener* const mListener;
const std::chrono::microseconds mSensorPeriod;
- // Order matters for the following two members to ensure correct destruction.
std::unique_ptr<media::HeadTrackingProcessor> mProcessor;
- std::unique_ptr<media::SensorPoseProvider> mPoseProvider;
int32_t mHeadSensor = media::SensorPoseProvider::INVALID_HANDLE;
int32_t mScreenSensor = media::SensorPoseProvider::INVALID_HANDLE;
std::optional<media::HeadTrackingMode> mActualMode;
@@ -146,6 +144,9 @@
4 /* vectorSize */, std::chrono::minutes(1), 10 /* maxLogLine */,
{ 3 } /* delimiterIdx */};
+ // Next to last variable as releasing this stops the callbacks
+ std::unique_ptr<media::SensorPoseProvider> mPoseProvider;
+
// It's important that mThread is the last variable in this class
// since we starts mThread in initializer list
std::thread mThread;
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index bf82680..285b354 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -19,19 +19,20 @@
],
shared_libs: [
+ "framework-permission-aidl-cpp",
"libaudioclient",
"libaudiofoundation",
"libaudiopolicy",
"libaudiopolicymanagerdefault",
"libbase",
+ "libbinder",
+ "libcutils",
"libhidlbase",
"liblog",
"libmedia_helper",
"libutils",
"libcutils",
"libxml2",
- "framework-permission-aidl-cpp",
- "libbinder",
],
static_libs: [
@@ -73,17 +74,19 @@
require_root: true,
shared_libs: [
- "libaudiofoundation",
+ "audioclient-types-aidl-cpp",
"libaudioclient",
+ "libaudioclient_aidl_conversion",
+ "libaudiofoundation",
"libaudiopolicymanagerdefault",
+ "libcutils",
"liblog",
"libmedia_helper",
- "libutils",
- "libaudioclient_aidl_conversion",
- "libstagefright_foundation",
"libshmemcompat",
"libshmemutil",
- "audioclient-types-aidl-cpp",
+ "libstagefright_foundation",
+ "libutils",
+ "libxml2",
],
static_libs: ["libaudiopolicycomponents"],
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index 6eca7cc..3629c16 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -103,10 +103,11 @@
++mAudioPortListUpdateCount;
}
- status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) override {
- if (connected) {
+ status_t setDeviceConnectedState(const struct audio_port_v7 *port,
+ media::DeviceConnectedState state) override {
+ if (state == media::DeviceConnectedState::CONNECTED) {
mConnectedDevicePorts.push_back(*port);
- } else {
+ } else if (state == media::DeviceConnectedState::DISCONNECTED){
mDisconnectedDevicePorts.push_back(*port);
}
return NO_ERROR;
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index 0c04e35..71e34e3 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -96,8 +96,8 @@
const TrackSecondaryOutputsMap& trackSecondaryOutputs __unused) override {
return NO_INIT;
}
- status_t setDeviceConnectedState(
- const struct audio_port_v7 *port __unused, bool connected __unused) override {
+ status_t setDeviceConnectedState(const struct audio_port_v7 *port __unused,
+ media::DeviceConnectedState state __unused) override {
return NO_INIT;
}
status_t invalidateTracks(const std::vector<audio_port_handle_t>& /*portIds*/) override {
diff --git a/services/audiopolicy/tests/AudioPolicyTestManager.h b/services/audiopolicy/tests/AudioPolicyTestManager.h
index 2a7a060..31ee252 100644
--- a/services/audiopolicy/tests/AudioPolicyTestManager.h
+++ b/services/audiopolicy/tests/AudioPolicyTestManager.h
@@ -22,9 +22,13 @@
class AudioPolicyTestManager : public AudioPolicyManager {
public:
explicit AudioPolicyTestManager(AudioPolicyClientInterface *clientInterface)
- : AudioPolicyManager(clientInterface, true /*forTesting*/) { }
+ : AudioPolicyTestManager(AudioPolicyConfig::createDefault(), clientInterface) {}
+ AudioPolicyTestManager(const sp<const AudioPolicyConfig>& config,
+ AudioPolicyClientInterface *clientInterface)
+ : AudioPolicyManager(config,
+ loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
+ clientInterface) {}
using AudioPolicyManager::getConfig;
- using AudioPolicyManager::loadConfig;
using AudioPolicyManager::initialize;
using AudioPolicyManager::getOutputs;
using AudioPolicyManager::getAvailableOutputDevices;
diff --git a/services/audiopolicy/tests/audio_health_tests.cpp b/services/audiopolicy/tests/audio_health_tests.cpp
index 798332c..70a3022 100644
--- a/services/audiopolicy/tests/audio_health_tests.cpp
+++ b/services/audiopolicy/tests/audio_health_tests.cpp
@@ -21,6 +21,7 @@
#include <gtest/gtest.h>
+#include <AudioPolicyConfig.h>
#include <media/AudioSystem.h>
#include <media/TypeConverter.h>
#include <system/audio.h>
@@ -65,19 +66,17 @@
}
free(audioPorts);
- AudioPolicyManagerTestClient client;
- AudioPolicyTestManager manager(&client);
- manager.loadConfig();
- ASSERT_NE("AudioPolicyConfig::setDefault", manager.getConfig().getSource());
+ auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback();
+ ASSERT_NE(AudioPolicyConfig::kDefaultConfigSource, config->getSource());
- for (auto desc : manager.getConfig().getInputDevices()) {
+ for (const auto& desc : config->getInputDevices()) {
if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
std::string deviceType;
(void)DeviceConverter::toString(desc->type(), deviceType);
ADD_FAILURE() << "Input device \"" << deviceType << "\" not found";
}
}
- for (auto desc : manager.getConfig().getOutputDevices()) {
+ for (const auto& desc : config->getOutputDevices()) {
if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
std::string deviceType;
(void)DeviceConverter::toString(desc->type(), deviceType);
@@ -87,13 +86,13 @@
}
TEST(AudioHealthTest, ConnectSupportedDevice) {
+ auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback();
+ ASSERT_NE(AudioPolicyConfig::kDefaultConfigSource, config->getSource());
AudioPolicyManagerTestClient client;
- AudioPolicyTestManager manager(&client);
- manager.loadConfig();
- ASSERT_NE("AudioPolicyConfig::setDefault", manager.getConfig().getSource());
+ AudioPolicyTestManager manager(config, &client);
DeviceVector devices;
- for (const auto& hwModule : manager.getConfig().getHwModules()) {
+ for (const auto& hwModule : config->getHwModules()) {
for (const auto& profile : hwModule->getOutputProfiles()) {
devices.merge(profile->getSupportedDevices());
}
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 412ab19..97a1e0d 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -92,11 +92,44 @@
} // namespace
+TEST(AudioPolicyConfigTest, DefaultConfigForTestsIsEmpty) {
+ auto config = AudioPolicyConfig::createWritableForTests();
+ EXPECT_TRUE(config->getSource().empty());
+ EXPECT_TRUE(config->getHwModules().isEmpty());
+ EXPECT_TRUE(config->getInputDevices().isEmpty());
+ EXPECT_TRUE(config->getOutputDevices().isEmpty());
+}
+
+TEST(AudioPolicyConfigTest, FallbackToDefault) {
+ auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
+ base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
+ EXPECT_EQ(AudioPolicyConfig::kDefaultConfigSource, config->getSource());
+}
+
+TEST(AudioPolicyConfigTest, LoadForTests) {
+ {
+ auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(
+ base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
+ EXPECT_FALSE(result.ok());
+ }
+ {
+ const std::string source =
+ base::GetExecutableDirectory() + "/test_audio_policy_configuration.xml";
+ auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(source);
+ ASSERT_TRUE(result.ok());
+ EXPECT_EQ(source, result.value()->getSource());
+ EXPECT_FALSE(result.value()->getHwModules().isEmpty());
+ EXPECT_FALSE(result.value()->getInputDevices().isEmpty());
+ EXPECT_FALSE(result.value()->getOutputDevices().isEmpty());
+ }
+}
+
TEST(AudioPolicyManagerTestInit, EngineFailure) {
AudioPolicyTestClient client;
- AudioPolicyTestManager manager(&client);
- manager.getConfig().setDefault();
- manager.getConfig().setEngineLibraryNameSuffix("non-existent");
+ auto config = AudioPolicyConfig::createWritableForTests();
+ config->setDefault();
+ config->setEngineLibraryNameSuffix("non-existent");
+ AudioPolicyTestManager manager(config, &client);
ASSERT_EQ(NO_INIT, manager.initialize());
ASSERT_EQ(NO_INIT, manager.initCheck());
}
@@ -104,41 +137,12 @@
TEST(AudioPolicyManagerTestInit, ClientFailure) {
AudioPolicyTestClient client;
AudioPolicyTestManager manager(&client);
- manager.getConfig().setDefault();
// Since the default client fails to open anything,
// APM should indicate that the initialization didn't succeed.
ASSERT_EQ(NO_INIT, manager.initialize());
ASSERT_EQ(NO_INIT, manager.initCheck());
}
-// Verifies that a failure while loading a config doesn't leave
-// APM config in a "dirty" state. Since AudioPolicyConfig object
-// is a proxy for the data hosted by APM, it isn't possible
-// to "deep copy" it, and thus we have to test its elements
-// individually.
-TEST(AudioPolicyManagerTestInit, ConfigLoadingIsTransactional) {
- AudioPolicyTestClient client;
- AudioPolicyTestManager manager(&client);
- ASSERT_TRUE(manager.getConfig().getHwModules().isEmpty());
- ASSERT_TRUE(manager.getConfig().getInputDevices().isEmpty());
- ASSERT_TRUE(manager.getConfig().getOutputDevices().isEmpty());
- status_t status = deserializeAudioPolicyFile(
- (base::GetExecutableDirectory() +
- "/test_invalid_audio_policy_configuration.xml").c_str(),
- &manager.getConfig());
- ASSERT_NE(NO_ERROR, status);
- EXPECT_TRUE(manager.getConfig().getHwModules().isEmpty());
- EXPECT_TRUE(manager.getConfig().getInputDevices().isEmpty());
- EXPECT_TRUE(manager.getConfig().getOutputDevices().isEmpty());
- status = deserializeAudioPolicyFile(
- (base::GetExecutableDirectory() + "/test_audio_policy_configuration.xml").c_str(),
- &manager.getConfig());
- ASSERT_EQ(NO_ERROR, status);
- EXPECT_FALSE(manager.getConfig().getHwModules().isEmpty());
- EXPECT_FALSE(manager.getConfig().getInputDevices().isEmpty());
- EXPECT_FALSE(manager.getConfig().getOutputDevices().isEmpty());
-}
-
class PatchCountCheck {
public:
@@ -200,6 +204,7 @@
static audio_port_handle_t getDeviceIdFromPatch(const struct audio_patch* patch);
virtual AudioPolicyManagerTestClient* getClient() { return new AudioPolicyManagerTestClient; }
+ sp<AudioPolicyConfig> mConfig;
std::unique_ptr<AudioPolicyManagerTestClient> mClient;
std::unique_ptr<AudioPolicyTestManager> mManager;
@@ -208,8 +213,8 @@
void AudioPolicyManagerTest::SetUp() {
mClient.reset(getClient());
- mManager.reset(new AudioPolicyTestManager(mClient.get()));
ASSERT_NO_FATAL_FAILURE(SetUpManagerConfig()); // Subclasses may want to customize the config.
+ mManager.reset(new AudioPolicyTestManager(mConfig, mClient.get()));
ASSERT_EQ(NO_ERROR, mManager->initialize());
ASSERT_EQ(NO_ERROR, mManager->initCheck());
}
@@ -220,7 +225,8 @@
}
void AudioPolicyManagerTest::SetUpManagerConfig() {
- mManager->getConfig().setDefault();
+ mConfig = AudioPolicyConfig::createWritableForTests();
+ mConfig->setDefault();
}
void AudioPolicyManagerTest::dumpToLog() {
@@ -467,7 +473,6 @@
void AudioPolicyManagerTestMsd::SetUpManagerConfig() {
// TODO: Consider using Serializer to load part of the config from a string.
ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUpManagerConfig());
- AudioPolicyConfig& config = mManager->getConfig();
mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
sp<AudioProfile> pcmOutputProfile = new AudioProfile(
AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
@@ -483,26 +488,26 @@
sp<AudioProfile> pcmInputProfile = new AudioProfile(
AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 44100);
mMsdInputDevice->addAudioProfile(pcmInputProfile);
- config.addDevice(mMsdOutputDevice);
- config.addDevice(mMsdInputDevice);
+ mConfig->addDevice(mMsdOutputDevice);
+ mConfig->addDevice(mMsdInputDevice);
if (mExpectedAudioPatchCount == 2) {
// Add SPDIF device with PCM output profile as a second device for dual MSD audio patching.
mSpdifDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPDIF);
mSpdifDevice->addAudioProfile(pcmOutputProfile);
- config.addDevice(mSpdifDevice);
+ mConfig->addDevice(mSpdifDevice);
sp<OutputProfile> spdifOutputProfile = new OutputProfile("spdif output");
spdifOutputProfile->addAudioProfile(pcmOutputProfile);
spdifOutputProfile->addSupportedDevice(mSpdifDevice);
- config.getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
+ mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
addOutputProfile(spdifOutputProfile);
}
sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 2 /*halVersionMajor*/);
- HwModuleCollection modules = config.getHwModules();
+ HwModuleCollection modules = mConfig->getHwModules();
modules.add(msdModule);
- config.setHwModules(modules);
+ mConfig->setHwModules(modules);
sp<OutputProfile> msdOutputProfile = new OutputProfile("msd input");
msdOutputProfile->addAudioProfile(pcmOutputProfile);
@@ -530,15 +535,15 @@
// of streams that are not supported by MSD.
sp<AudioProfile> dtsOutputProfile = new AudioProfile(
AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, k48000SamplingRate);
- config.getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
+ mConfig->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
sp<OutputProfile> primaryEncodedOutputProfile = new OutputProfile("encoded");
primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile);
primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
- primaryEncodedOutputProfile->addSupportedDevice(config.getDefaultOutputDevice());
- config.getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
+ primaryEncodedOutputProfile->addSupportedDevice(mConfig->getDefaultOutputDevice());
+ mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
addOutputProfile(primaryEncodedOutputProfile);
- mDefaultOutputDevice = config.getDefaultOutputDevice();
+ mDefaultOutputDevice = mConfig->getDefaultOutputDevice();
if (mExpectedAudioPatchCount == 2) {
mSpdifDevice->addAudioProfile(dtsOutputProfile);
primaryEncodedOutputProfile->addSupportedDevice(mSpdifDevice);
@@ -549,12 +554,12 @@
sp<AudioProfile> iec958InputProfile = new AudioProfile(
AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
mHdmiInputDevice->addAudioProfile(iec958InputProfile);
- config.addDevice(mHdmiInputDevice);
+ mConfig->addDevice(mHdmiInputDevice);
sp<InputProfile> hdmiInputProfile = new InputProfile("hdmi input");
hdmiInputProfile->addAudioProfile(iec958InputProfile);
hdmiInputProfile->setFlags(AUDIO_INPUT_FLAG_DIRECT);
hdmiInputProfile->addSupportedDevice(mHdmiInputDevice);
- config.getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
+ mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
addInputProfile(hdmiInputProfile);
}
@@ -721,7 +726,7 @@
int countDirectProfilesPrimary = 0;
const auto& primary = mManager->getConfig().getHwModules()
.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
- for (const auto outputProfile : primary->getOutputProfiles()) {
+ for (const auto& outputProfile : primary->getOutputProfiles()) {
if (outputProfile->asAudioPort()->isDirectOutput()) {
countDirectProfilesPrimary += outputProfile->asAudioPort()->getAudioProfiles().size();
}
@@ -731,7 +736,7 @@
int countDirectProfilesMsd = 0;
const auto& msd = mManager->getConfig().getHwModules()
.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
- for (const auto outputProfile : msd->getOutputProfiles()) {
+ for (const auto& outputProfile : msd->getOutputProfiles()) {
if (outputProfile->asAudioPort()->isDirectOutput()) {
countDirectProfilesMsd += outputProfile->asAudioPort()->getAudioProfiles().size();
}
@@ -922,9 +927,9 @@
sExecutableDir + "test_audio_policy_configuration.xml";
void AudioPolicyManagerTestWithConfigurationFile::SetUpManagerConfig() {
- status_t status = deserializeAudioPolicyFile(getConfigFile().c_str(), &mManager->getConfig());
- ASSERT_EQ(NO_ERROR, status);
- mManager->getConfig().setSource(getConfigFile());
+ auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(getConfigFile());
+ ASSERT_TRUE(result.ok());
+ mConfig = result.value();
}
TEST_F(AudioPolicyManagerTestWithConfigurationFile, InitSuccess) {
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a2aafdf..cecced4 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2602,6 +2602,19 @@
}
}
+void CameraService::notifyMonitoredUids(const std::unordered_set<uid_t> ¬ifyUidSet) {
+ Mutex::Autolock lock(mStatusListenerLock);
+
+ for (const auto& it : mListenerList) {
+ if (notifyUidSet.find(it->getListenerUid()) != notifyUidSet.end()) {
+ ALOGV("%s: notifying uid %d", __FUNCTION__, it->getListenerUid());
+ auto ret = it->getListener()->onCameraAccessPrioritiesChanged();
+ it->handleBinderStatus(ret, "%s: Failed to trigger permission callback for %d:%d: %d",
+ __FUNCTION__, it->getListenerUid(), it->getListenerPid(), ret.exceptionCode());
+ }
+ }
+}
+
Status CameraService::notifyDeviceStateChange(int64_t newState) {
const int pid = CameraThreadState::getCallingPid();
const int selfPid = getpid();
@@ -2823,7 +2836,7 @@
// permissions the listener process has / whether it is a vendor listener. Since it might be
// eligible to listen to other camera ids.
mListenerList.emplace_back(serviceListener);
- mUidPolicy->registerMonitorUid(clientUid);
+ mUidPolicy->registerMonitorUid(clientUid, /*openCamera*/false);
}
/* Collect current devices and status */
@@ -2891,7 +2904,7 @@
Mutex::Autolock lock(mStatusListenerLock);
for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
if (IInterface::asBinder((*it)->getListener()) == IInterface::asBinder(listener)) {
- mUidPolicy->unregisterMonitorUid((*it)->getListenerUid());
+ mUidPolicy->unregisterMonitorUid((*it)->getListenerUid(), /*closeCamera*/false);
IInterface::asBinder(listener)->unlinkToDeath(*it);
mListenerList.erase(it);
return Status::ok();
@@ -3680,7 +3693,7 @@
// Transition device availability listeners from PRESENT -> NOT_AVAILABLE
sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr);
- sCameraService->mUidPolicy->registerMonitorUid(mClientUid);
+ sCameraService->mUidPolicy->registerMonitorUid(mClientUid, /*openCamera*/true);
// Notify listeners of camera open/close status
sCameraService->updateOpenCloseStatus(mCameraIdStr, true/*open*/, mClientPackageName);
@@ -3788,7 +3801,7 @@
}
mOpsCallback.clear();
- sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid);
+ sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid, /*closeCamera*/true);
// Notify listeners of camera open/close status
sCameraService->updateOpenCloseStatus(mCameraIdStr, false/*open*/, mClientPackageName);
@@ -3988,24 +4001,51 @@
}
}
-void CameraService::UidPolicy::onUidProcAdjChanged(uid_t uid) {
- bool procAdjChange = false;
+/**
+ * When the OOM adj of the uid owning the camera changes, a different uid waiting on camera
+ * privileges may take precedence if the owner's new OOM adj is greater than the waiting package.
+ * Here, we track which monitoredUid has the camera, and track its adj relative to other
+ * monitoredUids. If it is revised above some other monitoredUid, signal
+ * onCameraAccessPrioritiesChanged. This only needs to capture the case where there are two
+ * foreground apps in split screen - state changes will capture all other cases.
+ */
+void CameraService::UidPolicy::onUidProcAdjChanged(uid_t uid, int32_t adj) {
+ std::unordered_set<uid_t> notifyUidSet;
{
Mutex::Autolock _l(mUidLock);
- if (mMonitoredUids.find(uid) != mMonitoredUids.end()) {
- procAdjChange = true;
+ auto it = mMonitoredUids.find(uid);
+
+ if (it != mMonitoredUids.end()) {
+ if (it->second.hasCamera) {
+ for (auto &monitoredUid : mMonitoredUids) {
+ if (monitoredUid.first != uid && adj > monitoredUid.second.procAdj) {
+ notifyUidSet.emplace(monitoredUid.first);
+ }
+ }
+ notifyUidSet.emplace(uid);
+ } else {
+ for (auto &monitoredUid : mMonitoredUids) {
+ if (monitoredUid.second.hasCamera && adj < monitoredUid.second.procAdj) {
+ notifyUidSet.emplace(uid);
+ }
+ }
+ }
+ it->second.procAdj = adj;
}
}
- if (procAdjChange) {
+ if (notifyUidSet.size() > 0) {
sp<CameraService> service = mService.promote();
if (service != nullptr) {
- service->notifyMonitoredUids();
+ service->notifyMonitoredUids(notifyUidSet);
}
}
}
-void CameraService::UidPolicy::registerMonitorUid(uid_t uid) {
+/**
+ * Register a uid for monitoring, and note whether it owns a camera.
+ */
+void CameraService::UidPolicy::registerMonitorUid(uid_t uid, bool openCamera) {
Mutex::Autolock _l(mUidLock);
auto it = mMonitoredUids.find(uid);
if (it != mMonitoredUids.end()) {
@@ -4013,18 +4053,28 @@
} else {
MonitoredUid monitoredUid;
monitoredUid.procState = ActivityManager::PROCESS_STATE_NONEXISTENT;
+ monitoredUid.procAdj = resource_policy::UNKNOWN_ADJ;
monitoredUid.refCount = 1;
- mMonitoredUids.emplace(std::pair<uid_t, MonitoredUid>(uid, monitoredUid));
+ it = mMonitoredUids.emplace(std::pair<uid_t, MonitoredUid>(uid, monitoredUid)).first;
+ }
+
+ if (openCamera) {
+ it->second.hasCamera = true;
}
}
-void CameraService::UidPolicy::unregisterMonitorUid(uid_t uid) {
+/**
+ * Unregister a uid for monitoring, and note whether it lost ownership of a camera.
+ */
+void CameraService::UidPolicy::unregisterMonitorUid(uid_t uid, bool closeCamera) {
Mutex::Autolock _l(mUidLock);
auto it = mMonitoredUids.find(uid);
if (it != mMonitoredUids.end()) {
it->second.refCount--;
if (it->second.refCount == 0) {
mMonitoredUids.erase(it);
+ } else if (closeCamera) {
+ it->second.hasCamera = false;
}
} else {
ALOGE("%s: Trying to unregister uid: %d which is not monitored!", __FUNCTION__, uid);
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index ecec15f..8c57d26 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -233,6 +233,7 @@
// Monitored UIDs availability notification
void notifyMonitoredUids();
+ void notifyMonitoredUids(const std::unordered_set<uid_t> ¬ifyUidSet);
// Stores current open session device info in temp file.
void cacheDump();
@@ -763,13 +764,13 @@
void onUidIdle(uid_t uid, bool disabled) override;
void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
int32_t capability) override;
- void onUidProcAdjChanged(uid_t uid) override;
+ void onUidProcAdjChanged(uid_t uid, int adj) override;
void addOverrideUid(uid_t uid, String16 callingPackage, bool active);
void removeOverrideUid(uid_t uid, String16 callingPackage);
- void registerMonitorUid(uid_t uid);
- void unregisterMonitorUid(uid_t uid);
+ void registerMonitorUid(uid_t uid, bool openCamera);
+ void unregisterMonitorUid(uid_t uid, bool closeCamera);
// Implementation of IServiceManager::LocalRegistrationCallback
virtual void onServiceRegistration(const String16& name,
@@ -784,6 +785,8 @@
struct MonitoredUid {
int32_t procState;
+ int32_t procAdj;
+ bool hasCamera;
size_t refCount;
};
diff --git a/services/camera/libcameraservice/CameraServiceWatchdog.cpp b/services/camera/libcameraservice/CameraServiceWatchdog.cpp
index e80064a..28dff7d 100644
--- a/services/camera/libcameraservice/CameraServiceWatchdog.cpp
+++ b/services/camera/libcameraservice/CameraServiceWatchdog.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "CameraServiceWatchdog"
#include "CameraServiceWatchdog.h"
+#include "android/set_abort_message.h"
#include "utils/CameraServiceProxyWrapper.h"
namespace android {
@@ -36,12 +37,15 @@
{
AutoMutex _l(mWatchdogLock);
- for (auto it = tidToCycleCounterMap.begin(); it != tidToCycleCounterMap.end(); it++) {
+ for (auto it = mTidMap.begin(); it != mTidMap.end(); it++) {
uint32_t currentThreadId = it->first;
- tidToCycleCounterMap[currentThreadId]++;
+ mTidMap[currentThreadId].cycles++;
- if (tidToCycleCounterMap[currentThreadId] >= mMaxCycles) {
+ if (mTidMap[currentThreadId].cycles >= mMaxCycles) {
+ std::string abortMessage = getAbortMessage(getpid(), currentThreadId,
+ mTidMap[currentThreadId].functionName);
+ android_set_abort_message(abortMessage.c_str());
ALOGW("CameraServiceWatchdog triggering abort for pid: %d tid: %d", getpid(),
currentThreadId);
mCameraServiceProxyWrapper->logClose(mCameraId, 0 /*latencyMs*/,
@@ -56,13 +60,20 @@
return true;
}
+std::string CameraServiceWatchdog::getAbortMessage(int pid, int tid, std::string functionName) {
+ std::string res = "CameraServiceWatchdog triggering abort during "
+ + functionName + " | pid: " + std::to_string(pid)
+ + " tid: " + std::to_string(tid);
+ return res;
+}
+
void CameraServiceWatchdog::requestExit()
{
Thread::requestExit();
AutoMutex _l(mWatchdogLock);
- tidToCycleCounterMap.clear();
+ mTidMap.clear();
if (mPause) {
mPause = false;
@@ -85,18 +96,21 @@
{
AutoMutex _l(mWatchdogLock);
- tidToCycleCounterMap.erase(tid);
+ mTidMap.erase(tid);
- if (tidToCycleCounterMap.empty()) {
+ if (mTidMap.empty()) {
mPause = true;
}
}
-void CameraServiceWatchdog::start(uint32_t tid)
+void CameraServiceWatchdog::start(uint32_t tid, const char* functionName)
{
AutoMutex _l(mWatchdogLock);
- tidToCycleCounterMap[tid] = 0;
+ MonitoredFunction monitoredFunction = {};
+ monitoredFunction.cycles = 0;
+ monitoredFunction.functionName = functionName;
+ mTidMap[tid] = monitoredFunction;
if (mPause) {
mPause = false;
diff --git a/services/camera/libcameraservice/CameraServiceWatchdog.h b/services/camera/libcameraservice/CameraServiceWatchdog.h
index 6617873..6f8858a 100644
--- a/services/camera/libcameraservice/CameraServiceWatchdog.h
+++ b/services/camera/libcameraservice/CameraServiceWatchdog.h
@@ -40,9 +40,9 @@
#include "utils/CameraServiceProxyWrapper.h"
// Used to wrap the call of interest in start and stop calls
-#define WATCH(toMonitor) watchThread([&]() { return toMonitor;}, gettid())
+#define WATCH(toMonitor) watchThread([&]() { return toMonitor;}, gettid(), __FUNCTION__)
#define WATCH_CUSTOM_TIMER(toMonitor, cycles, cycleLength) \
- watchThread([&]() { return toMonitor;}, gettid(), cycles, cycleLength);
+ watchThread([&]() { return toMonitor;}, gettid(), __FUNCTION__, cycles, cycleLength);
// Default cycles and cycle length values used to calculate permitted elapsed time
const static size_t kMaxCycles = 100;
@@ -52,6 +52,11 @@
class CameraServiceWatchdog : public Thread {
+struct MonitoredFunction {
+ uint32_t cycles;
+ std::string functionName;
+};
+
public:
explicit CameraServiceWatchdog(const String8 &cameraId,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
@@ -75,7 +80,8 @@
/** Used to wrap monitored calls in start and stop functions using custom timer values */
template<typename T>
- auto watchThread(T func, uint32_t tid, uint32_t cycles, uint32_t cycleLength) {
+ auto watchThread(T func, uint32_t tid, const char* functionName, uint32_t cycles,
+ uint32_t cycleLength) {
decltype(func()) res;
if (cycles != mMaxCycles || cycleLength != mCycleLengthMs) {
@@ -91,17 +97,17 @@
status_t status = tempWatchdog->run("CameraServiceWatchdog");
if (status != OK) {
ALOGE("Unable to watch thread: %s (%d)", strerror(-status), status);
- res = watchThread(func, tid);
+ res = watchThread(func, tid, functionName);
return res;
}
- res = tempWatchdog->watchThread(func, tid);
+ res = tempWatchdog->watchThread(func, tid, functionName);
tempWatchdog->requestExit();
tempWatchdog.clear();
} else {
// If custom timer values are equivalent to set class timer values, use
// current thread
- res = watchThread(func, tid);
+ res = watchThread(func, tid, functionName);
}
return res;
@@ -109,12 +115,12 @@
/** Used to wrap monitored calls in start and stop functions using class timer values */
template<typename T>
- auto watchThread(T func, uint32_t tid) {
+ auto watchThread(T func, uint32_t tid, const char* functionName) {
decltype(func()) res;
AutoMutex _l(mEnabledLock);
if (mEnabled) {
- start(tid);
+ start(tid, functionName);
res = func();
stop(tid);
} else {
@@ -130,7 +136,7 @@
* Start adds a cycle counter for the calling thread. When threadloop is blocked/paused,
* start() unblocks and starts the watchdog
*/
- void start(uint32_t tid);
+ void start(uint32_t tid, const char* functionName);
/**
* If there are no calls left to be monitored, stop blocks/pauses threadloop
@@ -138,6 +144,8 @@
*/
void stop(uint32_t tid);
+ std::string getAbortMessage(int pid, int tid, std::string functionName);
+
virtual bool threadLoop();
Mutex mWatchdogLock; // Lock for condition variable
@@ -151,7 +159,9 @@
std::shared_ptr<CameraServiceProxyWrapper> mCameraServiceProxyWrapper;
- std::unordered_map<uint32_t, uint32_t> tidToCycleCounterMap; // Thread Id to cycle counter map
+ std::unordered_map<uint32_t, MonitoredFunction> mTidMap; // Thread Id to MonitoredFunction type
+ // which retrieves the num of cycles
+ // and name of the function
};
} // namespace android
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index fda6af3..38c615d 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -957,7 +957,7 @@
bool isHeicCompositeStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
bool isJpegRCompositeStream =
camera3::JpegRCompositeStream::isJpegRCompositeStream(surfaces[0]) &&
- !mDevice->supportNativeJpegR();
+ !mDevice->isCompositeJpegRDisabled();
if (isDepthCompositeStream || isHeicCompositeStream || isJpegRCompositeStream) {
sp<CompositeStream> compositeStream;
if (isDepthCompositeStream) {
@@ -1851,7 +1851,7 @@
isCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(s) ||
camera3::HeicCompositeStream::isHeicCompositeStream(s) ||
(camera3::JpegRCompositeStream::isJpegRCompositeStream(s) &&
- !mDevice->supportNativeJpegR());
+ !mDevice->isCompositeJpegRDisabled());
if (isCompositeStream) {
auto compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp));
if (compositeIdx == NAME_NOT_FOUND) {
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 66077c5..86a0ebc 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -264,7 +264,7 @@
mOpsActive = true;
// Transition device state to OPEN
- sCameraService->mUidPolicy->registerMonitorUid(mClientUid);
+ sCameraService->mUidPolicy->registerMonitorUid(mClientUid, /*openCamera*/true);
return OK;
}
@@ -288,7 +288,7 @@
}
mOpsCallback.clear();
- sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid);
+ sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid, /*closeCamera*/true);
return OK;
}
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 530b03e..919108d 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -113,7 +113,7 @@
*/
virtual const CameraMetadata& infoPhysical(const String8& physicalId) const = 0;
- virtual bool supportNativeJpegR() const { return false; };
+ virtual bool isCompositeJpegRDisabled() const { return false; };
struct PhysicalCameraSettings {
std::string cameraId;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index b7c86c6..6f4c04a 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -316,16 +316,16 @@
return deviceInfo->supportNativeZoomRatio();
}
-bool CameraProviderManager::supportNativeJpegR(const std::string &id) const {
+bool CameraProviderManager::isCompositeJpegRDisabled(const std::string &id) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
- return supportNativeJpegRLocked(id);
+ return isCompositeJpegRDisabledLocked(id);
}
-bool CameraProviderManager::supportNativeJpegRLocked(const std::string &id) const {
+bool CameraProviderManager::isCompositeJpegRDisabledLocked(const std::string &id) const {
auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo == nullptr) return false;
- return deviceInfo->supportNativeJpegR();
+ return deviceInfo->isCompositeJpegRDisabled();
}
status_t CameraProviderManager::getResourceCost(const std::string &id,
@@ -1120,7 +1120,7 @@
}
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::deriveJpegRTags(bool maxResolution) {
- if (kFrameworkJpegRDisabled || mSupportsNativeJpegR) {
+ if (kFrameworkJpegRDisabled || mCompositeJpegRDisabled) {
return OK;
}
@@ -1166,6 +1166,18 @@
return OK;
}
+ if (!isConcurrentDynamicRangeCaptureSupported(c,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) &&
+ !property_get_bool("ro.camera.enableCompositeAPI0JpegR", false)) {
+ // API0, P010 only Jpeg/R support is meant to be used only as a reference due to possible
+ // impact on quality and performance.
+ // This data path will be turned off by default and individual device builds must enable
+ // 'ro.camera.enableCompositeAPI0JpegR' in order to experiment using it.
+ mCompositeJpegRDisabled = true;
+ return OK;
+ }
+
getSupportedSizes(c, scalerSizesTag,
static_cast<android_pixel_format_t>(HAL_PIXEL_FORMAT_BLOB), &supportedBlobSizes);
getSupportedSizes(c, scalerSizesTag,
@@ -2526,6 +2538,10 @@
(mDeviceStateOrientationMap.find(newState) != mDeviceStateOrientationMap.end())) {
mCameraCharacteristics.update(ANDROID_SENSOR_ORIENTATION,
&mDeviceStateOrientationMap[newState], 1);
+ if (mCameraCharNoPCOverride.get() != nullptr) {
+ mCameraCharNoPCOverride->update(ANDROID_SENSOR_ORIENTATION,
+ &mDeviceStateOrientationMap[newState], 1);
+ }
}
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index ce4129c..e6e4619 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -248,9 +248,9 @@
bool supportNativeZoomRatio(const std::string &id) const;
/**
- * Return true if the camera device has native Jpeg/R support.
+ * Return true if the camera device has no composite Jpeg/R support.
*/
- bool supportNativeJpegR(const std::string &id) const;
+ bool isCompositeJpegRDisabled(const std::string &id) const;
/**
* Return the resource cost of this camera device
@@ -573,7 +573,7 @@
bool hasFlashUnit() const { return mHasFlashUnit; }
bool supportNativeZoomRatio() const { return mSupportNativeZoomRatio; }
- bool supportNativeJpegR() const { return mSupportsNativeJpegR; }
+ bool isCompositeJpegRDisabled() const { return mCompositeJpegRDisabled; }
virtual status_t setTorchMode(bool enabled) = 0;
virtual status_t turnOnTorchWithStrengthLevel(int32_t torchStrength) = 0;
virtual status_t getTorchStrengthLevel(int32_t *torchStrength) = 0;
@@ -615,14 +615,14 @@
mParentProvider(parentProvider), mTorchStrengthLevel(0),
mTorchMaximumStrengthLevel(0), mTorchDefaultStrengthLevel(0),
mHasFlashUnit(false), mSupportNativeZoomRatio(false),
- mPublicCameraIds(publicCameraIds), mSupportsNativeJpegR(false) {}
+ mPublicCameraIds(publicCameraIds), mCompositeJpegRDisabled(false) {}
virtual ~DeviceInfo() {}
protected:
bool mHasFlashUnit; // const after constructor
bool mSupportNativeZoomRatio; // const after constructor
const std::vector<std::string>& mPublicCameraIds;
- bool mSupportsNativeJpegR;
+ bool mCompositeJpegRDisabled;
};
std::vector<std::unique_ptr<DeviceInfo>> mDevices;
std::unordered_set<std::string> mUniqueCameraIds;
@@ -811,7 +811,7 @@
// No guarantees on the order of traversal
ProviderInfo::DeviceInfo* findDeviceInfoLocked(const std::string& id) const;
- bool supportNativeJpegRLocked(const std::string &id) const;
+ bool isCompositeJpegRDisabledLocked(const std::string &id) const;
// Map external providers to USB devices in order to handle USB hotplug
// events for lazy HALs
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index 64098ea..b18cbd4 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -483,7 +483,7 @@
}
}
- mSupportsNativeJpegR = mCameraCharacteristics.exists(
+ mCompositeJpegRDisabled = mCameraCharacteristics.exists(
ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS);
mSystemCameraKind = getSystemCameraKind();
@@ -735,7 +735,7 @@
camera::device::StreamConfiguration streamConfiguration;
bool earlyExit = false;
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
- String8(mId.c_str()), mCameraCharacteristics, mSupportsNativeJpegR, getMetadata,
+ String8(mId.c_str()), mCameraCharacteristics, mCompositeJpegRDisabled, getMetadata,
mPhysicalIds, streamConfiguration, overrideForPerfClass, &earlyExit);
if (!bRes.isOk()) {
@@ -802,7 +802,7 @@
SessionConfigurationUtils::convertToHALStreamCombination(
cameraIdAndSessionConfig.mSessionConfiguration,
String8(cameraId.c_str()), deviceInfo,
- mManager->supportNativeJpegRLocked(cameraId), getMetadata,
+ mManager->isCompositeJpegRDisabledLocked(cameraId), getMetadata,
physicalCameraIds, streamConfiguration,
overrideForPerfClass, &shouldExit);
if (!bStatus.isOk()) {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 9de14a2..f5f50a5 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -81,7 +81,7 @@
mLegacyClient(legacyClient),
mOperatingMode(NO_MODE),
mIsConstrainedHighSpeedConfiguration(false),
- mSupportNativeJpegR(false),
+ mIsCompositeJpegRDisabled(false),
mStatus(STATUS_UNINITIALIZED),
mStatusWaiters(0),
mUsePartialResult(false),
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 5cc5ab0..b1dd135 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -119,7 +119,7 @@
status_t dumpWatchedEventsToVector(std::vector<std::string> &out) override;
const CameraMetadata& info() const override;
const CameraMetadata& infoPhysical(const String8& physicalId) const override;
- bool supportNativeJpegR() const override { return mSupportNativeJpegR; };
+ bool isCompositeJpegRDisabled() const override { return mIsCompositeJpegRDisabled; };
// Capture and setStreamingRequest will configure streams if currently in
// idle state
@@ -553,7 +553,7 @@
CameraMetadata mDeviceInfo;
bool mSupportNativeZoomRatio;
- bool mSupportNativeJpegR;
+ bool mIsCompositeJpegRDisabled;
std::unordered_map<std::string, CameraMetadata> mPhysicalDeviceInfoMap;
CameraMetadata mRequestTemplateCache[CAMERA_TEMPLATE_COUNT];
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index beef0da..f2a62fa 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -1444,7 +1444,7 @@
//
nsecs_t captureInterval = t - mLastCaptureTime;
if (captureInterval > kSpacingResetIntervalNs) {
- for (size_t i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ for (size_t i = 0; i < vsyncEventData.frameTimelinesLength; i++) {
const auto& timeline = vsyncEventData.frameTimelines[i];
if (timeline.deadlineTimestamp >= currentTime &&
timeline.expectedPresentationTime > minPresentT) {
@@ -1513,7 +1513,7 @@
// - For variable FPS, or if the capture interval deviates from refresh
// interval for more than 5%, find a presentation time closest to the
// (lastPresentationTime + captureToPresentOffset) instead.
- int maxTimelines = std::min(kMaxTimelines, (int)VsyncEventData::kFrameTimelinesLength);
+ int maxTimelines = std::min(kMaxTimelines, (int)vsyncEventData.frameTimelinesLength);
float biasForShortDelay = 1.0f;
for (int i = 0; i < maxTimelines; i ++) {
const auto& vsyncTime = vsyncEventData.frameTimelines[i];
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
index e186f13..aa941b0 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -205,7 +205,7 @@
return res;
}
mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
- mSupportNativeJpegR = manager->supportNativeJpegR(mId.string());
+ mIsCompositeJpegRDisabled = manager->isCompositeJpegRDisabled(mId.string());
std::vector<std::string> physicalCameraIds;
bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index e25f972..ffd9f01 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -677,7 +677,8 @@
binder::Status
convertToHALStreamCombination(
const SessionConfiguration& sessionConfiguration,
- const String8 &logicalCameraId, const CameraMetadata &deviceInfo, bool supportNativeJpegR,
+ const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+ bool isCompositeJpegRDisabled,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit) {
@@ -822,7 +823,7 @@
camera3::HeicCompositeStream::isHeicCompositeStream(surface);
bool isJpegRCompositeStream =
camera3::JpegRCompositeStream::isJpegRCompositeStream(surface) &&
- !supportNativeJpegR;
+ !isCompositeJpegRDisabled;
if (isDepthCompositeStream || isHeicCompositeStream || isJpegRCompositeStream) {
// We need to take in to account that composite streams can have
// additional internal camera streams.
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index d27144e..dc143da 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -138,7 +138,7 @@
binder::Status
convertToHALStreamCombination(
const SessionConfiguration& sessionConfiguration,
- const String8 &logicalCameraId, const CameraMetadata &deviceInfo, bool supportNativeJpegR,
+ const String8 &logicalCameraId, const CameraMetadata &deviceInfo, bool isCompositeJpegRDisabled,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit);
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
index d960024..111c1bf 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
@@ -111,8 +111,8 @@
bool overrideForPerfClass, bool *earlyExit) {
aidl::android::hardware::camera::device::StreamConfiguration aidlStreamConfiguration;
auto ret = convertToHALStreamCombination(sessionConfiguration, logicalCameraId, deviceInfo,
- false /*supportNativeJpegR*/, getMetadata, physicalCameraIds, aidlStreamConfiguration,
- overrideForPerfClass, earlyExit);
+ false /*isCompositeJpegRDisabled*/, getMetadata, physicalCameraIds,
+ aidlStreamConfiguration, overrideForPerfClass, earlyExit);
if (!ret.isOk()) {
return ret;
}
diff --git a/services/mediametrics/statsd_codec.cpp b/services/mediametrics/statsd_codec.cpp
index cb5e783..158914a 100644
--- a/services/mediametrics/statsd_codec.cpp
+++ b/services/mediametrics/statsd_codec.cpp
@@ -438,7 +438,7 @@
}
AStatsEvent_writeInt32(event, hdr10PlusInfo);
- int32_t hdrFormat= -1;
+ int32_t hdrFormat = -1;
if (item->getInt32("android.media.mediacodec.hdr-format", &hdrFormat)) {
metrics_proto.set_hdr_format(hdrFormat);
}
@@ -450,6 +450,61 @@
}
AStatsEvent_writeInt64(event, codecId);
+ int32_t arrayMode = -1;
+ if (item->getInt32("android.media.mediacodec.array-mode", &arrayMode)) {
+ metrics_proto.set_array_mode(arrayMode);
+ }
+ AStatsEvent_writeInt32(event, arrayMode);
+
+ int32_t operationMode = -1;
+ if (item->getInt32("android.media.mediacodec.operation-mode", &operationMode)) {
+ metrics_proto.set_operation_mode(operationMode);
+ }
+ AStatsEvent_writeInt32(event, operationMode);
+
+ int32_t outputSurface = -1;
+ if (item->getInt32("android.media.mediacodec.output-surface", &outputSurface)) {
+ metrics_proto.set_output_surface(outputSurface);
+ }
+ AStatsEvent_writeInt32(event, outputSurface);
+
+ int32_t appMaxInputSize = -1;
+ if (item->getInt32("android.media.mediacodec.app-max-input-size", &appMaxInputSize)) {
+ metrics_proto.set_app_max_input_size(appMaxInputSize);
+ }
+ AStatsEvent_writeInt32(event, appMaxInputSize);
+
+ int32_t usedMaxInputSize = -1;
+ if (item->getInt32("android.media.mediacodec.used-max-input-size", &usedMaxInputSize)) {
+ metrics_proto.set_used_max_input_size(usedMaxInputSize);
+ }
+ AStatsEvent_writeInt32(event, usedMaxInputSize);
+
+ int32_t codecMaxInputSize = -1;
+ if (item->getInt32("android.media.mediacodec.codec-max-input-size", &codecMaxInputSize)) {
+ metrics_proto.set_codec_max_input_size(codecMaxInputSize);
+ }
+ AStatsEvent_writeInt32(event, codecMaxInputSize);
+
+ int32_t flushCount = -1;
+ if (item->getInt32("android.media.mediacodec.flush-count", &flushCount)) {
+ metrics_proto.set_flush_count(flushCount);
+ }
+ AStatsEvent_writeInt32(event, flushCount);
+
+ int32_t setSurfaceCount = -1;
+ if (item->getInt32("android.media.mediacodec.set-surface-count", &setSurfaceCount)) {
+ metrics_proto.set_set_surface_count(setSurfaceCount);
+ }
+ AStatsEvent_writeInt32(event, setSurfaceCount);
+
+ int32_t resolutionChangeCount = -1;
+ if (item->getInt32("android.media.mediacodec.resolution-change-count",
+ &resolutionChangeCount)) {
+ metrics_proto.set_resolution_change_count(resolutionChangeCount);
+ }
+ AStatsEvent_writeInt32(event, resolutionChangeCount);
+
int err = AStatsEvent_write(event);
if (err < 0) {
ALOGE("Failed to write codec metrics to statsd (%d)", err);
diff --git a/services/mediaresourcemanager/UidObserver.cpp b/services/mediaresourcemanager/UidObserver.cpp
index f321ebc..4bcd325 100644
--- a/services/mediaresourcemanager/UidObserver.cpp
+++ b/services/mediaresourcemanager/UidObserver.cpp
@@ -170,7 +170,7 @@
int32_t /*capability*/) {
}
-void UidObserver::onUidProcAdjChanged(uid_t /*uid*/) {
+void UidObserver::onUidProcAdjChanged(uid_t /*uid*/, int32_t /*adj*/) {
}
void UidObserver::binderDied(const wp<IBinder>& /*who*/) {
diff --git a/services/mediaresourcemanager/UidObserver.h b/services/mediaresourcemanager/UidObserver.h
index ed76839..b5cc3b9 100644
--- a/services/mediaresourcemanager/UidObserver.h
+++ b/services/mediaresourcemanager/UidObserver.h
@@ -74,7 +74,7 @@
void onUidIdle(uid_t uid, bool disabled) override;
void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
int32_t capability) override;
- void onUidProcAdjChanged(uid_t uid) override;
+ void onUidProcAdjChanged(uid_t uid, int32_t adj) override;
// IServiceManager::LocalRegistrationCallback implementation.
void onServiceRegistration(const String16& name,
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 2b94dbf..e7d14a0 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -196,11 +196,11 @@
: AUDIO_SOURCE_DEFAULT;
audio_flags_mask_t flags;
if (direction == AAUDIO_DIRECTION_OUTPUT) {
- flags = static_cast<audio_flags_mask_t>(AUDIO_FLAG_LOW_LATENCY
- | AAudioConvert_allowCapturePolicyToAudioFlagsMask(
+ flags = AAudio_computeAudioFlagsMask(
params->getAllowedCapturePolicy(),
params->getSpatializationBehavior(),
- params->isContentSpatialized()));
+ params->isContentSpatialized(),
+ AUDIO_OUTPUT_FLAG_FAST);
} else {
flags = static_cast<audio_flags_mask_t>(AUDIO_FLAG_LOW_LATENCY
| AAudioConvert_privacySensitiveToAudioFlagsMask(params->isPrivacySensitive()));