Merge "Fix CodecLooper queue block issue" into main
diff --git a/Android.bp b/Android.bp
index 302e250..7a2bb9b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -52,8 +52,8 @@
"aidl/android/media/VolumeShaperOperationFlag.aidl",
"aidl/android/media/VolumeShaperState.aidl",
],
- imports: [
- "android.media.audio.common.types-V2",
+ defaults: [
+ "latest_android_media_audio_common_types_import_interface",
],
backend: {
cpp: {
@@ -113,8 +113,8 @@
srcs: [
"aidl/android/media/audio/IHalAdapterVendorExtension.aidl",
],
- imports: [
- "android.hardware.audio.core-V1",
+ defaults: [
+ "latest_android_hardware_audio_core_import_interface",
],
backend: {
// The C++ backend is disabled transitively due to use of FMQ by the audio core HAL.
diff --git a/drm/libmediadrm/fuzzer/Android.bp b/drm/libmediadrm/fuzzer/Android.bp
index deda9ef..adc33d5 100644
--- a/drm/libmediadrm/fuzzer/Android.bp
+++ b/drm/libmediadrm/fuzzer/Android.bp
@@ -65,8 +65,16 @@
],
fuzz_config: {
cc: [
- "android-media-fuzzing-reports@google.com",
+ "android-drm-team@google.com",
],
- componentid: 155276,
+ componentid: 49079,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of libmediadrm",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
diff --git a/include/common_time/OWNERS b/include/common_time/OWNERS
deleted file mode 100644
index f9cb567..0000000
--- a/include/common_time/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-gkasten@google.com
diff --git a/include/private/media/OWNERS b/include/private/media/OWNERS
index 21723ba..10d06de 100644
--- a/include/private/media/OWNERS
+++ b/include/private/media/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 48436
elaurent@google.com
-gkasten@google.com
hunga@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/OWNERS b/media/OWNERS
index 4a25b68..976fb9e 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -10,11 +10,9 @@
philburk@google.com
pmclean@google.com
quxiangfang@google.com
-rago@google.com
robertshih@google.com
taklee@google.com
wonsik@google.com
-ytai@google.com
# go/android-fwk-media-solutions for info on areas of ownership.
include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/media/audioserver/OWNERS b/media/audioserver/OWNERS
index f9cb567..f02cbc3 100644
--- a/media/audioserver/OWNERS
+++ b/media/audioserver/OWNERS
@@ -1 +1,5 @@
-gkasten@google.com
+# Bug component: 48436
+atneya@google.com
+hunga@google.com
+philburk@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/codec2/components/dav1d/Android.bp b/media/codec2/components/dav1d/Android.bp
index c9387dd..d549ccb 100644
--- a/media/codec2/components/dav1d/Android.bp
+++ b/media/codec2/components/dav1d/Android.bp
@@ -9,8 +9,6 @@
cc_library {
name: "libcodec2_soft_av1dec_dav1d",
- // TODO: b/277797541 - enable once ready
- enabled: false,
defaults: [
"libcodec2_soft-defaults",
@@ -19,19 +17,12 @@
],
cflags: [
- "-DCODECNAME=\"c2.android.dav1d-av1.decoder\"",
+ "-DCODECNAME=\"c2.android.av1-dav1d.decoder\"",
"-Wno-unused-variable",
],
srcs: ["C2SoftDav1dDec.cpp", "C2SoftDav1dDump.cpp"],
static_libs: [
- "libdav1d_8bit",
- "libdav1d_16bit",
+ "libdav1d",
],
-
- apex_available: [
- "//apex_available:platform",
- "com.android.media.swcodec",
- ],
-
}
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 3e4247b..f056759 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "C2SoftGav1Dec"
#include "C2SoftGav1Dec.h"
+#include <android-base/properties.h>
#include <C2Debug.h>
#include <C2PlatformSupport.h>
#include <Codec2BufferUtils.h>
@@ -39,6 +40,9 @@
namespace android {
+// Property used to control the number of threads used in the gav1 decoder.
+constexpr char kNumThreadsProperty[] = "debug.c2.gav1.numthreads";
+
// codecname set and passed in as a compile flag from Android.bp
constexpr char COMPONENT_NAME[] = CODECNAME;
@@ -506,6 +510,10 @@
libgav1::DecoderSettings settings = {};
settings.threads = GetCPUCoreCount();
+ int32_t numThreads = android::base::GetIntProperty(kNumThreadsProperty, 0);
+ if (numThreads > 0 && numThreads < settings.threads) {
+ settings.threads = numThreads;
+ }
ALOGV("Using libgav1 AV1 software decoder.");
Libgav1StatusCode status = mCodecCtx->Init(&settings);
diff --git a/media/codec2/fuzzer/Android.bp b/media/codec2/fuzzer/Android.bp
index dd68e7e..b387b2c 100644
--- a/media/codec2/fuzzer/Android.bp
+++ b/media/codec2/fuzzer/Android.bp
@@ -41,8 +41,17 @@
fuzz_config: {
cc: [
- "wonsik@google.com",
+ "android-fwk-video@google.com",
],
+ componentid: 1344,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of libcodec2",
+ vector: "remote",
+ service_privilege: "constrained",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
diff --git a/media/codec2/hal/aidl/Android.bp b/media/codec2/hal/aidl/Android.bp
index a313250..73cae93 100644
--- a/media/codec2/hal/aidl/Android.bp
+++ b/media/codec2/hal/aidl/Android.bp
@@ -165,18 +165,15 @@
defaults: [
"libcodec2-aidl-defaults",
"service_fuzzer_defaults",
+ "libcodec2-runtime-libs",
],
shared_libs: [
"libcodec2_vndk",
-
- "libcodec2_soft_avcdec",
- "libcodec2_soft_avcenc",
- "libcodec2_soft_aacdec",
- "libcodec2_soft_aacenc",
],
fuzz_config: {
cc: [
"wonsik@google.com",
],
+ triage_assignee: "waghpawan@google.com",
},
}
diff --git a/media/codec2/hal/aidl/Component.cpp b/media/codec2/hal/aidl/Component.cpp
index 392e3c6..4f5b899 100644
--- a/media/codec2/hal/aidl/Component.cpp
+++ b/media/codec2/hal/aidl/Component.cpp
@@ -292,7 +292,7 @@
static constexpr IComponent::BlockPoolAllocator::Tag ALLOCATOR_ID =
IComponent::BlockPoolAllocator::allocatorId;
static constexpr IComponent::BlockPoolAllocator::Tag IGBA =
- IComponent::BlockPoolAllocator::igba;
+ IComponent::BlockPoolAllocator::allocator;
c2_status_t status = C2_OK;
switch (allocator.getTag()) {
case ALLOCATOR_ID:
diff --git a/media/codec2/hal/aidl/fuzzer.cpp b/media/codec2/hal/aidl/fuzzer.cpp
index c1a2762..111ef26 100644
--- a/media/codec2/hal/aidl/fuzzer.cpp
+++ b/media/codec2/hal/aidl/fuzzer.cpp
@@ -29,6 +29,7 @@
std::shared_ptr<C2ComponentStore> store = ::android::GetCodec2PlatformComponentStore();
std::shared_ptr<ComponentStore> binder = SharedRefBase::make<ComponentStore>(store);
+ signal(SIGPIPE, SIG_IGN);
fuzzService(binder->asBinder().get(), FuzzedDataProvider(data, size));
return 0;
diff --git a/media/codec2/hal/client/GraphicBufferAllocator.cpp b/media/codec2/hal/client/GraphicBufferAllocator.cpp
index 7045537..8f489ec 100644
--- a/media/codec2/hal/client/GraphicBufferAllocator.cpp
+++ b/media/codec2/hal/client/GraphicBufferAllocator.cpp
@@ -13,6 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-GraphicBufferAllocator"
+
#include <gui/IProducerListener.h>
#include <media/stagefright/foundation/ADebug.h>
diff --git a/media/codec2/hal/client/GraphicsTracker.cpp b/media/codec2/hal/client/GraphicsTracker.cpp
index 573ded8..0848fc6 100644
--- a/media/codec2/hal/client/GraphicsTracker.cpp
+++ b/media/codec2/hal/client/GraphicsTracker.cpp
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "GraphicsTracker"
#include <fcntl.h>
#include <unistd.h>
@@ -73,11 +75,19 @@
}
GraphicsTracker::BufferItem::BufferItem(
- uint32_t generation,
- AHardwareBuffer_Desc *desc, AHardwareBuffer *pBuf) :
+ uint32_t generation, AHardwareBuffer *pBuf, uint64_t usage) :
mInit{true}, mGeneration{generation}, mSlot{-1},
- mBuf{pBuf}, mUsage{::android::AHardwareBuffer_convertToGrallocUsageBits(desc->usage)},
+ mBuf{pBuf}, mUsage{usage},
mFence{Fence::NO_FENCE} {
+ if (__builtin_available(android __ANDROID_API_T__, *)) {
+ int ret = AHardwareBuffer_getId(mBuf, &mId);
+ if (ret != ::android::OK) {
+ mInit = false;
+ mBuf = nullptr;
+ return;
+ }
+ }
+ AHardwareBuffer_acquire(mBuf);
}
GraphicsTracker::BufferItem::~BufferItem() {
@@ -86,7 +96,8 @@
}
}
-sp<GraphicBuffer> GraphicsTracker::BufferItem::updateBuffer(
+
+std::shared_ptr<GraphicsTracker::BufferItem> GraphicsTracker::BufferItem::migrateBuffer(
uint64_t newUsage, uint32_t newGeneration) {
if (!mInit) {
return nullptr;
@@ -111,21 +122,28 @@
return nullptr;
}
- GraphicBuffer *gb = ::android::AHardwareBuffer_to_GraphicBuffer(newBuf);
- if (!gb) {
- AHardwareBuffer_release(newBuf);
+ std::shared_ptr<BufferItem> newBuffer =
+ std::make_shared<BufferItem>(newGeneration, newBuf, newUsage);
+ AHardwareBuffer_release(newBuf);
+ return newBuffer;
+}
+
+sp<GraphicBuffer> GraphicsTracker::BufferItem::getGraphicBuffer() {
+ if (!mInit) {
return nullptr;
}
-
- gb->setGenerationNumber(newGeneration);
- mUsage = newUsage;
- mGeneration = newGeneration;
- AHardwareBuffer_release(mBuf);
- // acquire is already done when creating.
- mBuf = newBuf;
+ GraphicBuffer *gb = ::android::AHardwareBuffer_to_GraphicBuffer(mBuf);
+ if (!gb) {
+ return nullptr;
+ }
+ gb->setGenerationNumber(mGeneration);
return gb;
}
+GraphicsTracker::BufferCache::~BufferCache() {
+ ALOGV("BufferCache destruction: generation(%d), igbp(%d)", mGeneration, (bool)mIgbp);
+}
+
void GraphicsTracker::BufferCache::waitOnSlot(int slot) {
// TODO: log
CHECK(0 <= slot && slot < kNumSlots);
@@ -138,6 +156,7 @@
void GraphicsTracker::BufferCache::blockSlot(int slot) {
CHECK(0 <= slot && slot < kNumSlots);
+ ALOGV("block slot %d", slot);
BlockedSlot *p = &mBlockedSlots[slot];
std::unique_lock<std::mutex> l(p->l);
p->blocked = true;
@@ -145,6 +164,7 @@
void GraphicsTracker::BufferCache::unblockSlot(int slot) {
CHECK(0 <= slot && slot < kNumSlots);
+ ALOGV("unblock slot %d", slot);
BlockedSlot *p = &mBlockedSlots[slot];
std::unique_lock<std::mutex> l(p->l);
p->blocked = false;
@@ -153,7 +173,8 @@
}
GraphicsTracker::GraphicsTracker(int maxDequeueCount)
- : mMaxDequeue{maxDequeueCount}, mMaxDequeueRequested{maxDequeueCount},
+ : mBufferCache(new BufferCache()), mMaxDequeue{maxDequeueCount},
+ mMaxDequeueRequested{maxDequeueCount},
mMaxDequeueCommitted{maxDequeueCount},
mMaxDequeueRequestedSeqId{0UL}, mMaxDequeueCommittedSeqId{0ULL},
mDequeueable{maxDequeueCount},
@@ -177,6 +198,7 @@
mWritePipeFd.reset(pipefd[1]);
mEventQueueThread = std::thread([this](){processEvent();});
+ writeIncDequeueable(mDequeueable);
CHECK(ret >= 0);
CHECK(mEventQueueThread.joinable());
@@ -185,9 +207,6 @@
GraphicsTracker::~GraphicsTracker() {
stop();
if (mEventQueueThread.joinable()) {
- std::unique_lock<std::mutex> l(mEventLock);
- l.unlock();
- mEventCv.notify_one();
mEventQueueThread.join();
}
}
@@ -327,6 +346,7 @@
void GraphicsTracker::updateDequeueConf() {
std::shared_ptr<BufferCache> cache;
int dequeueCommit;
+ ALOGV("trying to update max dequeue count");
std::unique_lock<std::mutex> cl(mConfigLock);
{
std::unique_lock<std::mutex> l(mLock);
@@ -374,6 +394,11 @@
}
+int GraphicsTracker::getCurDequeueable() {
+ std::unique_lock<std::mutex> l(mLock);
+ return mDequeueable;
+}
+
void GraphicsTracker::stop() {
bool expected = false;
std::unique_lock<std::mutex> l(mEventLock);
@@ -381,6 +406,9 @@
if (updated) {
int writeFd = mWritePipeFd.release();
::close(writeFd);
+ int readFd = mReadPipeFd.release();
+ ::close(readFd);
+ mEventCv.notify_one();
}
}
@@ -470,6 +498,7 @@
}
if (ret == 0) {
// writing end is closed
+ ALOGE("writing end for the waitable object seems to be closed");
return C2_BAD_STATE;
}
mDequeueable--;
@@ -492,6 +521,7 @@
CHECK(it != cache->mBuffers.end());
it->second->mFence = fence;
*pBuffer = it->second;
+ ALOGV("an allocated buffer already cached, updated Fence");
} else if (cache.get() == mBufferCache.get() && mBufferCache->mIgbp) {
// Cache the buffer if it is allocated from the current IGBP
CHECK(slot >= 0);
@@ -499,6 +529,7 @@
if (!ret.second) {
ret.first->second = *pBuffer;
}
+ ALOGV("an allocated buffer not cached from the current IGBP");
}
uint64_t bid = (*pBuffer)->mId;
auto mapRet = mDequeued.emplace(bid, *pBuffer);
@@ -520,7 +551,7 @@
// retrieved by commitAllocate();
c2_status_t GraphicsTracker::_allocate(const std::shared_ptr<BufferCache> &cache,
uint32_t width, uint32_t height, PixelFormat format,
- int64_t usage,
+ uint64_t usage,
bool *cached,
int *rSlotId,
sp<Fence> *rFence,
@@ -545,11 +576,21 @@
return ret == ::android::NO_MEMORY ? C2_NO_MEMORY : C2_CORRUPTED;
}
*cached = false;
- *buffer = std::make_shared<BufferItem>(generation, &desc, buf);
+ *rSlotId = -1;
+ *rFence = Fence::NO_FENCE;
+ *buffer = std::make_shared<BufferItem>(generation, buf, usage);
+ AHardwareBuffer_release(buf); // remove an acquire count from
+ // AHwb_allocate().
if (!*buffer) {
- AHardwareBuffer_release(buf);
+ ALOGE("direct allocation of AHB successful, but failed to create BufferItem");
return C2_NO_MEMORY;
}
+ if (!(*buffer)->mInit) {
+ ALOGE("direct allocation of AHB successful, but BufferItem init failed");
+ buffer->reset();
+ return C2_CORRUPTED;
+ }
+ ALOGV("allocate: direct allocate without igbp");
return C2_OK;
}
@@ -578,19 +619,29 @@
sp<GraphicBuffer> realloced;
status = igbp->requestBuffer(slotId, &realloced);
if (status != ::android::OK) {
+ ALOGE("allocate by dequeueBuffer() successful, but requestBuffer() failed %d",
+ status);
igbp->cancelBuffer(slotId, fence);
return C2_CORRUPTED;
}
*buffer = std::make_shared<BufferItem>(generation, slotId, realloced, fence);
+ if (!*buffer) {
+ ALOGE("allocate by dequeueBuffer() successful, but creating BufferItem failed");
+ igbp->cancelBuffer(slotId, fence);
+ return C2_NO_MEMORY;
+ }
if (!(*buffer)->mInit) {
+ ALOGE("allocate by dequeueBuffer() successful, but BufferItem init failed");
buffer->reset();
igbp->cancelBuffer(slotId, fence);
return C2_CORRUPTED;
}
*cached = false;
- return C2_OK;
+ } else {
+ *cached = true;
}
- *cached = true;
+ ALOGV("allocate: a new allocated buffer from igbp cached %d, slot: %d",
+ *cached, slotId);
*rSlotId = slotId;
*rFence = fence;
return C2_OK;
@@ -600,6 +651,7 @@
uint32_t width, uint32_t height, PixelFormat format, uint64_t usage,
AHardwareBuffer **buf, sp<Fence> *rFence) {
if (mStopped.load() == true) {
+ ALOGE("cannot allocate due to being stopped");
return C2_BAD_STATE;
}
std::shared_ptr<BufferCache> cache;
@@ -607,6 +659,7 @@
if (res != C2_OK) {
return res;
}
+ ALOGV("allocatable or dequeueable");
bool cached = false;
int slotId;
@@ -616,6 +669,8 @@
res = _allocate(cache, width, height, format, usage, &cached, &slotId, &fence, &buffer);
commitAllocate(res, cache, cached, slotId, fence, &buffer, &updateDequeue);
if (res == C2_OK) {
+ ALOGV("allocated a buffer width:%u height:%u pixelformat:%d usage:%llu",
+ width, height, format, (unsigned long long)usage);
*buf = buffer->mBuf;
*rFence = buffer->mFence;
// *buf should be valid even if buffer is dtor-ed.
@@ -668,14 +723,16 @@
void GraphicsTracker::commitDeallocate(
std::shared_ptr<BufferCache> &cache, int slotId, uint64_t bid) {
- std::lock_guard<std::mutex> l(mLock);
+ std::unique_lock<std::mutex> l(mLock);
size_t del1 = mDequeued.erase(bid);
size_t del2 = mDeallocating.erase(bid);
CHECK(del1 > 0 && del2 > 0);
- mDequeueable++;
if (cache) {
cache->unblockSlot(slotId);
}
+ mDequeueable++;
+ l.unlock();
+ writeIncDequeueable(1);
}
@@ -707,6 +764,7 @@
c2_status_t GraphicsTracker::requestRender(uint64_t bid, std::shared_ptr<BufferCache> *cache,
std::shared_ptr<BufferItem> *pBuffer,
+ bool *fromCache,
bool *updateDequeue) {
std::unique_lock<std::mutex> l(mLock);
if (mDeallocating.find(bid) != mDeallocating.end()) {
@@ -737,23 +795,35 @@
auto it = mBufferCache->mBuffers.find(buffer->mSlot);
CHECK(it != mBufferCache->mBuffers.end() && it->second.get() == buffer.get());
mBufferCache->blockSlot(buffer->mSlot);
+ *fromCache = true;
+ } else {
+ *fromCache = false;
}
*pBuffer = buffer;
mDeallocating.emplace(bid);
return C2_OK;
}
-void GraphicsTracker::commitRender(uint64_t origBid,
- const std::shared_ptr<BufferCache> &cache,
+void GraphicsTracker::commitRender(const std::shared_ptr<BufferCache> &cache,
const std::shared_ptr<BufferItem> &buffer,
+ const std::shared_ptr<BufferItem> &oldBuffer,
+ bool bufferReplaced,
bool *updateDequeue) {
std::unique_lock<std::mutex> l(mLock);
- uint64_t bid = buffer->mId;
+ uint64_t origBid = oldBuffer ? oldBuffer->mId : buffer->mId;
- if (cache.get() != mBufferCache.get()) {
+ if (cache) {
+ cache->unblockSlot(buffer->mSlot);
+ if (oldBuffer) {
+ // migrated, register the new buffer to the cache.
+ cache->mBuffers.emplace(buffer->mSlot, buffer);
+ }
+ }
+ mDeallocating.erase(origBid);
+ mDequeued.erase(origBid);
+
+ if (cache.get() != mBufferCache.get() || bufferReplaced) {
// Surface changed, no need to wait for buffer being released.
- mDeallocating.erase(bid);
- mDequeued.erase(bid);
if (adjustDequeueConfLocked(updateDequeue)) {
return;
}
@@ -762,13 +832,6 @@
writeIncDequeueable(1);
return;
}
-
- if (origBid != bid) {
- // migration happened, need to register the buffer to Cache
- mBufferCache->mBuffers.emplace(buffer->mSlot, buffer);
- }
- mDeallocating.erase(bid);
- mDequeued.erase(bid);
}
c2_status_t GraphicsTracker::render(const C2ConstGraphicBlock& blk,
@@ -782,57 +845,60 @@
}
std::shared_ptr<BufferCache> cache;
std::shared_ptr<BufferItem> buffer;
+ std::shared_ptr<BufferItem> oldBuffer;
bool updateDequeue = false;
- res = requestRender(bid, &cache, &buffer, &updateDequeue);
+ bool fromCache = false;
+ res = requestRender(bid, &cache, &buffer, &fromCache, &updateDequeue);
if (res != C2_OK) {
if (updateDequeue) {
updateDequeueConf();
}
return res;
}
- ::android::status_t migrateRes = ::android::OK;
- ::android::status_t renderRes = ::android::OK;
- if (cache->mGeneration != buffer->mGeneration) {
+ int cacheSlotId = fromCache ? buffer->mSlot : -1;
+ ALOGV("render prepared: igbp(%d) slot(%d)", bool(cache->mIgbp), cacheSlotId);
+ if (!fromCache) {
+ // The buffer does not come from the current cache.
+ // The buffer is needed to be migrated(attached).
uint64_t newUsage = 0ULL;
- int slotId = -1;;
(void) cache->mIgbp->getConsumerUsage(&newUsage);
- sp<GraphicBuffer> gb = buffer->updateBuffer(newUsage, cache->mGeneration);
- if (gb) {
- migrateRes = cache->mIgbp->attachBuffer(&(buffer->mSlot), gb);
- } else {
- ALOGW("realloc-ing a new buffer for migration failed");
- migrateRes = ::android::INVALID_OPERATION;
- }
- }
- if (migrateRes == ::android::OK) {
- renderRes = cache->mIgbp->queueBuffer(buffer->mSlot, input, output);
- if (renderRes != ::android::OK) {
- CHECK(renderRes != ::android::BAD_VALUE);
- }
- }
- if (migrateRes != ::android::OK || renderRes != ::android::OK) {
- // since it is not renderable, just de-allocate
- if (migrateRes != ::android::OK) {
+ std::shared_ptr<BufferItem> newBuffer =
+ buffer->migrateBuffer(newUsage, cache->mGeneration);
+ sp<GraphicBuffer> gb = newBuffer ? newBuffer->getGraphicBuffer() : nullptr;
+
+ if (!gb) {
+ ALOGE("render: realloc-ing a new buffer for migration failed");
std::shared_ptr<BufferCache> nullCache;
commitDeallocate(nullCache, -1, bid);
- } else {
- (void) cache->mIgbp->cancelBuffer(buffer->mSlot, input.fence);
- commitDeallocate(cache, buffer->mSlot, bid);
+ return C2_REFUSED;
}
- ALOGE("migration error(%d), render error(%d)", (int)migrateRes, (int)renderRes);
+ if (cache->mIgbp->attachBuffer(&(newBuffer->mSlot), gb) != ::android::OK) {
+ ALOGE("render: attaching a new buffer to IGBP failed");
+ std::shared_ptr<BufferCache> nullCache;
+ commitDeallocate(nullCache, -1, bid);
+ return C2_REFUSED;
+ }
+ cache->waitOnSlot(newBuffer->mSlot);
+ cache->blockSlot(newBuffer->mSlot);
+ oldBuffer = buffer;
+ buffer = newBuffer;
+ }
+ ::android::status_t renderRes = cache->mIgbp->queueBuffer(buffer->mSlot, input, output);
+ ALOGV("render done: migration(%d), render(err = %d)", !fromCache, renderRes);
+ if (renderRes != ::android::OK) {
+ CHECK(renderRes != ::android::BAD_VALUE);
+ ALOGE("render: failed to queueBuffer() err = %d", renderRes);
+ (void) cache->mIgbp->cancelBuffer(buffer->mSlot, input.fence);
+ commitDeallocate(cache, buffer->mSlot, bid);
return C2_REFUSED;
}
updateDequeue = false;
- commitRender(bid, cache, buffer, &updateDequeue);
+ commitRender(cache, buffer, oldBuffer, output->bufferReplaced, &updateDequeue);
if (updateDequeue) {
updateDequeueConf();
}
- if (output->bufferReplaced) {
- // in case of buffer drop during render
- onReleased(cache->mGeneration);
- }
return C2_OK;
}
diff --git a/media/codec2/hal/client/client.cpp b/media/codec2/hal/client/client.cpp
index ab6505e..1e9aa7f 100644
--- a/media/codec2/hal/client/client.cpp
+++ b/media/codec2/hal/client/client.cpp
@@ -16,8 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Codec2Client"
+#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <android-base/logging.h>
-
+#include <utils/Trace.h>
#include <codec2/hidl/client.h>
#include <C2Debug.h>
#include <C2BufferPriv.h>
@@ -2324,6 +2325,7 @@
const C2ConstGraphicBlock& block,
const QueueBufferInput& input,
QueueBufferOutput* output) {
+ ScopedTrace trace(ATRACE_TAG,"Codec2Client::Component::queueToOutputSurface");
return mOutputBufferQueue->outputBuffer(block, input, output);
}
diff --git a/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h b/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h
index 1fd9049..4640243 100644
--- a/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h
+++ b/media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h
@@ -153,6 +153,11 @@
c2_status_t getWaitableFd(int *pipeFd);
/**
+ * Get the current max allocatable/dequeueable buffer count without de-allocating.
+ */
+ int getCurDequeueable();
+
+ /**
* Ends to use the class. after the call, allocate will fail.
*/
void stop();
@@ -177,12 +182,15 @@
// Create from an AHB (no slot information)
// Should be attached to IGBP for rendering
BufferItem(uint32_t generation,
- AHardwareBuffer_Desc *desc,
- AHardwareBuffer *pBuf);
+ AHardwareBuffer *pBuf,
+ uint64_t usage);
~BufferItem();
- sp<GraphicBuffer> updateBuffer(uint64_t newUsage, uint32_t newGeneration);
+ std::shared_ptr<BufferItem> migrateBuffer(uint64_t newUsage, uint32_t newGeneration);
+
+ sp<GraphicBuffer> getGraphicBuffer();
+
};
struct BufferCache {
@@ -212,6 +220,8 @@
BufferCache(uint64_t bqId, uint32_t generation, const sp<IGraphicBufferProducer>& igbp) :
mBqId{bqId}, mGeneration{generation}, mIgbp{igbp} {}
+ ~BufferCache();
+
void waitOnSlot(int slot);
void blockSlot(int slot);
@@ -287,6 +297,7 @@
sp<Fence> *rFence);
c2_status_t requestRender(uint64_t bid, std::shared_ptr<BufferCache> *cache,
std::shared_ptr<BufferItem> *pBuffer,
+ bool *fromCache,
bool *updateDequeue);
void commitAllocate(c2_status_t res,
@@ -295,14 +306,15 @@
std::shared_ptr<BufferItem> *buffer,
bool *updateDequeue);
void commitDeallocate(std::shared_ptr<BufferCache> &cache, int slotId, uint64_t bid);
- void commitRender(uint64_t origBid,
- const std::shared_ptr<BufferCache> &cache,
+ void commitRender(const std::shared_ptr<BufferCache> &cache,
const std::shared_ptr<BufferItem> &buffer,
+ const std::shared_ptr<BufferItem> &oldBuffer,
+ bool bufferReplaced,
bool *updateDequeue);
c2_status_t _allocate(
const std::shared_ptr<BufferCache> &cache,
- uint32_t width, uint32_t height, PixelFormat format, int64_t usage,
+ uint32_t width, uint32_t height, PixelFormat format, uint64_t usage,
bool *cached, int *rSlotId, sp<Fence> *rFence,
std::shared_ptr<BufferItem> *buffer);
diff --git a/media/codec2/hal/client/output.cpp b/media/codec2/hal/client/output.cpp
index 4eebd1c..f86e048 100644
--- a/media/codec2/hal/client/output.cpp
+++ b/media/codec2/hal/client/output.cpp
@@ -16,7 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Codec2-OutputBufferQueue"
+#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <android-base/logging.h>
+#include <utils/Trace.h>
#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
#include <codec2/hidl/output.h>
@@ -336,9 +338,25 @@
}
void OutputBufferQueue::stop() {
- std::scoped_lock<std::mutex> l(mMutex);
- mStopped = true;
- mOwner.reset(); // destructor of the block will not triger IGBP::cancel()
+ std::shared_ptr<C2SurfaceSyncMemory> oldMem;
+ {
+ std::scoped_lock<std::mutex> l(mMutex);
+ if (mStopped) {
+ return;
+ }
+ mStopped = true;
+ mOwner.reset(); // destructor of the block will not trigger IGBP::cancel()
+ // basically configuring null surface
+ oldMem = mSyncMem;
+ mSyncMem.reset();
+ mIgbp.clear();
+ mGeneration = 0;
+ mBqId = 0;
+ }
+ {
+ std::scoped_lock<std::mutex> l(mOldMutex);
+ mOldMem = oldMem;
+ }
}
bool OutputBufferQueue::registerBuffer(const C2ConstGraphicBlock& block) {
@@ -388,6 +406,7 @@
uint32_t generation;
uint64_t bqId;
int32_t bqSlot;
+ ScopedTrace trace(ATRACE_TAG,"Codec2-OutputBufferQueue::outputBuffer");
bool display = V1_0::utils::displayBufferQueueBlock(block);
if (!getBufferQueueAssignment(block, &generation, &bqId, &bqSlot) ||
bqId == 0) {
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index e737006..cd3a80f 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1915,8 +1915,16 @@
}
comp = state->comp;
}
- status_t err = comp->stop();
+
+ // Note: Logically mChannel->stopUseOutputSurface() should be after comp->stop().
+ // But in the case some HAL implementations hang forever on comp->stop().
+ // (HAL is waiting for C2Fence until fetchGraphicBlock unblocks and not
+ // completing stop()).
+ // So we reverse their order for stopUseOutputSurface() to notify C2Fence waiters
+ // prior to comp->stop().
+ // See also b/300350761.
mChannel->stopUseOutputSurface(pushBlankBuffer);
+ status_t err = comp->stop();
if (err != C2_OK) {
// TODO: convert err into status_t
mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
@@ -2004,8 +2012,15 @@
}
comp = state->comp;
}
- comp->release();
+ // Note: Logically mChannel->stopUseOutputSurface() should be after comp->release().
+ // But in the case some HAL implementations hang forever on comp->release().
+ // (HAL is waiting for C2Fence until fetchGraphicBlock unblocks and not
+ // completing release()).
+ // So we reverse their order for stopUseOutputSurface() to notify C2Fence waiters
+ // prior to comp->release().
+ // See also b/300350761.
mChannel->stopUseOutputSurface(pushBlankBuffer);
+ comp->release();
{
Mutexed<State>::Locked state(mState);
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index c93b7d0..bddf3cb 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -598,6 +598,8 @@
size_t bufferSize = 0;
c2_status_t blockRes = C2_OK;
bool copied = false;
+ ScopedTrace trace(ATRACE_TAG, android::base::StringPrintf(
+ "CCodecBufferChannel::decrypt(%s)", mName).c_str());
if (mSendEncryptedInfoBuffer) {
static const C2MemoryUsage kDefaultReadWriteUsage{
C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
diff --git a/media/codec2/vndk/C2Buffer.cpp b/media/codec2/vndk/C2Buffer.cpp
index 018e269..a56a216 100644
--- a/media/codec2/vndk/C2Buffer.cpp
+++ b/media/codec2/vndk/C2Buffer.cpp
@@ -16,7 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "C2Buffer"
+#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <utils/Log.h>
+#include <utils/Trace.h>
#include <list>
#include <map>
@@ -33,6 +35,7 @@
namespace {
+using android::ScopedTrace;
using android::C2AllocatorBlob;
using android::C2AllocatorGralloc;
using android::C2AllocatorIon;
@@ -1159,6 +1162,7 @@
uint32_t capacity,
C2MemoryUsage usage,
std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
+ ScopedTrace trace(ATRACE_TAG,"C2PooledBlockPool::fetchLinearBlock");
if (mBufferPoolVer == VER_HIDL && mImpl) {
return mImpl->fetchLinearBlock(capacity, usage, block);
}
@@ -1174,6 +1178,7 @@
uint32_t format,
C2MemoryUsage usage,
std::shared_ptr<C2GraphicBlock> *block) {
+ ScopedTrace trace(ATRACE_TAG,"C2PooledBlockPool::fetchGraphicBlock");
if (mBufferPoolVer == VER_HIDL && mImpl) {
return mImpl->fetchGraphicBlock(width, height, format, usage, block);
}
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index f6f97da..61aafa7 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -1081,6 +1081,7 @@
emplace("libcodec2_soft_amrwbenc.so");
//emplace("libcodec2_soft_av1dec_aom.so"); // deprecated for the gav1 implementation
emplace("libcodec2_soft_av1dec_gav1.so");
+ emplace("libcodec2_soft_av1dec_dav1d.so");
emplace("libcodec2_soft_av1enc.so");
emplace("libcodec2_soft_avcdec.so");
emplace("libcodec2_soft_avcenc.so");
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
index 5fb0c8f..960fa79 100644
--- a/media/codec2/vndk/platform/C2BqBuffer.cpp
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -16,8 +16,10 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "C2BqBuffer"
+#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <android/hardware_buffer.h>
#include <utils/Log.h>
+#include <utils/Trace.h>
#include <ui/BufferQueueDefs.h>
#include <ui/GraphicBuffer.h>
@@ -37,6 +39,7 @@
#include <map>
#include <mutex>
+using ::android::ScopedTrace;
using ::android::BufferQueueDefs::NUM_BUFFER_SLOTS;
using ::android::C2AllocatorGralloc;
using ::android::C2AndroidMemoryUsage;
@@ -1063,6 +1066,7 @@
uint32_t format,
C2MemoryUsage usage,
std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
+ ScopedTrace trace(ATRACE_TAG,"C2BufferQueueBlockPool::fetchGraphicBlock");
if (mImpl) {
return mImpl->fetchGraphicBlock(width, height, format, usage, block, nullptr);
}
diff --git a/media/common_time/OWNERS b/media/common_time/OWNERS
deleted file mode 100644
index f9cb567..0000000
--- a/media/common_time/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-gkasten@google.com
diff --git a/media/janitors/audio_OWNERS b/media/janitors/audio_OWNERS
new file mode 100644
index 0000000..0d0c487
--- /dev/null
+++ b/media/janitors/audio_OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 48436
+# gerrit owner/approvers in the audio team
+# For catch-all/last resort from other projects
+
+elaurent@google.com # lead
+hunga@google.com
+jmtrivi@google.com
+philburk@google.com
diff --git a/media/janitors/media_reliability_OWNERS b/media/janitors/media_reliability_OWNERS
new file mode 100644
index 0000000..cced19c
--- /dev/null
+++ b/media/janitors/media_reliability_OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 1051309
+# go/android-media-reliability
+
+essick@google.com
+nchalko@google.com
diff --git a/media/libaaudio/OWNERS b/media/libaaudio/OWNERS
index f4d51f9..3285bf3 100644
--- a/media/libaaudio/OWNERS
+++ b/media/libaaudio/OWNERS
@@ -1 +1,4 @@
+# Bug component: 48436
+jiabin@google.com
philburk@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/libaaudio/fuzzer/libaaudio_fuzzer.cpp b/media/libaaudio/fuzzer/libaaudio_fuzzer.cpp
index 0233ee1..e1ff3eb 100644
--- a/media/libaaudio/fuzzer/libaaudio_fuzzer.cpp
+++ b/media/libaaudio/fuzzer/libaaudio_fuzzer.cpp
@@ -20,7 +20,7 @@
#include <fuzzer/FuzzedDataProvider.h>
constexpr int32_t kRandomStringLength = 256;
-
+constexpr int32_t kMaxRuns = 100;
constexpr int64_t kNanosPerMillisecond = 1000 * 1000;
constexpr aaudio_direction_t kDirections[] = {
@@ -97,6 +97,7 @@
public:
~LibAaudioFuzzer() { deInit(); }
bool init();
+ void invokeAAudioSetAPIs(FuzzedDataProvider &fdp);
void process(const uint8_t *data, size_t size);
void deInit();
@@ -113,160 +114,208 @@
return true;
}
-void LibAaudioFuzzer::process(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp(data, size);
- aaudio_performance_mode_t mode =
- fdp.PickValueInArray({fdp.PickValueInArray(kPerformanceModes),
- fdp.ConsumeIntegral<int32_t>()});
+void LibAaudioFuzzer::invokeAAudioSetAPIs(FuzzedDataProvider &fdp){
+ aaudio_performance_mode_t mode = fdp.PickValueInArray(
+ {fdp.PickValueInArray(kPerformanceModes), fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setPerformanceMode(mAaudioBuilder, mode);
- int32_t deviceId = fdp.PickValueInArray(
- {AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
+ int32_t deviceId = fdp.PickValueInArray({AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setDeviceId(mAaudioBuilder, deviceId);
- std::string packageName = fdp.PickValueInArray<std::string>(
- {"android.nativemedia.aaudio", "android.app.appops.cts",
- fdp.ConsumeRandomLengthString(kRandomStringLength)});
+ std::string packageName =
+ fdp.PickValueInArray<std::string>({"android.nativemedia.aaudio", "android.app.appops.cts",
+ fdp.ConsumeRandomLengthString(kRandomStringLength)});
AAudioStreamBuilder_setPackageName(mAaudioBuilder, packageName.c_str());
- std::string attributionTag =
- fdp.ConsumeRandomLengthString(kRandomStringLength);
+ std::string attributionTag = fdp.ConsumeRandomLengthString(kRandomStringLength);
AAudioStreamBuilder_setAttributionTag(mAaudioBuilder, attributionTag.c_str());
int32_t sampleRate = fdp.PickValueInArray(kSampleRates);
AAudioStreamBuilder_setSampleRate(mAaudioBuilder, sampleRate);
- int32_t channelCount = fdp.PickValueInArray(
- {AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
+ int32_t channelCount = fdp.PickValueInArray({AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setChannelCount(mAaudioBuilder, channelCount);
- aaudio_direction_t direction = fdp.PickValueInArray(
- {fdp.PickValueInArray(kDirections), fdp.ConsumeIntegral<int32_t>()});
+ aaudio_direction_t direction =
+ fdp.PickValueInArray({fdp.PickValueInArray(kDirections), fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setDirection(mAaudioBuilder, direction);
- aaudio_format_t format = fdp.PickValueInArray(
- {fdp.PickValueInArray(kFormats), fdp.ConsumeIntegral<int32_t>()});
+ aaudio_format_t format =
+ fdp.PickValueInArray({fdp.PickValueInArray(kFormats), fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setFormat(mAaudioBuilder, format);
aaudio_sharing_mode_t sharingMode = fdp.PickValueInArray(
- {fdp.PickValueInArray(kSharingModes), fdp.ConsumeIntegral<int32_t>()});
+ {fdp.PickValueInArray(kSharingModes), fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setSharingMode(mAaudioBuilder, sharingMode);
- aaudio_usage_t usage = fdp.PickValueInArray(
- {fdp.PickValueInArray(kUsages), fdp.ConsumeIntegral<int32_t>()});
+ aaudio_usage_t usage =
+ fdp.PickValueInArray({fdp.PickValueInArray(kUsages), fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setUsage(mAaudioBuilder, usage);
aaudio_content_type_t contentType = fdp.PickValueInArray(
- {fdp.PickValueInArray(kContentTypes), fdp.ConsumeIntegral<int32_t>()});
+ {fdp.PickValueInArray(kContentTypes), fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setContentType(mAaudioBuilder, contentType);
aaudio_input_preset_t inputPreset = fdp.PickValueInArray(
- {fdp.PickValueInArray(kInputPresets), fdp.ConsumeIntegral<int32_t>()});
+ {fdp.PickValueInArray(kInputPresets), fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setInputPreset(mAaudioBuilder, inputPreset);
bool privacySensitive = fdp.ConsumeBool();
AAudioStreamBuilder_setPrivacySensitive(mAaudioBuilder, privacySensitive);
- int32_t frames = fdp.PickValueInArray(
- {AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
+ int32_t frames = fdp.PickValueInArray({AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setBufferCapacityInFrames(mAaudioBuilder, frames);
- aaudio_allowed_capture_policy_t allowedCapturePolicy =
- fdp.PickValueInArray({fdp.PickValueInArray(kAllowedCapturePolicies),
- fdp.ConsumeIntegral<int32_t>()});
- AAudioStreamBuilder_setAllowedCapturePolicy(mAaudioBuilder,
- allowedCapturePolicy);
+ aaudio_allowed_capture_policy_t allowedCapturePolicy = fdp.PickValueInArray(
+ {fdp.PickValueInArray(kAllowedCapturePolicies), fdp.ConsumeIntegral<int32_t>()});
+ AAudioStreamBuilder_setAllowedCapturePolicy(mAaudioBuilder, allowedCapturePolicy);
- aaudio_session_id_t sessionId = fdp.PickValueInArray(
- {fdp.PickValueInArray(kSessionIds), fdp.ConsumeIntegral<int32_t>()});
+ aaudio_session_id_t sessionId =
+ fdp.PickValueInArray({fdp.PickValueInArray(kSessionIds), fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setSessionId(mAaudioBuilder, sessionId);
AAudioStreamBuilder_setDataCallback(mAaudioBuilder, nullptr, nullptr);
AAudioStreamBuilder_setErrorCallback(mAaudioBuilder, nullptr, nullptr);
- int32_t framesPerDataCallback = fdp.PickValueInArray(
- {AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
- AAudioStreamBuilder_setFramesPerDataCallback(mAaudioBuilder,
- framesPerDataCallback);
+ int32_t framesPerDataCallback =
+ fdp.PickValueInArray({AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
+ AAudioStreamBuilder_setFramesPerDataCallback(mAaudioBuilder, framesPerDataCallback);
- aaudio_policy_t policy = fdp.PickValueInArray(
- {fdp.PickValueInArray(kPolicies), fdp.ConsumeIntegral<int32_t>()});
+ aaudio_policy_t policy =
+ fdp.PickValueInArray({fdp.PickValueInArray(kPolicies), fdp.ConsumeIntegral<int32_t>()});
AAudio_setMMapPolicy(policy);
- (void)AAudio_getMMapPolicy();
+}
- aaudio_result_t result =
- AAudioStreamBuilder_openStream(mAaudioBuilder, &mAaudioStream);
+void LibAaudioFuzzer::process(const uint8_t *data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ int32_t maxFrames = 0;
+ int32_t count = 0;
+ aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
+
+ invokeAAudioSetAPIs(fdp);
+
+ aaudio_result_t result = AAudioStreamBuilder_openStream(mAaudioBuilder, &mAaudioStream);
if ((result != AAUDIO_OK) || (!mAaudioStream)) {
return;
}
+ /* The 'runs' variable serves to set an upper limit on the loop iterations, preventing excessive
+ * execution.
+ */
+ int32_t runs = kMaxRuns;
+ while (fdp.remaining_bytes() > 0 && --runs) {
+ auto AAudioapi = fdp.PickValueInArray<const std::function<void()>>({
+ [&]() { (void)AAudio_getMMapPolicy(); },
- int32_t framesPerBurst = AAudioStream_getFramesPerBurst(mAaudioStream);
- uint8_t numberOfBursts = fdp.ConsumeIntegral<uint8_t>();
- int32_t maxFrames = numberOfBursts * framesPerBurst;
- int32_t requestedBufferSize =
- fdp.ConsumeIntegral<uint16_t>() * framesPerBurst;
- AAudioStream_setBufferSizeInFrames(mAaudioStream, requestedBufferSize);
+ [&]() {
+ int32_t framesPerBurst = AAudioStream_getFramesPerBurst(mAaudioStream);
+ uint8_t numberOfBursts = fdp.ConsumeIntegral<uint8_t>();
+ maxFrames = numberOfBursts * framesPerBurst;
+ int32_t requestedBufferSize = fdp.ConsumeIntegral<uint16_t>() * framesPerBurst;
+ AAudioStream_setBufferSizeInFrames(mAaudioStream, requestedBufferSize);
+ },
+ [&]() {
+ int64_t position = 0, nanoseconds = 0;
+ AAudioStream_getTimestamp(mAaudioStream, CLOCK_MONOTONIC, &position, &nanoseconds);
+ },
+ [&]() {
+ AAudioStream_requestStart(mAaudioStream);
+ },
+ [&]() {
+ AAudioStream_requestPause(mAaudioStream);
+ },
+ [&]() {
+ AAudioStream_requestFlush(mAaudioStream);
+ },
+ [&]() {
+ AAudioStream_requestStop(mAaudioStream);
+ },
+ [&]() {
+ aaudio_format_t actualFormat = AAudioStream_getFormat(mAaudioStream);
+ int32_t actualChannelCount = AAudioStream_getChannelCount(mAaudioStream);
- int64_t position = 0, nanoseconds = 0;
- AAudioStream_getTimestamp(mAaudioStream, CLOCK_MONOTONIC, &position,
- &nanoseconds);
+ count = fdp.ConsumeIntegral<int32_t>();
+ aaudio_direction_t direction = AAudioStream_getDirection(mAaudioStream);
- AAudioStream_requestStart(mAaudioStream);
-
- aaudio_format_t actualFormat = AAudioStream_getFormat(mAaudioStream);
- int32_t actualChannelCount = AAudioStream_getChannelCount(mAaudioStream);
-
- int32_t count = fdp.ConsumeIntegral<int32_t>();
- direction = AAudioStream_getDirection(mAaudioStream);
-
- if (actualFormat == AAUDIO_FORMAT_PCM_I16) {
- std::vector<int16_t> inputShortData(maxFrames * actualChannelCount, 0x0);
- if (direction == AAUDIO_DIRECTION_INPUT) {
- AAudioStream_read(mAaudioStream, inputShortData.data(), maxFrames,
- count * kNanosPerMillisecond);
- } else if (direction == AAUDIO_DIRECTION_OUTPUT) {
- AAudioStream_write(mAaudioStream, inputShortData.data(), maxFrames,
- count * kNanosPerMillisecond);
- }
- } else if (actualFormat == AAUDIO_FORMAT_PCM_FLOAT) {
- std::vector<float> inputFloatData(maxFrames * actualChannelCount, 0x0);
- if (direction == AAUDIO_DIRECTION_INPUT) {
- AAudioStream_read(mAaudioStream, inputFloatData.data(), maxFrames,
- count * kNanosPerMillisecond);
- } else if (direction == AAUDIO_DIRECTION_OUTPUT) {
- AAudioStream_write(mAaudioStream, inputFloatData.data(), maxFrames,
- count * kNanosPerMillisecond);
- }
+ if (actualFormat == AAUDIO_FORMAT_PCM_I16) {
+ std::vector<int16_t> inputShortData(maxFrames * actualChannelCount, 0x0);
+ if (direction == AAUDIO_DIRECTION_INPUT) {
+ AAudioStream_read(mAaudioStream, inputShortData.data(), maxFrames,
+ count * kNanosPerMillisecond);
+ } else if (direction == AAUDIO_DIRECTION_OUTPUT) {
+ AAudioStream_write(mAaudioStream, inputShortData.data(), maxFrames,
+ count * kNanosPerMillisecond);
+ }
+ } else if (actualFormat == AAUDIO_FORMAT_PCM_FLOAT) {
+ std::vector<float> inputFloatData(maxFrames * actualChannelCount, 0x0);
+ if (direction == AAUDIO_DIRECTION_INPUT) {
+ AAudioStream_read(mAaudioStream, inputFloatData.data(), maxFrames,
+ count * kNanosPerMillisecond);
+ } else if (direction == AAUDIO_DIRECTION_OUTPUT) {
+ AAudioStream_write(mAaudioStream, inputFloatData.data(), maxFrames,
+ count * kNanosPerMillisecond);
+ }
+ }
+ },
+ [&]() {
+ AAudioStream_waitForStateChange(mAaudioStream, AAUDIO_STREAM_STATE_UNKNOWN, &state,
+ count * kNanosPerMillisecond);
+ },
+ [&]() { (void)AAudio_convertStreamStateToText(state); },
+ [&]() {
+ (void)AAudioStream_getState(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getUsage(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getSamplesPerFrame(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getContentType(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getInputPreset(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_isPrivacySensitive(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getAllowedCapturePolicy(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getPerformanceMode(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getDeviceId(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getSharingMode(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getSessionId(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getFramesRead(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getXRunCount(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getFramesWritten(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getBufferCapacityInFrames(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_getBufferSizeInFrames(mAaudioStream);
+ },
+ [&]() {
+ (void)AAudioStream_isMMapUsed(mAaudioStream);
+ },
+ });
+ AAudioapi();
}
-
- aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
- AAudioStream_waitForStateChange(mAaudioStream, AAUDIO_STREAM_STATE_UNKNOWN,
- &state, count * kNanosPerMillisecond);
- (void)AAudio_convertStreamStateToText(state);
-
- (void)AAudioStream_getUsage(mAaudioStream);
- (void)AAudioStream_getSampleRate(mAaudioStream);
- (void)AAudioStream_getState(mAaudioStream);
- (void)AAudioStream_getSamplesPerFrame(mAaudioStream);
- (void)AAudioStream_getContentType(mAaudioStream);
- (void)AAudioStream_getInputPreset(mAaudioStream);
- (void)AAudioStream_isPrivacySensitive(mAaudioStream);
- (void)AAudioStream_getAllowedCapturePolicy(mAaudioStream);
- (void)AAudioStream_getPerformanceMode(mAaudioStream);
- (void)AAudioStream_getDeviceId(mAaudioStream);
- (void)AAudioStream_getSharingMode(mAaudioStream);
- (void)AAudioStream_getSessionId(mAaudioStream);
- (void)AAudioStream_getFramesRead(mAaudioStream);
- (void)AAudioStream_getFramesWritten(mAaudioStream);
- (void)AAudioStream_getXRunCount(mAaudioStream);
- (void)AAudioStream_getBufferCapacityInFrames(mAaudioStream);
- (void)AAudioStream_getBufferSizeInFrames(mAaudioStream);
- (void)AAudioStream_isMMapUsed(mAaudioStream);
-
- AAudioStream_requestPause(mAaudioStream);
- AAudioStream_requestFlush(mAaudioStream);
AAudioStream_release(mAaudioStream);
- AAudioStream_requestStop(mAaudioStream);
}
void LibAaudioFuzzer::deInit() {
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 30f451a..7882951 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -254,6 +254,9 @@
name: "aaudio-aidl",
unstable: true,
local_include_dir: "binding/aidl",
+ defaults: [
+ "latest_android_media_audio_common_types_import_interface",
+ ],
srcs: [
"binding/aidl/aaudio/Endpoint.aidl",
"binding/aidl/aaudio/RingBuffer.aidl",
@@ -264,7 +267,6 @@
"binding/aidl/aaudio/IAAudioService.aidl",
],
imports: [
- "android.media.audio.common.types-V2",
"audioclient-types-aidl",
"shared-file-region-aidl",
"framework-permission-aidl",
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 01e3d53..2c9e173 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -255,8 +255,10 @@
"aidl/android/media/IEffect.aidl",
"aidl/android/media/IEffectClient.aidl",
],
+ defaults: [
+ "latest_android_media_audio_common_types_import_interface",
+ ],
imports: [
- "android.media.audio.common.types-V2",
"shared-file-region-aidl",
],
backend: {
@@ -309,8 +311,10 @@
"aidl/android/media/TrackSecondaryOutputInfo.aidl",
"aidl/android/media/SurroundSoundConfig.aidl",
],
+ defaults: [
+ "latest_android_media_audio_common_types_import_interface",
+ ],
imports: [
- "android.media.audio.common.types-V2",
"framework-permission-aidl",
],
backend: {
@@ -351,12 +355,11 @@
"aidl/android/media/AudioVolumeGroup.aidl",
"aidl/android/media/DeviceRole.aidl",
"aidl/android/media/SoundTriggerSession.aidl",
- "aidl/android/media/SpatializationLevel.aidl",
- "aidl/android/media/SpatializationMode.aidl",
- "aidl/android/media/SpatializerHeadTrackingMode.aidl",
+ ],
+ defaults: [
+ "latest_android_media_audio_common_types_import_interface",
],
imports: [
- "android.media.audio.common.types-V2",
"audioclient-types-aidl",
],
backend: {
@@ -402,8 +405,10 @@
"aidl/android/media/ISoundDoseCallback.aidl",
"aidl/android/media/SoundDoseRecord.aidl",
],
+ defaults: [
+ "latest_android_media_audio_common_types_import_interface",
+ ],
imports: [
- "android.media.audio.common.types-V2",
"audioclient-types-aidl",
"av-types-aidl",
"effect-aidl",
@@ -439,8 +444,10 @@
"aidl/android/media/IAudioPolicyService.aidl",
"aidl/android/media/IAudioPolicyServiceClient.aidl",
],
+ defaults: [
+ "latest_android_media_audio_common_types_import_interface",
+ ],
imports: [
- "android.media.audio.common.types-V2",
"audioclient-types-aidl",
"audiopolicy-types-aidl",
"capture_state_listener-aidl",
@@ -474,6 +481,9 @@
"aidl/android/media/ISpatializer.aidl",
"aidl/android/media/ISpatializerHeadTrackingCallback.aidl",
],
+ defaults: [
+ "latest_android_media_audio_common_types_import_interface",
+ ],
imports: [
"audiopolicy-types-aidl",
],
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 6616197..5b94845 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -108,7 +108,7 @@
}
// establish binder interface to AudioFlinger service
-const sp<IAudioFlinger> AudioSystem::get_audio_flinger() {
+const sp<IAudioFlinger> AudioSystem::getAudioFlingerImpl(bool canStartThreadPool = true) {
sp<IAudioFlinger> af;
sp<AudioFlingerClient> afc;
bool reportNoError = false;
@@ -147,7 +147,9 @@
afc = gAudioFlingerClient;
af = gAudioFlinger;
// Make sure callbacks can be received by gAudioFlingerClient
- ProcessState::self()->startThreadPool();
+ if(canStartThreadPool) {
+ ProcessState::self()->startThreadPool();
+ }
}
const int64_t token = IPCThreadState::self()->clearCallingIdentity();
af->registerClient(afc);
@@ -156,6 +158,14 @@
return af;
}
+const sp<IAudioFlinger> AudioSystem:: get_audio_flinger() {
+ return getAudioFlingerImpl();
+}
+
+const sp<IAudioFlinger> AudioSystem:: get_audio_flinger_for_fuzzer() {
+ return getAudioFlingerImpl(false);
+}
+
const sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() {
// calling get_audio_flinger() will initialize gAudioFlingerClient if needed
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 4bd12b8..01edf72 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -898,6 +898,22 @@
return NO_ERROR;
}
+status_t AudioFlingerClientAdapter::getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *mixPort) const {
+ if (devicePort == nullptr || mixPort == nullptr) {
+ return BAD_VALUE;
+ }
+ media::AudioPortFw devicePortAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_v7_AudioPortFw(*devicePort));
+ media::AudioPortFw mixPortAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_v7_AudioPortFw(*mixPort));
+ media::AudioPortFw aidlRet;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mDelegate->getAudioMixPort(devicePortAidl, mixPortAidl, &aidlRet)));
+ *mixPort = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortFw_audio_port_v7(aidlRet));
+ return OK;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// AudioFlingerServerAdapter
AudioFlingerServerAdapter::AudioFlingerServerAdapter(
@@ -1444,4 +1460,16 @@
return Status::fromStatusT(mDelegate->getAudioPolicyConfig(_aidl_return));
}
+Status AudioFlingerServerAdapter::getAudioMixPort(const media::AudioPortFw &devicePort,
+ const media::AudioPortFw &mixPort,
+ media::AudioPortFw *_aidl_return) {
+ audio_port_v7 devicePortLegacy = VALUE_OR_RETURN_BINDER(
+ aidl2legacy_AudioPortFw_audio_port_v7(devicePort));
+ audio_port_v7 mixPortLegacy = VALUE_OR_RETURN_BINDER(
+ aidl2legacy_AudioPortFw_audio_port_v7(mixPort));
+ RETURN_BINDER_IF_ERROR(mDelegate->getAudioMixPort(&devicePortLegacy, &mixPortLegacy));
+ *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_port_v7_AudioPortFw(mixPortLegacy));
+ return Status::ok();
+}
+
} // namespace android
diff --git a/media/libaudioclient/OWNERS b/media/libaudioclient/OWNERS
index 034d161..afc4d9b 100644
--- a/media/libaudioclient/OWNERS
+++ b/media/libaudioclient/OWNERS
@@ -1,4 +1,6 @@
-gkasten@google.com
+# Bug component: 48436
+atneya@google.com
hunga@google.com
jmtrivi@google.com
mnaganov@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index 6412810..31d3af5 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -288,6 +288,11 @@
*/
AudioPolicyConfig getAudioPolicyConfig();
+ /**
+ * Get the attributes of the mix port when connecting to the given device port.
+ */
+ AudioPortFw getAudioMixPort(in AudioPortFw devicePort, in AudioPortFw mixPort);
+
// When adding a new method, please review and update
// IAudioFlinger.h AudioFlingerServerAdapter::Delegate::TransactionCode
// AudioFlinger.cpp AudioFlinger::onTransactWrapper()
diff --git a/media/libaudioclient/aidl/android/media/INativeSpatializerCallback.aidl b/media/libaudioclient/aidl/android/media/INativeSpatializerCallback.aidl
index 88b8108..8b30b29 100644
--- a/media/libaudioclient/aidl/android/media/INativeSpatializerCallback.aidl
+++ b/media/libaudioclient/aidl/android/media/INativeSpatializerCallback.aidl
@@ -16,8 +16,7 @@
package android.media;
-import android.media.SpatializationLevel;
-import android.media.SpatializerHeadTrackingMode;
+import android.media.audio.common.Spatialization;
/**
* The INativeSpatializerCallback interface is a callback associated to the
@@ -30,7 +29,7 @@
/** Called when the spatialization level applied by the spatializer changes
* (e.g. when the spatializer is enabled or disabled)
*/
- void onLevelChanged(SpatializationLevel level);
+ void onLevelChanged(Spatialization.Level level);
/** Called when the output stream the Spatializer is attached to changes.
* Indicates the IO Handle of the new output.
diff --git a/media/libaudioclient/aidl/android/media/ISpatializer.aidl b/media/libaudioclient/aidl/android/media/ISpatializer.aidl
index 250c450..37dd776 100644
--- a/media/libaudioclient/aidl/android/media/ISpatializer.aidl
+++ b/media/libaudioclient/aidl/android/media/ISpatializer.aidl
@@ -16,11 +16,9 @@
package android.media;
+import android.media.audio.common.HeadTracking;
+import android.media.audio.common.Spatialization;
import android.media.ISpatializerHeadTrackingCallback;
-import android.media.SpatializationLevel;
-import android.media.SpatializationMode;
-import android.media.SpatializerHeadTrackingMode;
-
/**
* The ISpatializer interface is used to control the native audio service implementation
@@ -34,21 +32,25 @@
/** Releases a ISpatializer interface previously acquired. */
void release();
- /** Reports the list of supported spatialization levels (see SpatializationLevel.aidl).
+ /**
+ * Reports the list of supported spatialization levels.
* The list should never be empty if an ISpatializer interface was successfully
* retrieved with IAudioPolicyService.getSpatializer().
*/
- SpatializationLevel[] getSupportedLevels();
+ Spatialization.Level[] getSupportedLevels();
- /** Selects the desired spatialization level (see SpatializationLevel.aidl). Selecting a level
- * different from SpatializationLevel.NONE with create the specialized multichannel output
+ /**
+ * Selects the desired spatialization level. Selecting a level
+ * different from Spatializer.Level.NONE with create the specialized multichannel output
* mixer, create and enable the spatializer effect and let the audio policy attach eligible
* AudioTrack to this output stream.
*/
- void setLevel(SpatializationLevel level);
+ void setLevel(Spatialization.Level level);
- /** Gets the selected spatialization level (see SpatializationLevel.aidl) */
- SpatializationLevel getLevel();
+ /**
+ * Gets the selected spatialization level.
+ */
+ Spatialization.Level getLevel();
/** Reports if the spatializer engine supports head tracking or not.
* This is a pre condition independent of the fact that a head tracking sensor is
@@ -56,26 +58,33 @@
*/
boolean isHeadTrackingSupported();
- /** Reports the list of supported head tracking modes (see SpatializerHeadTrackingMode.aidl).
+ /**
+ * Reports the list of supported head tracking modes.
* The list always contains SpatializerHeadTrackingMode.DISABLED and can include other modes
* if the spatializer effect implementation supports head tracking.
* The result does not depend on currently connected sensors but reflects the capabilities
* when sensors are available.
*/
- SpatializerHeadTrackingMode[] getSupportedHeadTrackingModes();
+ HeadTracking.Mode[] getSupportedHeadTrackingModes();
- /** Selects the desired head tracking mode (see SpatializerHeadTrackingMode.aidl) */
- void setDesiredHeadTrackingMode(SpatializerHeadTrackingMode mode);
+ /**
+ * Selects the desired head tracking mode.
+ */
+ void setDesiredHeadTrackingMode(HeadTracking.Mode mode);
- /** Gets the actual head tracking mode. Can be different from the desired mode if conditions to
+ /**
+ * Gets the actual head tracking mode. Can be different from the desired mode if conditions to
* enable the desired mode are not met (e.g if the head tracking device was removed)
*/
- SpatializerHeadTrackingMode getActualHeadTrackingMode();
+ HeadTracking.Mode getActualHeadTrackingMode();
- /** Reset the head tracking algorithm to consider current head pose as neutral */
+ /**
+ * Reset the head tracking algorithm to consider current head pose as neutral
+ */
void recenterHeadTracker();
- /** Set the screen to stage transform to use by the head tracking algorithm
+ /**
+ * Set the screen to stage transform to use by the head tracking algorithm
* The screen to stage transform is conveyed as a vector of 6 elements,
* where the first three are a translation vector and
* the last three are a rotation vector.
@@ -123,11 +132,12 @@
*/
void setFoldState(boolean folded);
- /** Reports the list of supported spatialization modess (see SpatializationMode.aidl).
+ /**
+ * Reports the list of supported spatialization modess.
* The list should never be empty if an ISpatializer interface was successfully
* retrieved with IAudioPolicyService.getSpatializer().
*/
- SpatializationMode[] getSupportedModes();
+ Spatialization.Mode[] getSupportedModes();
/**
* Registers a callback to monitor head tracking functions.
diff --git a/media/libaudioclient/aidl/android/media/ISpatializerHeadTrackingCallback.aidl b/media/libaudioclient/aidl/android/media/ISpatializerHeadTrackingCallback.aidl
index 23d5e13..615b971 100644
--- a/media/libaudioclient/aidl/android/media/ISpatializerHeadTrackingCallback.aidl
+++ b/media/libaudioclient/aidl/android/media/ISpatializerHeadTrackingCallback.aidl
@@ -16,8 +16,7 @@
package android.media;
-import android.media.SpatializationLevel;
-import android.media.SpatializerHeadTrackingMode;
+import android.media.audio.common.HeadTracking;
/**
* The ISpatializerHeadTrackingCallback interface is a callback associated to the
@@ -28,7 +27,7 @@
oneway interface ISpatializerHeadTrackingCallback {
/** Called when the head tracking mode has changed
*/
- void onHeadTrackingModeChanged(SpatializerHeadTrackingMode mode);
+ void onHeadTrackingModeChanged(HeadTracking.Mode mode);
/** Called when the head to stage pose hase been updated
* The head to stage pose is conveyed as a vector of 6 elements,
diff --git a/media/libaudioclient/aidl/android/media/SpatializationLevel.aidl b/media/libaudioclient/aidl/android/media/SpatializationLevel.aidl
deleted file mode 100644
index 961c5a1..0000000
--- a/media/libaudioclient/aidl/android/media/SpatializationLevel.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2021 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;
-
-/**
- * The spatialization level supported by the spatializer stage effect implementation.
- * Used by methods of the ISpatializer interface.
- * {@hide}
- */
-@Backing(type="byte")
-enum SpatializationLevel {
- /** Spatialization is disabled. */
- NONE = 0,
- /** The spatializer accepts audio with positional multichannel masks (e.g 5.1). */
- SPATIALIZER_MULTICHANNEL = 1,
- /** The spatializer accepts audio made of a channel bed of positional multichannels (e.g 5.1)
- * and audio objects positioned independently via meta data.
- */
- SPATIALIZER_MCHAN_BED_PLUS_OBJECTS = 2,
-}
diff --git a/media/libaudioclient/aidl/android/media/SpatializationMode.aidl b/media/libaudioclient/aidl/android/media/SpatializationMode.aidl
deleted file mode 100644
index eaaff37..0000000
--- a/media/libaudioclient/aidl/android/media/SpatializationMode.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2021 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;
-
-/**
- * The spatialization mode supported by the spatializer stage effect implementation.
- * Used by methods of the ISpatializer interface.
- * {@hide}
- */
-@Backing(type="byte")
-enum SpatializationMode {
- /** The spatializer supports binaural mode (over headphones type devices). */
- SPATIALIZER_BINAURAL = 0,
- /** The spatializer supports transaural mode (over speaker type devices). */
- SPATIALIZER_TRANSAURAL = 1,
-}
diff --git a/media/libaudioclient/aidl/android/media/SpatializerHeadTrackingMode.aidl b/media/libaudioclient/aidl/android/media/SpatializerHeadTrackingMode.aidl
deleted file mode 100644
index 58e0f61..0000000
--- a/media/libaudioclient/aidl/android/media/SpatializerHeadTrackingMode.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2021 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;
-
-
-/**
- * The head tracking mode supported by the spatializer effect implementation.
- * Used by methods of the ISpatializer interface.
- * {@hide}
- */
-@Backing(type="byte")
-enum SpatializerHeadTrackingMode {
- /** Head tracking is active in a mode not listed below (forward compatibility) */
- OTHER = 0,
- /** Head tracking is disabled */
- DISABLED = 1,
- /** Head tracking is performed relative to the real work environment */
- RELATIVE_WORLD = 2,
- /** Head tracking is performed relative to the device's screen */
- RELATIVE_SCREEN = 3,
-}
diff --git a/media/libaudioclient/aidl/fuzzer/Android.bp b/media/libaudioclient/aidl/fuzzer/Android.bp
new file mode 100644
index 0000000..6093933
--- /dev/null
+++ b/media/libaudioclient/aidl/fuzzer/Android.bp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+cc_defaults {
+ name: "libaudioclient_aidl_fuzzer_defaults",
+ static_libs: [
+ "android.hardware.audio.common@7.0-enums",
+ "effect-aidl-cpp",
+ "libcgrouprc",
+ "libcgrouprc_format",
+ "libfakeservicemanager",
+ "libjsoncpp",
+ "liblog",
+ "libmediametricsservice",
+ "libmedia_helper",
+ "libprocessgroup",
+ "shared-file-region-aidl-cpp",
+ ],
+ shared_libs: [
+ "android.hardware.audio.common-util",
+ "audioclient-types-aidl-cpp",
+ "audiopolicy-aidl-cpp",
+ "audiopolicy-types-aidl-cpp",
+ "av-types-aidl-cpp",
+ "capture_state_listener-aidl-cpp",
+ "framework-permission-aidl-cpp",
+ "libaudioclient",
+ "audioflinger-aidl-cpp",
+ "libaudioflinger",
+ "libaudioclient_aidl_conversion",
+ "libaudiofoundation",
+ "libaudiomanager",
+ "libaudiopolicy",
+ "libaudioutils",
+ "libaudiopolicyservice",
+ "libaudiopolicymanagerdefault",
+ "libaudiohal",
+ "libaudioprocessing",
+ "libactivitymanager_aidl",
+ "libdl",
+ "libheadtracking",
+ "libmediautils",
+ "libmediametrics",
+ "libnblog",
+ "libnbaio",
+ "libpowermanager",
+ "libvibrator",
+ "libvndksupport",
+ "libxml2",
+ "mediametricsservice-aidl-cpp",
+ "packagemanager_aidl-cpp",
+ ],
+ header_libs: [
+ "libaudiopolicymanager_interface_headers",
+ "libaudiofoundation_headers",
+ "libaudiohal_headers",
+ "libaudioflinger_headers",
+ "libbinder_headers",
+ "libmedia_headers",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ hotlists: ["4593311"],
+ description: "The fuzzer targets the APIs of libaudioflinger",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
+ },
+}
+
+cc_fuzz {
+ name: "audioflinger_aidl_fuzzer",
+ srcs: ["audioflinger_aidl_fuzzer.cpp"],
+ defaults: [
+ "libaudioclient_aidl_fuzzer_defaults",
+ "service_fuzzer_defaults"
+ ],
+}
diff --git a/media/libaudioclient/aidl/fuzzer/audioflinger_aidl_fuzzer.cpp b/media/libaudioclient/aidl/fuzzer/audioflinger_aidl_fuzzer.cpp
new file mode 100644
index 0000000..f99cc3b
--- /dev/null
+++ b/media/libaudioclient/aidl/fuzzer/audioflinger_aidl_fuzzer.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 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 <AudioFlinger.h>
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_process.h>
+#include <android/media/IAudioPolicyService.h>
+#include <fakeservicemanager/FakeServiceManager.h>
+#include <fuzzbinder/libbinder_driver.h>
+#include <fuzzbinder/random_binder.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/IAudioFlinger.h>
+#include <service/AudioPolicyService.h>
+
+using namespace android;
+using namespace android::binder;
+using android::fuzzService;
+
+[[clang::no_destroy]] static std::once_flag gSmOnce;
+sp<FakeServiceManager> gFakeServiceManager;
+
+bool addService(const String16& serviceName, const sp<FakeServiceManager>& fakeServiceManager,
+ FuzzedDataProvider& fdp) {
+ sp<IBinder> binder = getRandomBinder(&fdp);
+ if (binder == nullptr) {
+ return false;
+ }
+ CHECK_EQ(NO_ERROR, fakeServiceManager->addService(serviceName, binder));
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+
+ std::call_once(gSmOnce, [&] {
+ /* Create a FakeServiceManager instance and add required services */
+ gFakeServiceManager = sp<FakeServiceManager>::make();
+ setDefaultServiceManager(gFakeServiceManager);
+ });
+ gFakeServiceManager->clear();
+
+ for (const char* service :
+ {"activity", "sensor_privacy", "permission", "scheduling_policy",
+ "android.hardware.audio.core.IConfig", "batterystats", "media.metrics"}) {
+ if (!addService(String16(service), gFakeServiceManager, fdp)) {
+ return 0;
+ }
+ }
+
+ const auto audioFlinger = sp<AudioFlinger>::make();
+ const auto afAdapter = sp<AudioFlingerServerAdapter>::make(audioFlinger);
+
+ CHECK_EQ(NO_ERROR,
+ gFakeServiceManager->addService(
+ String16(IAudioFlinger::DEFAULT_SERVICE_NAME), IInterface::asBinder(afAdapter),
+ false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT));
+
+ AudioSystem::get_audio_flinger_for_fuzzer();
+ const auto audioPolicyService = sp<AudioPolicyService>::make();
+
+ CHECK_EQ(NO_ERROR,
+ gFakeServiceManager->addService(String16("media.audio_policy"), audioPolicyService,
+ false /* allowIsolated */,
+ IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT));
+
+ sp<IBinder> audioFlingerServiceBinder =
+ gFakeServiceManager->getService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME));
+ sp<media::IAudioFlingerService> audioFlingerService =
+ interface_cast<media::IAudioFlingerService>(audioFlingerServiceBinder);
+
+ fuzzService(media::IAudioFlingerService::asBinder(audioFlingerService), std::move(fdp));
+
+ return 0;
+}
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 8f8c9dd..0215f3c 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -178,6 +178,7 @@
// helper function to obtain AudioFlinger service handle
static const sp<IAudioFlinger> get_audio_flinger();
+ static const sp<IAudioFlinger> get_audio_flinger_for_fuzzer();
static float linearToLog(int volume);
static int logToLinear(float volume);
@@ -876,6 +877,7 @@
static audio_io_handle_t getOutput(audio_stream_type_t stream);
static const sp<AudioFlingerClient> getAudioFlingerClient();
static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle);
+ static const sp<IAudioFlinger> getAudioFlingerImpl(bool canStartThreadPool);
// Invokes all registered error callbacks with the given error code.
static void reportError(status_t err);
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 3c96862..eb27e25 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -384,6 +384,9 @@
virtual status_t supportsBluetoothVariableLatency(bool* support) const = 0;
virtual status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) = 0;
+
+ virtual status_t getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *mixPort) const = 0;
};
/**
@@ -498,6 +501,8 @@
sp<media::ISoundDose>* soundDose) const override;
status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) override;
+ status_t getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *mixPort) const override;
private:
const sp<media::IAudioFlingerService> mDelegate;
@@ -599,6 +604,7 @@
INVALIDATE_TRACKS = media::BnAudioFlingerService::TRANSACTION_invalidateTracks,
GET_AUDIO_POLICY_CONFIG =
media::BnAudioFlingerService::TRANSACTION_getAudioPolicyConfig,
+ GET_AUDIO_MIX_PORT = media::BnAudioFlingerService::TRANSACTION_getAudioMixPort,
};
protected:
@@ -732,6 +738,9 @@
sp<media::ISoundDose>* _aidl_return) override;
Status invalidateTracks(const std::vector<int32_t>& portIds) override;
Status getAudioPolicyConfig(media::AudioPolicyConfig* _aidl_return) override;
+ Status getAudioMixPort(const media::AudioPortFw& devicePort,
+ const media::AudioPortFw& mixPort,
+ media::AudioPortFw* _aidl_return) override;
private:
const sp<AudioFlingerServerAdapter::Delegate> mDelegate;
};
diff --git a/media/libaudioclient/tests/audioeffect_tests.cpp b/media/libaudioclient/tests/audioeffect_tests.cpp
index e6149e4..26121cd 100644
--- a/media/libaudioclient/tests/audioeffect_tests.cpp
+++ b/media/libaudioclient/tests/audioeffect_tests.cpp
@@ -250,8 +250,10 @@
if (!isEffectDefaultOnRecord(&descriptors[i].type, &descriptors[i].uuid,
capture->getAudioRecordHandle())) {
selectedEffect = i;
+ EXPECT_EQ(OK, capture->stop());
break;
}
+ EXPECT_EQ(OK, capture->stop());
}
}
if (selectedEffect == -1) GTEST_SKIP() << " expected at least one preprocessing effect";
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
index 202a400..e1265cf 100644
--- a/media/libaudiofoundation/AudioContainers.cpp
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -119,4 +119,115 @@
return ss.str();
}
+std::string dumpMixerBehaviors(const MixerBehaviorSet& mixerBehaviors) {
+ std::stringstream ss;
+ for (auto it = mixerBehaviors.begin(); it != mixerBehaviors.end(); ++it) {
+ if (it != mixerBehaviors.begin()) {
+ ss << ", ";
+ }
+ ss << (*it);
+ }
+ return ss.str();
+}
+
+AudioProfileAttributesMultimap createAudioProfilesAttrMap(audio_profile profiles[],
+ uint32_t first,
+ uint32_t last) {
+ AudioProfileAttributesMultimap result;
+ for (uint32_t i = first; i < last; ++i) {
+ SampleRateSet sampleRates(profiles[i].sample_rates,
+ profiles[i].sample_rates + profiles[i].num_sample_rates);
+ ChannelMaskSet channelMasks(profiles[i].channel_masks,
+ profiles[i].channel_masks + profiles[i].num_channel_masks);
+ result.emplace(profiles[i].format, std::make_pair(sampleRates, channelMasks));
+ }
+ return result;
+}
+
+namespace {
+
+void populateAudioProfile(audio_format_t format,
+ const ChannelMaskSet& channelMasks,
+ const SampleRateSet& samplingRates,
+ audio_profile* profile) {
+ profile->format = format;
+ profile->num_channel_masks = 0;
+ for (auto it = channelMasks.begin();
+ it != channelMasks.end() && profile->num_channel_masks < AUDIO_PORT_MAX_CHANNEL_MASKS;
+ ++it) {
+ profile->channel_masks[profile->num_channel_masks++] = *it;
+ }
+ profile->num_sample_rates = 0;
+ for (auto it = samplingRates.begin();
+ it != samplingRates.end() && profile->num_sample_rates < AUDIO_PORT_MAX_SAMPLING_RATES;
+ ++it) {
+ profile->sample_rates[profile->num_sample_rates++] = *it;
+ }
+}
+
+} // namespace
+
+void populateAudioProfiles(const AudioProfileAttributesMultimap& profileAttrs,
+ audio_format_t format,
+ ChannelMaskSet allChannelMasks,
+ SampleRateSet allSampleRates,
+ audio_profile audioProfiles[],
+ uint32_t* numAudioProfiles,
+ uint32_t maxAudioProfiles) {
+ if (*numAudioProfiles >= maxAudioProfiles) {
+ return;
+ }
+
+ const auto lower= profileAttrs.lower_bound(format);
+ const auto upper = profileAttrs.upper_bound(format);
+ SampleRateSet sampleRatesPresent;
+ ChannelMaskSet channelMasksPresent;
+ for (auto it = lower; it != upper && *numAudioProfiles < maxAudioProfiles; ++it) {
+ SampleRateSet srs;
+ std::set_intersection(it->second.first.begin(), it->second.first.end(),
+ allSampleRates.begin(), allSampleRates.end(),
+ std::inserter(srs, srs.begin()));
+ if (srs.empty()) {
+ continue;
+ }
+ ChannelMaskSet cms;
+ std::set_intersection(it->second.second.begin(), it->second.second.end(),
+ allChannelMasks.begin(), allChannelMasks.end(),
+ std::inserter(cms, cms.begin()));
+ if (cms.empty()) {
+ continue;
+ }
+ sampleRatesPresent.insert(srs.begin(), srs.end());
+ channelMasksPresent.insert(cms.begin(), cms.end());
+ populateAudioProfile(it->first, cms, srs,
+ &audioProfiles[(*numAudioProfiles)++]);
+ }
+ if (*numAudioProfiles >= maxAudioProfiles) {
+ ALOGW("%s, too many audio profiles", __func__);
+ return;
+ }
+
+ SampleRateSet srs;
+ std::set_difference(allSampleRates.begin(), allSampleRates.end(),
+ sampleRatesPresent.begin(), sampleRatesPresent.end(),
+ std::inserter(srs, srs.begin()));
+ if (!srs.empty()) {
+ populateAudioProfile(format, allChannelMasks, srs,
+ &audioProfiles[(*numAudioProfiles)++]);
+ }
+ if (*numAudioProfiles >= maxAudioProfiles) {
+ ALOGW("%s, too many audio profiles", __func__);
+ return;
+ }
+ ChannelMaskSet cms;
+ std::set_difference(allChannelMasks.begin(), allChannelMasks.end(),
+ channelMasksPresent.begin(), channelMasksPresent.end(),
+ std::inserter(cms, cms.begin()));
+ if (!cms.empty()) {
+ populateAudioProfile(format, cms, allSampleRates,
+ &audioProfiles[(*numAudioProfiles)++]);
+ }
+
+}
+
} // namespace android
diff --git a/media/libaudiofoundation/AudioPort.cpp b/media/libaudiofoundation/AudioPort.cpp
index 6e05abc..ae0457f 100644
--- a/media/libaudiofoundation/AudioPort.cpp
+++ b/media/libaudiofoundation/AudioPort.cpp
@@ -57,14 +57,21 @@
void AudioPort::importAudioPort(const audio_port_v7 &port) {
for (size_t i = 0; i < port.num_audio_profiles; ++i) {
+ if (port.audio_profiles[i].format == AUDIO_FORMAT_DEFAULT) {
+ // The dynamic format from AudioPort should not be AUDIO_FORMAT_DEFAULT.
+ continue;
+ }
sp<AudioProfile> profile = new AudioProfile(port.audio_profiles[i].format,
ChannelMaskSet(port.audio_profiles[i].channel_masks,
port.audio_profiles[i].channel_masks +
- port.audio_profiles->num_channel_masks),
+ port.audio_profiles[i].num_channel_masks),
SampleRateSet(port.audio_profiles[i].sample_rates,
port.audio_profiles[i].sample_rates +
port.audio_profiles[i].num_sample_rates),
port.audio_profiles[i].encapsulation_type);
+ profile->setDynamicFormat(true);
+ profile->setDynamicChannels(true);
+ profile->setDynamicRate(true);
if (!mProfiles.contains(profile)) {
addAudioProfile(profile);
}
diff --git a/media/libaudiofoundation/AudioProfile.cpp b/media/libaudiofoundation/AudioProfile.cpp
index 999e263..4a5fb96 100644
--- a/media/libaudiofoundation/AudioProfile.cpp
+++ b/media/libaudiofoundation/AudioProfile.cpp
@@ -383,6 +383,16 @@
}
}
+ChannelMaskSet AudioProfileVector::getSupportedChannelMasks() const {
+ ChannelMaskSet channelMasks;
+ for (const auto& profile : *this) {
+ if (profile->isValid()) {
+ channelMasks.insert(profile->getChannels().begin(), profile->getChannels().end());
+ }
+ }
+ return channelMasks;
+}
+
ConversionResult<AudioProfileVector>
aidl2legacy_AudioProfileVector(const AudioProfileVector::Aidl& aidl, bool isInput) {
return convertContainers<AudioProfileVector>(aidl.first, aidl.second,
diff --git a/media/libaudiofoundation/TEST_MAPPING b/media/libaudiofoundation/TEST_MAPPING
index a4e271e..f7e5b12 100644
--- a/media/libaudiofoundation/TEST_MAPPING
+++ b/media/libaudiofoundation/TEST_MAPPING
@@ -20,5 +20,10 @@
}
]
}
+ ],
+ "postsubmit": [
+ {
+ "name": "audiofoundation_containers_test"
+ }
]
}
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 88dcee9..46fd620 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -19,6 +19,7 @@
#include <algorithm>
#include <functional>
#include <iterator>
+#include <map>
#include <set>
#include <vector>
@@ -34,6 +35,8 @@
using MixerBehaviorSet = std::set<audio_mixer_behavior_t>;
using FormatVector = std::vector<audio_format_t>;
+using AudioProfileAttributesMultimap =
+ std::multimap<audio_format_t, std::pair<SampleRateSet, ChannelMaskSet>>;
const DeviceTypeSet& getAudioDeviceOutAllSet();
const DeviceTypeSet& getAudioDeviceOutAllA2dpSet();
@@ -126,6 +129,8 @@
std::string dumpDeviceTypes(const DeviceTypeSet& deviceTypes);
+std::string dumpMixerBehaviors(const MixerBehaviorSet& mixerBehaviors);
+
/**
* Return human readable string for device types.
*/
@@ -133,5 +138,49 @@
return deviceTypesToString(deviceTypes);
}
+/**
+ * Create audio profile attributes map by given audio profile array from the range of [first, last).
+ *
+ * @param profiles the array of audio profiles.
+ * @param first the first index of the profile.
+ * @param last the last index of the profile.
+ * @return a multipmap of audio format to pair of corresponding sample rates and channel masks set.
+ */
+AudioProfileAttributesMultimap createAudioProfilesAttrMap(audio_profile profiles[],
+ uint32_t first,
+ uint32_t last);
+
+/**
+ * Populate audio profiles according to given profile attributes, format, channel masks and
+ * sample rates.
+ *
+ * The function will first go over all pairs of channel masks and sample rates that are present in
+ * the profile attributes of the given map. Note that the channel masks and the sample rates that
+ * are not present in the collections of all valid channel masks and all valid sample rates will be
+ * excluded. After that, if there are channel masks and sample rates that present in the all values
+ * collection but not in profile attributes, they will also be place in a new audio profile in the
+ * profile array.
+ *
+ * Note that if the resulting index of the audio profile exceeds the maximum, no new audio profiles
+ * will be placed in the array.
+ *
+ * @param profileAttrs a multimap that contains format and its corresponding channel masks and
+ * sample rates.
+ * @param format the targeted audio format.
+ * @param allChannelMasks all valid channel masks for the format.
+ * @param allSampleRates all valid sample rates for the format.
+ * @param audioProfiles the audio profile array.
+ * @param numAudioProfiles the start index to put audio profile in the array. The value will be
+ * updated if there is new audio profile placed.
+ * @param maxAudioProfiles the maximum number of audio profile.
+ */
+void populateAudioProfiles(const AudioProfileAttributesMultimap& profileAttrs,
+ audio_format_t format,
+ ChannelMaskSet allChannelMasks,
+ SampleRateSet allSampleRates,
+ audio_profile audioProfiles[],
+ uint32_t* numAudioProfiles,
+ uint32_t maxAudioProfiles = AUDIO_PORT_MAX_AUDIO_PROFILES);
+
} // namespace android
diff --git a/media/libaudiofoundation/include/media/AudioProfile.h b/media/libaudiofoundation/include/media/AudioProfile.h
index a668afe..bcde1fe 100644
--- a/media/libaudiofoundation/include/media/AudioProfile.h
+++ b/media/libaudiofoundation/include/media/AudioProfile.h
@@ -149,6 +149,8 @@
bool equals(const AudioProfileVector& other) const;
void addAllValidProfiles(const AudioProfileVector& audioProfiles);
+ ChannelMaskSet getSupportedChannelMasks() const;
+
using Aidl = std::pair<
std::vector<media::audio::common::AudioProfile>,
std::vector<media::AudioProfileSys>>;
diff --git a/media/libaudiofoundation/tests/Android.bp b/media/libaudiofoundation/tests/Android.bp
index 2f4aee0..82c7db7 100644
--- a/media/libaudiofoundation/tests/Android.bp
+++ b/media/libaudiofoundation/tests/Android.bp
@@ -43,3 +43,30 @@
test_suites: ["device-tests"],
}
+
+cc_test {
+ name: "audiofoundation_containers_test",
+
+ shared_libs: [
+ "liblog",
+ ],
+
+ static_libs: [
+ "libaudiofoundation",
+ ],
+
+ header_libs: [
+ "libaudio_system_headers",
+ ],
+
+ srcs: [
+ "audiofoundation_containers_test.cpp",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ test_suites: ["device-tests"],
+}
diff --git a/media/libaudiofoundation/tests/audiofoundation_containers_test.cpp b/media/libaudiofoundation/tests/audiofoundation_containers_test.cpp
new file mode 100644
index 0000000..967e2ee
--- /dev/null
+++ b/media/libaudiofoundation/tests/audiofoundation_containers_test.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include <media/AudioContainers.h>
+
+namespace android {
+
+const static AudioProfileAttributesMultimap AUDIO_PROFILE_ATTRIBUTES = {
+ {AUDIO_FORMAT_PCM_16_BIT, {{44100, 48000},
+ {AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_7POINT1}}},
+ {AUDIO_FORMAT_PCM_16_BIT, {{96000},
+ {AUDIO_CHANNEL_OUT_STEREO}}},
+ {AUDIO_FORMAT_PCM_8_24_BIT, {{48000},
+ {AUDIO_CHANNEL_OUT_STEREO}}}
+};
+
+TEST(PopulateAudioProfilesTest, AllAttributesMatches) {
+ const AudioProfileAttributesMultimap expected = {
+ {AUDIO_FORMAT_PCM_16_BIT, {{44100, 48000},
+ {AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_7POINT1}}},
+ {AUDIO_FORMAT_PCM_16_BIT, {{96000},
+ {AUDIO_CHANNEL_OUT_STEREO}}}
+ };
+ const audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
+ const SampleRateSet allSampleRates = {44100, 48000, 96000};
+ const ChannelMaskSet allChannelMasks = {AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_7POINT1};
+
+ audio_profile profiles[AUDIO_PORT_MAX_AUDIO_PROFILES];
+ uint32_t numProfiles = 0;
+ populateAudioProfiles(AUDIO_PROFILE_ATTRIBUTES, format, allChannelMasks, allSampleRates,
+ profiles, &numProfiles);
+ ASSERT_EQ(expected, createAudioProfilesAttrMap(profiles, 0, numProfiles));
+}
+
+TEST(PopulateAudioProfilesTest, AttributesNotInAllValues) {
+ const AudioProfileAttributesMultimap expected = {
+ {AUDIO_FORMAT_PCM_16_BIT, {{48000},
+ {AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_7POINT1}}},
+ {AUDIO_FORMAT_PCM_16_BIT, {{96000},
+ {AUDIO_CHANNEL_OUT_STEREO}}}
+ };
+ const audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
+ const SampleRateSet allSampleRates = {48000, 96000};
+ const ChannelMaskSet allChannelMasks = {AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_7POINT1};
+
+ audio_profile profiles[AUDIO_PORT_MAX_AUDIO_PROFILES];
+ uint32_t numProfiles = 0;
+ populateAudioProfiles(AUDIO_PROFILE_ATTRIBUTES, format, allChannelMasks, allSampleRates,
+ profiles, &numProfiles);
+ ASSERT_EQ(expected, createAudioProfilesAttrMap(profiles, 0, numProfiles));
+}
+
+TEST(PopulateAudioProfilesTest, AllValuesNotInAttributes) {
+ const AudioProfileAttributesMultimap expected = {
+ {AUDIO_FORMAT_PCM_16_BIT, {{48000},
+ {AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_7POINT1}}},
+ {AUDIO_FORMAT_PCM_16_BIT, {{96000},
+ {AUDIO_CHANNEL_OUT_STEREO}}},
+ {AUDIO_FORMAT_PCM_16_BIT, {{88200},
+ {AUDIO_CHANNEL_OUT_MONO, AUDIO_CHANNEL_OUT_STEREO,
+ AUDIO_CHANNEL_OUT_7POINT1}}},
+ {AUDIO_FORMAT_PCM_16_BIT, {{48000, 88200, 96000},
+ {AUDIO_CHANNEL_OUT_MONO}}}
+ };
+ const audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
+ const SampleRateSet allSampleRates = {48000, 88200, 96000};
+ const ChannelMaskSet allChannelMasks =
+ {AUDIO_CHANNEL_OUT_MONO, AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_7POINT1};
+
+ audio_profile profiles[AUDIO_PORT_MAX_AUDIO_PROFILES];
+ uint32_t numProfiles = 0;
+ populateAudioProfiles(AUDIO_PROFILE_ATTRIBUTES, format, allChannelMasks, allSampleRates,
+ profiles, &numProfiles);
+ ASSERT_EQ(expected, createAudioProfilesAttrMap(profiles, 0, numProfiles));
+}
+
+TEST(PopulateAudioProfilesTest, NoOverflow) {
+ const audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
+ const SampleRateSet allSampleRates = {48000, 88200, 96000};
+ const ChannelMaskSet allChannelMasks =
+ {AUDIO_CHANNEL_OUT_MONO, AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_7POINT1};
+
+ audio_profile profiles[AUDIO_PORT_MAX_AUDIO_PROFILES];
+ const uint32_t expectedNumProfiles = 4;
+ for (uint32_t i = 0; i <= AUDIO_PORT_MAX_AUDIO_PROFILES; ++i) {
+ uint32_t numProfiles = 0;
+ populateAudioProfiles(AUDIO_PROFILE_ATTRIBUTES, format, allChannelMasks, allSampleRates,
+ profiles, &numProfiles, i);
+ ASSERT_EQ(std::min(i, expectedNumProfiles), numProfiles);
+ }
+}
+
+} // namespace android
diff --git a/media/libaudiohal/OWNERS b/media/libaudiohal/OWNERS
index 71b17e6..993e0b3 100644
--- a/media/libaudiohal/OWNERS
+++ b/media/libaudiohal/OWNERS
@@ -1 +1,4 @@
+# Bug component: 48436
mnaganov@google.com
+yaoshunkai@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index b18e64b..e2233c7 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -836,6 +836,33 @@
return OK;
}
+status_t DeviceHalAidl::getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *mixPort) {
+ ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
+ if (devicePort->type != AUDIO_PORT_TYPE_DEVICE) {
+ return BAD_VALUE;
+ }
+ if (mixPort->type != AUDIO_PORT_TYPE_MIX) {
+ return BAD_VALUE;
+ }
+ const int32_t aidlHandle = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_io_handle_t_int32_t(mixPort->ext.mix.handle));
+ auto it = findPortConfig(std::nullopt /*config*/, std::nullopt/*flags*/, aidlHandle);
+ if (it == mPortConfigs.end()) {
+ ALOGE("%s, cannot find mix port config for handle=%u", __func__, aidlHandle);
+ return BAD_VALUE;
+ }
+ AudioPort port;
+ if (status_t status = getAudioPort(it->second.portId, &port); status != NO_ERROR) {
+ return status;
+ }
+ const bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
+ mixPort->role, mixPort->type)) == ::aidl::android::AudioPortDirection::INPUT;
+ *mixPort = VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioPort_audio_port_v7(
+ port, isInput));
+ return NO_ERROR;
+}
+
status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config) {
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
@@ -1010,7 +1037,7 @@
return mModule->dump(fd, Args(args).args(), args.size());
}
-int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports) {
+status_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports) {
TIME_CHECK();
if (!mModule) return NO_INIT;
if (supports == nullptr) {
@@ -1194,10 +1221,15 @@
TIME_CHECK();
if (String8 key = String8(AudioParameter::keyReconfigA2dpSupported); keys.containsKey(key)) {
keys.remove(key);
- bool supports;
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
- mBluetoothA2dp->supportsOffloadReconfiguration(&supports)));
- result->addInt(key, supports ? 1 : 0);
+ if (mBluetoothA2dp != nullptr) {
+ bool supports;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mBluetoothA2dp->supportsOffloadReconfiguration(&supports)));
+ result->addInt(key, supports ? 1 : 0);
+ } else {
+ ALOGI("%s: no IBluetoothA2dp on %s", __func__, mInstance.c_str());
+ result->addInt(key, 0);
+ }
}
return OK;
}
@@ -1702,7 +1734,9 @@
}
DeviceHalAidl::PortConfigs::iterator DeviceHalAidl::findPortConfig(
- const AudioConfig& config, const std::optional<AudioIoFlags>& flags, int32_t ioHandle) {
+ const std::optional<AudioConfig>& config,
+ const std::optional<AudioIoFlags>& flags,
+ int32_t ioHandle) {
using Tag = AudioPortExt::Tag;
return std::find_if(mPortConfigs.begin(), mPortConfigs.end(),
[&](const auto& pair) {
@@ -1713,7 +1747,8 @@
"%s: stored mix port config is not fully specified: %s",
__func__, p.toString().c_str());
return p.ext.getTag() == Tag::mix &&
- isConfigEqualToPortConfig(config, p) &&
+ (!config.has_value() ||
+ isConfigEqualToPortConfig(config.value(), p)) &&
(!flags.has_value() || p.flags.value() == flags.value()) &&
p.ext.template get<Tag::mix>().handle == ioHandle; });
}
@@ -1840,6 +1875,25 @@
return OK;
}
+status_t DeviceHalAidl::getAudioPort(int32_t portId, AudioPort* port) {
+ ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
+ TIME_CHECK();
+ if (!mModule) {
+ return NO_INIT;
+ }
+ const status_t status = statusTFromBinderStatus(mModule->getAudioPort(portId, port));
+ if (status == OK) {
+ auto portIt = mPorts.find(portId);
+ if (portIt != mPorts.end()) {
+ portIt->second = *port;
+ } else {
+ ALOGW("%s, port(%d) returned successfully from the HAL but not it is not cached",
+ __func__, portId);
+ }
+ }
+ return status;
+}
+
void DeviceHalAidl::clearCallbacks(void* cookie) {
std::lock_guard l(mLock);
mCallbacks.erase(cookie);
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 20cf88c..e1fe4d1 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -165,7 +165,7 @@
error::Result<audio_hw_sync_t> getHwAvSync() override;
- int32_t supportsBluetoothVariableLatency(bool* supports __unused) override;
+ status_t supportsBluetoothVariableLatency(bool* supports __unused) override;
status_t getSoundDoseInterface(const std::string& module,
::ndk::SpAIBinder* soundDoseBinder) override;
@@ -176,6 +176,9 @@
status_t setSimulateDeviceConnections(bool enabled) override;
+ status_t getAudioMixPort(const struct audio_port_v7* devicePort,
+ struct audio_port_v7* mixPort) override;
+
status_t dump(int __unused, const Vector<String16>& __unused) override;
private:
@@ -260,7 +263,7 @@
PortConfigs::iterator findPortConfig(
const ::aidl::android::media::audio::common::AudioDevice& device);
PortConfigs::iterator findPortConfig(
- const ::aidl::android::media::audio::common::AudioConfig& config,
+ const std::optional<::aidl::android::media::audio::common::AudioConfig>& config,
const std::optional<::aidl::android::media::audio::common::AudioIoFlags>& flags,
int32_t ioHandle);
bool isPortHeldByAStream(int32_t portId);
@@ -280,6 +283,7 @@
void resetUnusedPatchesAndPortConfigs();
void resetUnusedPortConfigs();
status_t updateRoutes();
+ status_t getAudioPort(int32_t portId, ::aidl::android::media::audio::common::AudioPort* port);
// CallbackBroker implementation
void clearCallbacks(void* cookie) override;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index f96d419..e8e1f46 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -304,7 +304,12 @@
}
HidlUtils::audioConfigToHal(suggestedConfig, config);
});
- return processReturn("openOutputStream", ret, retval);
+ const status_t status = processReturn("openOutputStream", ret, retval);
+ cleanupStreams();
+ if (status == NO_ERROR) {
+ mStreams.insert({handle, *outStream});
+ }
+ return status;
}
status_t DeviceHalHidl::openInputStream(
@@ -377,7 +382,12 @@
}
HidlUtils::audioConfigToHal(suggestedConfig, config);
});
- return processReturn("openInputStream", ret, retval);
+ const status_t status = processReturn("openInputStream", ret, retval);
+ cleanupStreams();
+ if (status == NO_ERROR) {
+ mStreams.insert({handle, *inStream});
+ }
+ return status;
}
status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
@@ -684,4 +694,148 @@
}
#endif
+status_t DeviceHalHidl::supportsBluetoothVariableLatency(bool* supports) {
+ if (supports == nullptr) {
+ return BAD_VALUE;
+ }
+ *supports = false;
+
+ String8 reply;
+ status_t status = getParameters(
+ String8(AUDIO_PARAMETER_BT_VARIABLE_LATENCY_SUPPORTED), &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ AudioParameter replyParams(reply);
+ String8 trueOrFalse;
+ status = replyParams.get(
+ String8(AUDIO_PARAMETER_BT_VARIABLE_LATENCY_SUPPORTED), trueOrFalse);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ *supports = trueOrFalse == AudioParameter::valueTrue;
+ return NO_ERROR;
+}
+
+namespace {
+
+status_t getParametersFromStream(
+ sp<StreamHalInterface> stream,
+ const char* parameters,
+ const char* extraParameters,
+ String8* reply) {
+ String8 request(parameters);
+ if (extraParameters != nullptr) {
+ request.append(";");
+ request.append(extraParameters);
+ }
+ status_t status = stream->getParameters(request, reply);
+ if (status != NO_ERROR) {
+ ALOGW("%s, failed to query %s, status=%d", __func__, parameters, status);
+ return status;
+ }
+ AudioParameter repliedParameters(*reply);
+ status = repliedParameters.get(String8(parameters), *reply);
+ if (status != NO_ERROR) {
+ ALOGW("%s: failed to retrieve %s, bailing out", __func__, parameters);
+ }
+ return status;
+}
+
+} // namespace
+
+status_t DeviceHalHidl::getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *mixPort) {
+ // For HIDL HAL, querying mix port information is not supported. If the HAL supports
+ // `getAudioPort` API to query the device port attributes, use the structured audio profiles
+ // that have the same attributes reported by the `getParameters` API. Otherwise, only use
+ // the attributes reported by `getParameters` API.
+ struct audio_port_v7 temp = *devicePort;
+ AudioProfileAttributesMultimap attrsFromDevice;
+ status_t status = getAudioPort(&temp);
+ if (status == NO_ERROR) {
+ attrsFromDevice = createAudioProfilesAttrMap(temp.audio_profiles, 0 /*first*/,
+ temp.num_audio_profiles);
+ }
+ auto streamIt = mStreams.find(mixPort->ext.mix.handle);
+ if (streamIt == mStreams.end()) {
+ return BAD_VALUE;
+ }
+ auto stream = streamIt->second.promote();
+ if (stream == nullptr) {
+ return BAD_VALUE;
+ }
+
+ String8 formatsStr;
+ status = getParametersFromStream(
+ stream, AudioParameter::keyStreamSupportedFormats, nullptr /*extraParameters*/,
+ &formatsStr);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ FormatVector formats = formatsFromString(formatsStr.c_str());
+
+ mixPort->num_audio_profiles = 0;
+ for (audio_format_t format : formats) {
+ if (mixPort->num_audio_profiles >= AUDIO_PORT_MAX_AUDIO_PROFILES) {
+ ALOGW("%s, too many audio profiles", __func__);
+ break;
+ }
+ AudioParameter formatParameter;
+ formatParameter.addInt(String8(AudioParameter::keyFormat), format);
+
+ String8 samplingRatesStr;
+ status = getParametersFromStream(
+ stream, AudioParameter::keyStreamSupportedSamplingRates,
+ formatParameter.toString(), &samplingRatesStr);
+ if (status != NO_ERROR) {
+ // Failed to query supported sample rate for current format, may succeed with
+ // other formats.
+ ALOGW("Skip adding format=%#x, status=%d", format, status);
+ continue;
+ }
+ SampleRateSet sampleRatesFromStream = samplingRatesFromString(samplingRatesStr.c_str());
+ if (sampleRatesFromStream.empty()) {
+ ALOGW("Skip adding format=%#x as the returned sampling rates are empty", format);
+ continue;
+ }
+ String8 channelMasksStr;
+ status = getParametersFromStream(
+ stream, AudioParameter::keyStreamSupportedChannels,
+ formatParameter.toString(), &channelMasksStr);
+ if (status != NO_ERROR) {
+ // Failed to query supported channel masks for current format, may succeed with
+ // other formats.
+ ALOGW("Skip adding format=%#x, status=%d", format, status);
+ continue;
+ }
+ ChannelMaskSet channelMasksFromStream = channelMasksFromString(channelMasksStr.c_str());
+ if (channelMasksFromStream.empty()) {
+ ALOGW("Skip adding format=%#x as the returned channel masks are empty", format);
+ continue;
+ }
+
+ // For an audio format, all audio profiles from the device port with the same format will
+ // be added to mix port after filtering sample rates, channel masks according to the reply
+ // of getParameters API. If there is any sample rate or channel mask reported by
+ // getParameters API but not reported by the device, additional audio profiles will be
+ // added.
+ populateAudioProfiles(attrsFromDevice, format, channelMasksFromStream,
+ sampleRatesFromStream, mixPort->audio_profiles,
+ &mixPort->num_audio_profiles);
+ }
+
+ return NO_ERROR;
+}
+
+void DeviceHalHidl::cleanupStreams() {
+ for (auto it = mStreams.begin(); it != mStreams.end();) {
+ if (it->second.promote() == nullptr) {
+ it = mStreams.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index 989c1f5..7a712df 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -21,6 +21,7 @@
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
#include <media/audiohal/DeviceHalInterface.h>
#include <media/audiohal/EffectHalInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
#include "CoreConversionHelperHidl.h"
@@ -127,10 +128,7 @@
return INVALID_OPERATION;
}
- int32_t supportsBluetoothVariableLatency(bool* supports __unused) override {
- // TODO: Implement the HAL query when moving to AIDL HAL.
- return INVALID_OPERATION;
- }
+ status_t supportsBluetoothVariableLatency(bool* supports) override;
status_t setConnectedState(const struct audio_port_v7 *port, bool connected) override;
@@ -148,6 +146,9 @@
status_t prepareToDisconnectExternalDevice(const struct audio_port_v7* port) override;
+ status_t getAudioMixPort(const struct audio_port_v7* devicePort,
+ struct audio_port_v7* mixPort) override;
+
private:
friend class DevicesFactoryHalHidl;
sp<::android::hardware::audio::CPP_VERSION::IDevice> mDevice;
@@ -157,12 +158,15 @@
class SoundDoseWrapper;
const std::unique_ptr<SoundDoseWrapper> mSoundDoseWrapper;
std::set<audio_port_handle_t> mDeviceDisconnectionNotified;
+ std::map<audio_io_handle_t, wp<StreamHalInterface>> mStreams;
// Can not be constructed directly by clients.
explicit DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device);
explicit DeviceHalHidl(
const sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice>& device);
+ void cleanupStreams();
+
// The destructor automatically closes the device.
virtual ~DeviceHalHidl();
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 87aaeac..7d807b2 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -243,7 +243,7 @@
[&](const auto& desc) { return desc.common.id.uuid == uuid; });
if (matchIt == list.end()) {
ALOGE("%s UUID not found in HAL and proxy list %s", __func__, toString(uuid).c_str());
- return BAD_VALUE;
+ return NAME_NOT_FOUND;
}
ALOGI("%s UUID impl found %s", __func__, toString(uuid).c_str());
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp
index ff0c32b..49e6827 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp
@@ -51,6 +51,7 @@
status_t AidlConversionSpatializer::getParameter(EffectParamWriter& param) {
DefaultExtension defaultExt;
// read parameters into DefaultExtension vector<uint8_t>
+ defaultExt.bytes.resize(param.getParameterSize());
if (OK != param.readFromParameter(defaultExt.bytes.data(), param.getParameterSize())) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
param.setStatus(BAD_VALUE);
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index a965709..bb5f851 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -142,7 +142,7 @@
virtual int32_t getAAudioMixerBurstCount() = 0;
virtual int32_t getAAudioHardwareBurstMinUsec() = 0;
- virtual int32_t supportsBluetoothVariableLatency(bool* supports) = 0;
+ virtual status_t supportsBluetoothVariableLatency(bool* supports) = 0;
// Update the connection status of an external device.
virtual status_t setConnectedState(const struct audio_port_v7* port, bool connected) = 0;
@@ -160,6 +160,9 @@
virtual status_t prepareToDisconnectExternalDevice(const struct audio_port_v7* port) = 0;
+ virtual status_t getAudioMixPort(const struct audio_port_v7* devicePort,
+ struct audio_port_v7* mixPort) = 0;
+
protected:
// Subclasses can not be constructed directly by clients.
DeviceHalInterface() {}
diff --git a/media/libaudioprocessing/OWNERS b/media/libaudioprocessing/OWNERS
index 96d0ea0..ae071cf 100644
--- a/media/libaudioprocessing/OWNERS
+++ b/media/libaudioprocessing/OWNERS
@@ -1,3 +1,4 @@
-gkasten@google.com
+# Bug component: 48436
hunga@google.com
-rago@google.com
+yaoshunkai@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/libcpustats/OWNERS b/media/libcpustats/OWNERS
index f9cb567..fe3205a 100644
--- a/media/libcpustats/OWNERS
+++ b/media/libcpustats/OWNERS
@@ -1 +1,4 @@
-gkasten@google.com
+# Bug component: 48436
+atneya@google.com
+hunga@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/libeffects/OWNERS b/media/libeffects/OWNERS
index b7832ea..fe0ca99 100644
--- a/media/libeffects/OWNERS
+++ b/media/libeffects/OWNERS
@@ -1,3 +1,5 @@
+# Bug component: 48436
hunga@google.com
mnaganov@google.com
-rago@google.com
+yaoshunkai@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/libheadtracking/OWNERS b/media/libheadtracking/OWNERS
index e5d0370..ae071cf 100644
--- a/media/libheadtracking/OWNERS
+++ b/media/libheadtracking/OWNERS
@@ -1,2 +1,4 @@
-ytai@google.com
-elaurent@google.com
+# Bug component: 48436
+hunga@google.com
+yaoshunkai@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/libnbaio/OWNERS b/media/libnbaio/OWNERS
index eece71f..4bd5e06 100644
--- a/media/libnbaio/OWNERS
+++ b/media/libnbaio/OWNERS
@@ -1,2 +1,4 @@
-gkasten@google.com
+# Bug component: 48436
hunga@google.com
+mnaganov@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/libshmem/OWNERS b/media/libshmem/OWNERS
index 29fa2f5..63c7dab 100644
--- a/media/libshmem/OWNERS
+++ b/media/libshmem/OWNERS
@@ -1,3 +1,5 @@
-ytai@google.com
+# Bug component: 48436
+atneya@google.com
mnaganov@google.com
-elaurent@google.com
+yaoshunkai@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index b5bd975..57937f9 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -16,7 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "FrameDecoder"
-
+#define ATRACE_TAG ATRACE_TAG_VIDEO
#include "include/FrameDecoder.h"
#include "include/FrameCaptureLayer.h"
#include "include/HevcUtils.h"
@@ -41,6 +41,7 @@
#include <media/stagefright/Utils.h>
#include <private/media/VideoFrame.h>
#include <utils/Log.h>
+#include <utils/Trace.h>
namespace android {
@@ -340,6 +341,7 @@
}
sp<IMemory> FrameDecoder::extractFrame(FrameRect *rect) {
+ ScopedTrace trace(ATRACE_TAG, "FrameDecoder::ExtractFrame");
status_t err = onExtractRect(rect);
if (err == OK) {
err = extractInternal();
@@ -713,6 +715,7 @@
}
converter.setSrcColorSpace(standard, range, transfer);
if (converter.isValid()) {
+ ScopedTrace trace(ATRACE_TAG, "FrameDecoder::ColorConverter");
converter.convert(
(const uint8_t *)videoFrameBuffer->data(),
width, height, stride,
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 870ebdf..c110f05 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2991,12 +2991,6 @@
ALOGE("retrying start: failed to reset codec");
break;
}
- sp<AMessage> response;
- err = PostAndAwaitResponse(mConfigureMsg, &response);
- if (err != OK) {
- ALOGE("retrying start: failed to configure codec");
- break;
- }
if (callback != nullptr) {
err = setCallback(callback);
if (err != OK) {
@@ -3005,6 +2999,12 @@
}
ALOGD("succeed to set callback for reclaim");
}
+ sp<AMessage> response;
+ err = PostAndAwaitResponse(mConfigureMsg, &response);
+ if (err != OK) {
+ ALOGE("retrying start: failed to configure codec");
+ break;
+ }
}
// Keep callback message after the first iteration if necessary.
diff --git a/media/libstagefright/SurfaceUtils.cpp b/media/libstagefright/SurfaceUtils.cpp
index 291b892..827052d 100644
--- a/media/libstagefright/SurfaceUtils.cpp
+++ b/media/libstagefright/SurfaceUtils.cpp
@@ -225,6 +225,13 @@
return err;
};
+ // We need to set sidebandStream to nullptr before pushing blank buffers
+ err = native_window_set_sideband_stream(nativeWindow, nullptr);
+ if (err != NO_ERROR) {
+ ALOGE("error setting sidebandStream to nullptr: %s (%d)", strerror(-err), -err);
+ return err;
+ }
+
// We need to reconnect to the ANativeWindow as a CPU client to ensure that
// no frames get dropped by SurfaceFlinger assuming that these are video
// frames.
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index 665ceee..ee41867 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -218,6 +218,24 @@
<Feature name="adaptive-playback" />
<Attribute name="software-codec" />
</MediaCodec>
+ <MediaCodec name="c2.android.av1-dav1d.decoder" type="video/av01" variant="slow-cpu,!slow-cpu" rank="1024">
+ <Limit name="alignment" value="1x1" />
+ <Limit name="block-size" value="16x16" />
+ <Variant name="!slow-cpu">
+ <Limit name="size" min="2x2" max="2048x2048" />
+ <Limit name="block-count" range="1-8192" /> <!-- max 2048x1024 -->
+ <Limit name="blocks-per-second" range="1-245760" />
+ <Limit name="bitrate" range="1-40000000" />
+ </Variant>
+ <Variant name="slow-cpu">
+ <Limit name="size" min="2x2" max="1280x1280" />
+ <Limit name="block-count" range="1-3600" /> <!-- max 1280x720 -->
+ <Limit name="blocks-per-second" range="1-108000" />
+ <Limit name="bitrate" range="1-5000000" />
+ </Variant>
+ <Feature name="adaptive-playback" />
+ <Attribute name="software-codec" />
+ </MediaCodec>
<MediaCodec name="c2.android.mpeg2.decoder" type="video/mpeg2" domain="tv">
<Alias name="OMX.google.mpeg2.decoder" />
<!-- profiles and levels: ProfileMain : LevelHL -->
diff --git a/media/libstagefright/httplive/fuzzer/Android.bp b/media/libstagefright/httplive/fuzzer/Android.bp
index dd49714..cb2f4ee 100644
--- a/media/libstagefright/httplive/fuzzer/Android.bp
+++ b/media/libstagefright/httplive/fuzzer/Android.bp
@@ -48,6 +48,7 @@
"libstagefright_httplive_headers",
],
shared_libs: [
+ "libbase",
"libcrypto",
"libstagefright_foundation",
"libhidlbase",
diff --git a/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp b/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp
index 7823922..ee76a67 100644
--- a/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp
+++ b/media/libstagefright/tests/VideoRenderQualityTracker_test.cpp
@@ -261,7 +261,7 @@
Configuration::GetServerConfigurableFlagFn getServerConfigurableFlagFn{
[](const std::string &, const std::string &flag, const std::string &) -> std::string {
if (flag == "render_metrics_enabled") {
- return "false";
+ return "true";
} else if (flag == "render_metrics_are_skipped_frames_dropped") {
return "false";
} else if (flag == "render_metrics_max_expected_content_frame_duration_us") {
@@ -304,7 +304,7 @@
// default - if we are accidentally configuring to the default then we're not necessarily
// testing the parsing.
Configuration d;
- EXPECT_EQ(c.enabled, false);
+ EXPECT_EQ(c.enabled, true);
EXPECT_NE(c.enabled, d.enabled);
EXPECT_EQ(c.areSkippedFramesDropped, false);
EXPECT_NE(c.areSkippedFramesDropped, d.areSkippedFramesDropped);
@@ -357,6 +357,7 @@
TEST_F(VideoRenderQualityTrackerTest, countsReleasedFrames) {
Configuration c;
+ c.enabled = true;
Helper h(16.66, c);
h.drop(10);
h.render({16.66, 16.66, 16.66});
@@ -368,6 +369,7 @@
TEST_F(VideoRenderQualityTrackerTest, countsSkippedFrames) {
Configuration c;
+ c.enabled = true;
Helper h(16.66, c);
h.drop(10); // dropped frames are not counted
h.skip(10); // frames skipped before rendering a frame are not counted
@@ -382,6 +384,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenSkippedFramesAreDropped_countsDroppedFrames) {
Configuration c;
+ c.enabled = true;
c.areSkippedFramesDropped = true;
Helper h(16.66, c);
h.skip(10); // skipped frames at the beginning of playback are not counted
@@ -398,6 +401,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenNotSkippedFramesAreDropped_countsDroppedFrames) {
Configuration c;
+ c.enabled = true;
c.areSkippedFramesDropped = false;
Helper h(16.66, c);
h.skip(10); // skipped frames at the beginning of playback are not counted
@@ -414,6 +418,7 @@
TEST_F(VideoRenderQualityTrackerTest, countsRenderedFrames) {
Configuration c;
+ c.enabled = true;
Helper h(16.66, c);
h.drop(10); // dropped frames are not counted
h.render({16.66, 16.66, 16.66});
@@ -425,6 +430,7 @@
TEST_F(VideoRenderQualityTrackerTest, detectsFrameRate) {
Configuration c;
+ c.enabled = true;
c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
Helper h(16.66, c);
h.render({16.6, 16.7, 16.6, 16.7});
@@ -434,6 +440,7 @@
TEST_F(VideoRenderQualityTrackerTest, handlesSeeking) {
Configuration c;
+ c.enabled = true;
c.maxExpectedContentFrameDurationUs = 30;
VideoRenderQualityTracker v(c);
v.onFrameReleased(0, 0);
@@ -472,6 +479,7 @@
TEST_F(VideoRenderQualityTrackerTest, withSkipping_handlesSeeking) {
Configuration c;
+ c.enabled = true;
c.maxExpectedContentFrameDurationUs = 30;
VideoRenderQualityTracker v(c);
v.onFrameReleased(0, 0);
@@ -508,6 +516,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenLowTolerance_doesntDetectFrameRate) {
Configuration c;
+ c.enabled = true;
c.frameRateDetectionToleranceUs = 0;
Helper h(16.66, c);
h.render({16.6, 16.7, 16.6, 16.7});
@@ -517,6 +526,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenFrameRateDestabilizes_detectsFrameRate) {
Configuration c;
+ c.enabled = true;
c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
Helper h(16.66, c);
h.render({16.6, 16.7, 16.6, 16.7});
@@ -527,6 +537,7 @@
TEST_F(VideoRenderQualityTrackerTest, detects32Pulldown) {
Configuration c;
+ c.enabled = true;
c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
Helper h(41.66, c);
h.render({49.9, 33.2, 50.0, 33.4, 50.1, 33.2});
@@ -536,6 +547,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenBad32Pulldown_doesntDetect32Pulldown) {
Configuration c;
+ c.enabled = true;
c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
Helper h(41.66, c);
h.render({50.0, 33.33, 33.33, 50.00, 33.33, 50.00});
@@ -545,6 +557,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenFrameRateChanges_detectsMostRecentFrameRate) {
Configuration c;
+ c.enabled = true;
c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
Helper h(16.66, c);
h.render({16.6, 16.7, 16.6, 16.7});
@@ -558,6 +571,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenFrameRateIsUnstable_doesntDetectFrameRate) {
Configuration c;
+ c.enabled = true;
c.frameRateDetectionToleranceUs = 2 * 1000; // 2 ms
Helper h(16.66, c);
h.render({16.66, 30.0, 16.66, 30.0, 16.66});
@@ -567,6 +581,7 @@
TEST_F(VideoRenderQualityTrackerTest, capturesFreezeRate) {
Configuration c;
+ c.enabled = true;
Helper h(20, c);
h.render(3);
EXPECT_EQ(h.getMetrics().freezeRate, 0);
@@ -579,6 +594,7 @@
TEST_F(VideoRenderQualityTrackerTest, capturesFreezeDurationHistogram) {
Configuration c;
+ c.enabled = true;
// +17 because freeze durations include the render time of the previous frame
c.freezeDurationMsHistogramBuckets = {2 * 17 + 17, 3 * 17 + 17, 6 * 17 + 17};
Helper h(17, c);
@@ -612,6 +628,7 @@
TEST_F(VideoRenderQualityTrackerTest, capturesFreezeDistanceHistogram) {
Configuration c;
+ c.enabled = true;
c.freezeDistanceMsHistogramBuckets = {1 * 17, 5 * 17, 6 * 17};
Helper h(17, c);
h.render(1);
@@ -643,6 +660,7 @@
TEST_F(VideoRenderQualityTrackerTest, when60hz_hasNoJudder) {
Configuration c;
+ c.enabled = true;
Helper h(16.66, c); // ~24Hz
h.render({16.66, 16.66, 16.66, 16.66, 16.66, 16.66, 16.66});
EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -651,6 +669,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenSmallVariance60hz_hasNoJudder) {
Configuration c;
+ c.enabled = true;
Helper h(16.66, c); // ~24Hz
h.render({14, 18, 14, 18, 14, 18, 14, 18});
EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -659,6 +678,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenBadSmallVariance60Hz_hasJudder) {
Configuration c;
+ c.enabled = true;
Helper h(16.66, c); // ~24Hz
h.render({14, 18, 14, /* no 18 between 14s */ 14, 18, 14, 18});
EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 1);
@@ -666,6 +686,7 @@
TEST_F(VideoRenderQualityTrackerTest, when30Hz_hasNoJudder) {
Configuration c;
+ c.enabled = true;
Helper h(33.33, c);
h.render({33.33, 33.33, 33.33, 33.33, 33.33, 33.33});
EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -674,6 +695,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenSmallVariance30Hz_hasNoJudder) {
Configuration c;
+ c.enabled = true;
Helper h(33.33, c);
h.render({29.0, 35.0, 29.0, 35.0, 29.0, 35.0});
EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -682,6 +704,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenBadSmallVariance30Hz_hasJudder) {
Configuration c;
+ c.enabled = true;
Helper h(33.33, c);
h.render({29.0, 35.0, 29.0, /* no 35 between 29s */ 29.0, 35.0, 29.0, 35.0});
EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 1);
@@ -689,6 +712,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenBad30HzTo60Hz_hasJudder) {
Configuration c;
+ c.enabled = true;
Helper h(33.33, c);
h.render({33.33, 33.33, 50.0, /* frame stayed 1 vsync too long */ 16.66, 33.33, 33.33});
EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 2); // note: 2 counts of judder
@@ -696,6 +720,7 @@
TEST_F(VideoRenderQualityTrackerTest, when24HzTo60Hz_hasNoJudder) {
Configuration c;
+ c.enabled = true;
Helper h(41.66, c);
h.render({50.0, 33.33, 50.0, 33.33, 50.0, 33.33});
EXPECT_LE(h.getMetrics().judderScoreHistogram.getMax(), 0);
@@ -704,6 +729,7 @@
TEST_F(VideoRenderQualityTrackerTest, when25HzTo60Hz_hasJudder) {
Configuration c;
+ c.enabled = true;
Helper h(40, c);
h.render({33.33, 33.33, 50.0});
h.render({33.33, 33.33, 50.0});
@@ -716,6 +742,7 @@
TEST_F(VideoRenderQualityTrackerTest, when50HzTo60Hz_hasJudder) {
Configuration c;
+ c.enabled = true;
Helper h(20, c);
h.render({16.66, 16.66, 16.66, 33.33});
h.render({16.66, 16.66, 16.66, 33.33});
@@ -728,6 +755,7 @@
TEST_F(VideoRenderQualityTrackerTest, when30HzTo50Hz_hasJudder) {
Configuration c;
+ c.enabled = true;
Helper h(33.33, c);
h.render({40.0, 40.0, 40.0, 60.0});
h.render({40.0, 40.0, 40.0, 60.0});
@@ -739,6 +767,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenSmallVariancePulldown24HzTo60Hz_hasNoJudder) {
Configuration c;
+ c.enabled = true;
Helper h(41.66, c);
h.render({52.0, 31.33, 52.0, 31.33, 52.0, 31.33});
EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 0);
@@ -746,6 +775,7 @@
TEST_F(VideoRenderQualityTrackerTest, whenBad24HzTo60Hz_hasJudder) {
Configuration c;
+ c.enabled = true;
Helper h(41.66, c);
h.render({50.0, 33.33, 50.0, 33.33, /* no 50 between 33s */ 33.33, 50.0, 33.33});
EXPECT_EQ(h.getMetrics().judderScoreHistogram.getCount(), 1);
@@ -753,6 +783,7 @@
TEST_F(VideoRenderQualityTrackerTest, capturesJudderScoreHistogram) {
Configuration c;
+ c.enabled = true;
c.judderErrorToleranceUs = 2000;
c.judderScoreHistogramBuckets = {1, 5, 8};
Helper h(16, c);
@@ -767,6 +798,7 @@
TEST_F(VideoRenderQualityTrackerTest, ranksJudderScoresInOrder) {
// Each rendering is ranked from best to worst from a user experience
Configuration c;
+ c.enabled = true;
c.judderErrorToleranceUs = 2000;
c.judderScoreHistogramBuckets = {0, 1000};
int64_t previousScore = 0;
@@ -846,6 +878,7 @@
TEST_F(VideoRenderQualityTrackerTest, capturesFreezeEvents) {
Configuration c;
+ c.enabled = true;
c.freezeEventMax = 5;
c.freezeEventDetailsMax = 4;
c.freezeEventDistanceToleranceMs = 1000;
@@ -938,6 +971,7 @@
TEST_F(VideoRenderQualityTrackerTest, capturesJudderEvents) {
Configuration c;
+ c.enabled = true;
c.judderEventMax = 4;
c.judderEventDetailsMax = 3;
c.judderEventDistanceToleranceMs = 100;
@@ -988,6 +1022,7 @@
TEST_F(VideoRenderQualityTrackerTest, capturesOverallFreezeScore) {
Configuration c;
+ c.enabled = true;
// # drops * 20ms + 20ms because current frame is frozen + 1 for bucket threshold
c.freezeDurationMsHistogramBuckets = {1 * 20 + 21, 5 * 20 + 21, 10 * 20 + 21};
c.freezeDurationMsHistogramToScore = {10, 100, 1000};
@@ -1012,6 +1047,7 @@
TEST_F(VideoRenderQualityTrackerTest, capturesOverallJudderScore) {
Configuration c;
+ c.enabled = true;
c.judderScoreHistogramBuckets = {0, 6, 10};
c.judderScoreHistogramToScore = {10, 100, 1000};
Helper h(20, c);
diff --git a/media/module/codecs/m4v_h263/dec/src/vop.cpp b/media/module/codecs/m4v_h263/dec/src/vop.cpp
index abc0861..2c937c3 100644
--- a/media/module/codecs/m4v_h263/dec/src/vop.cpp
+++ b/media/module/codecs/m4v_h263/dec/src/vop.cpp
@@ -136,6 +136,7 @@
case 0x05:
case 0x06:
case 0x08:
+ case 0x09:
case 0x10:
case 0x11:
case 0x12:
diff --git a/media/module/codecserviceregistrant/Android.bp b/media/module/codecserviceregistrant/Android.bp
index f3a1723..9ee81a4 100644
--- a/media/module/codecserviceregistrant/Android.bp
+++ b/media/module/codecserviceregistrant/Android.bp
@@ -6,34 +6,8 @@
// SPDX-license-identifier-Apache-2.0
}
-cc_library {
- name: "libmedia_codecserviceregistrant",
- vendor_available: true,
- min_sdk_version: "29",
- apex_available: [
- "//apex_available:platform",
- "com.android.media.swcodec",
- ],
-
- srcs: [
- "CodecServiceRegistrant.cpp",
- ],
-
- header_libs: [
- "libmedia_headers",
- ],
-
- defaults: [
- "libcodec2-hidl-defaults",
- ],
- shared_libs: [
- "libbase",
- "libcodec2_hidl@1.0",
- "libcodec2_vndk",
- "libhidlbase",
- "libutils",
- ],
-
+cc_defaults {
+ name: "libcodec2-runtime-libs",
// Codecs
runtime_libs: [
"libcodec2_soft_avcdec",
@@ -61,6 +35,7 @@
"libcodec2_soft_vp9dec",
// "libcodec2_soft_av1dec_aom", // replaced by the gav1 implementation
"libcodec2_soft_av1dec_gav1",
+ "libcodec2_soft_av1dec_dav1d",
"libcodec2_soft_av1enc",
"libcodec2_soft_vp8enc",
"libcodec2_soft_vp9enc",
@@ -70,3 +45,34 @@
"libcodec2_soft_gsmdec",
],
}
+
+cc_library {
+ name: "libmedia_codecserviceregistrant",
+ vendor_available: true,
+ min_sdk_version: "29",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media.swcodec",
+ ],
+
+ srcs: [
+ "CodecServiceRegistrant.cpp",
+ ],
+
+ header_libs: [
+ "libmedia_headers",
+ ],
+
+ defaults: [
+ "libcodec2-hidl-defaults",
+ "libcodec2-runtime-libs",
+ ],
+ shared_libs: [
+ "libbase",
+ "libcodec2_hidl@1.0",
+ "libcodec2_vndk",
+ "libhidlbase",
+ "libutils",
+ ],
+
+}
diff --git a/media/module/libmediatranscoding/transcoder/tests/fuzzer/Android.bp b/media/module/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
index 69b2827..b6eca2a 100644
--- a/media/module/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
+++ b/media/module/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
@@ -48,8 +48,16 @@
],
fuzz_config: {
cc: [
- "android-media-fuzzing-reports@google.com",
+ "android-media-editing@google.com",
],
- componentid: 155276,
+ componentid: 761430,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of libmediatranscoder",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
diff --git a/media/module/mpeg2ts/ATSParser.cpp b/media/module/mpeg2ts/ATSParser.cpp
index 6aeea3b..86187bd 100644
--- a/media/module/mpeg2ts/ATSParser.cpp
+++ b/media/module/mpeg2ts/ATSParser.cpp
@@ -23,8 +23,8 @@
#include "ESQueue.h"
#include <android/hardware/cas/native/1.0/IDescrambler.h>
-#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
+#include <cutils/ashmem.h>
#include <cutils/native_handle.h>
#include <hidlmemory/mapping.h>
#include <media/cas/DescramblerAPI.h>
@@ -46,12 +46,12 @@
#include <inttypes.h>
namespace android {
+using hardware::hidl_handle;
using hardware::hidl_string;
using hardware::hidl_vec;
using hardware::hidl_memory;
using namespace hardware::cas::V1_0;
using namespace hardware::cas::native::V1_0;
-typedef hidl::allocator::V1_0::IAllocator TAllocator;
typedef hidl::memory::V1_0::IMemory TMemory;
// I want the expression "y" evaluated even if verbose logging is off.
@@ -210,7 +210,6 @@
bool mSampleEncrypted;
sp<AMessage> mSampleAesKeyItem;
sp<TMemory> mHidlMemory;
- sp<TAllocator> mHidlAllocator;
hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
sp<ABuffer> mDescrambledBuffer;
List<SubSampleInfo> mSubSamples;
@@ -1006,34 +1005,29 @@
sp<ABuffer> newBuffer, newScrambledBuffer;
sp<TMemory> newMem;
if (mScrambled) {
- if (mHidlAllocator == nullptr) {
- mHidlAllocator = TAllocator::getService("ashmem");
- if (mHidlAllocator == nullptr) {
- ALOGE("[stream %d] can't get hidl allocator", mElementaryPID);
- return false;
+ int fd = ashmem_create_region("mediaATS", neededSize);
+ if (fd < 0) {
+ ALOGE("[stream %d] create_ashmem_region failed for size %zu. FD returned: %d",
+ mElementaryPID, neededSize, fd);
+ return false;
+ }
+
+ native_handle_t* handle = native_handle_create(1 /*numFds*/, 0/*numInts*/);
+ if (handle == nullptr) {
+ ALOGE("[stream %d] failed to create a native_handle_t", mElementaryPID);
+ if (close(fd)) {
+ ALOGE("[stream %d] failed to close ashmem fd. errno: %s", mElementaryPID,
+ strerror(errno));
}
- }
- hidl_memory hidlMemToken;
- bool success;
- auto transStatus = mHidlAllocator->allocate(
- neededSize,
- [&success, &hidlMemToken](
- bool s,
- hidl_memory const& m) {
- success = s;
- hidlMemToken = m;
- });
-
- if (!transStatus.isOk()) {
- ALOGE("[stream %d] hidl allocator failed at the transport: %s",
- mElementaryPID, transStatus.description().c_str());
return false;
}
- if (!success) {
- ALOGE("[stream %d] hidl allocator failed", mElementaryPID);
- return false;
- }
+
+ handle->data[0] = fd;
+ hidl_handle memHandle;
+ memHandle.setTo(handle, true /*shouldOwn*/);
+ hidl_memory hidlMemToken("ashmem", memHandle, neededSize);
+
newMem = mapMemory(hidlMemToken);
if (newMem == nullptr || newMem->getPointer() == nullptr) {
ALOGE("[stream %d] hidl failed to map memory", mElementaryPID);
diff --git a/media/module/mpeg2ts/Android.bp b/media/module/mpeg2ts/Android.bp
index bf762c6..c710ffb 100644
--- a/media/module/mpeg2ts/Android.bp
+++ b/media/module/mpeg2ts/Android.bp
@@ -44,7 +44,6 @@
"libhidlmemory",
"android.hardware.cas.native@1.0",
"android.hidl.memory@1.0",
- "android.hidl.allocator@1.0",
],
header_libs: [
diff --git a/media/module/mpeg2ts/test/Android.bp b/media/module/mpeg2ts/test/Android.bp
index 34a8d3e..cccefac 100644
--- a/media/module/mpeg2ts/test/Android.bp
+++ b/media/module/mpeg2ts/test/Android.bp
@@ -37,9 +37,8 @@
shared_libs: [
"android.hardware.cas@1.0",
"android.hardware.cas.native@1.0",
- "android.hidl.token@1.0-utils",
- "android.hidl.allocator@1.0",
"libcrypto",
+ "libcutils",
"libhidlbase",
"libhidlmemory",
"liblog",
diff --git a/media/mtp/tests/MtpFuzzer/Android.bp b/media/mtp/tests/MtpFuzzer/Android.bp
index 9e41680..acae06a 100644
--- a/media/mtp/tests/MtpFuzzer/Android.bp
+++ b/media/mtp/tests/MtpFuzzer/Android.bp
@@ -38,11 +38,19 @@
],
fuzz_config: {
- cc: ["jameswei@google.com"],
- componentid: 1344,
+ cc: ["android-usb@google.com"],
+ componentid: 1407286,
acknowledgement: [
"Grant Hernandez of Google",
],
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of libmtp library",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
cc_fuzz {
diff --git a/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h b/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h
index 87fea9f..9be53a2 100644
--- a/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h
+++ b/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h
@@ -28,6 +28,7 @@
constexpr size_t kMinSize = 0;
constexpr size_t kMaxSize = 1000;
constexpr size_t kMaxLength = 1000;
+constexpr size_t kMaxPathLength = 64;
class MtpPacketFuzzerUtils {
protected:
@@ -43,7 +44,7 @@
};
void fillFilePath(FuzzedDataProvider* fdp) {
- mPath= fdp->ConsumeRandomLengthString(kMaxLength);
+ mPath= fdp->ConsumeRandomLengthString(kMaxPathLength);
};
void fillUsbDevFsUrb(FuzzedDataProvider* fdp) {
diff --git a/media/ndk/include/media/NdkMediaDataSource.h b/media/ndk/include/media/NdkMediaDataSource.h
index 4158a97..197e202 100644
--- a/media/ndk/include/media/NdkMediaDataSource.h
+++ b/media/ndk/include/media/NdkMediaDataSource.h
@@ -14,6 +14,14 @@
* limitations under the License.
*/
+/**
+ * @addtogroup Media
+ * @{
+ */
+
+/**
+ * @file NdkMediaDataSource.h
+ */
/*
* This file defines an NDK API.
diff --git a/media/ndk/include/media/NdkMediaExtractor.h b/media/ndk/include/media/NdkMediaExtractor.h
index e429820..af30b8b 100644
--- a/media/ndk/include/media/NdkMediaExtractor.h
+++ b/media/ndk/include/media/NdkMediaExtractor.h
@@ -221,9 +221,9 @@
* available (end of stream). This API can be used in in conjunction with
* AMediaExtractor_readSampleData:
*
- * ssize_t sampleSize = AMediaExtractor_getSampleSize(ex);
+ * <pre>ssize_t sampleSize = AMediaExtractor_getSampleSize(ex);
* uint8_t *buf = new uint8_t[sampleSize];
- * AMediaExtractor_readSampleData(ex, buf, sampleSize);
+ * AMediaExtractor_readSampleData(ex, buf, sampleSize);</pre>
*
* Available since API level 28.
*/
@@ -245,13 +245,13 @@
int64_t AMediaExtractor_getCachedDuration(AMediaExtractor *) __INTRODUCED_IN(28);
/**
- * Read the current sample's metadata format into |fmt|. Examples of sample metadata are
+ * Read the current sample's metadata format into `fmt`. Examples of sample metadata are
* SEI (supplemental enhancement information) and MPEG user data, both of which can embed
* closed-caption data.
*
* Returns AMEDIA_OK on success or AMEDIA_ERROR_* to indicate failure reason.
- * Existing key-value pairs in |fmt| would be removed if this API returns AMEDIA_OK.
- * The contents of |fmt| is undefined if this API returns AMEDIA_ERROR_*.
+ * Existing key-value pairs in `fmt` would be removed if this API returns AMEDIA_OK.
+ * The contents of `fmt` is undefined if this API returns AMEDIA_ERROR_*.
*
* Available since API level 28.
*/
diff --git a/media/utils/OWNERS b/media/utils/OWNERS
index f9cb567..fe3205a 100644
--- a/media/utils/OWNERS
+++ b/media/utils/OWNERS
@@ -1 +1,4 @@
-gkasten@google.com
+# Bug component: 48436
+atneya@google.com
+hunga@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 0cd6243..0c878c9 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -142,9 +142,10 @@
name: "libaudioflinger",
defaults: [
- "latest_android_media_audio_common_types_cpp_shared",
- "latest_android_hardware_audio_core_sounddose_ndk_shared",
"audioflinger_flags_defaults",
+ "latest_android_hardware_audio_core_sounddose_ndk_export_shared_lib_header",
+ "latest_android_hardware_audio_core_sounddose_ndk_shared",
+ "latest_android_media_audio_common_types_cpp_shared",
],
srcs: [
@@ -217,7 +218,6 @@
export_shared_lib_headers: [
"libpermission",
- "android.hardware.audio.core.sounddose-V1-ndk",
],
cflags: [
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 0d539c0..29c6845 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -189,6 +189,7 @@
BINDER_METHOD_ENTRY(supportsBluetoothVariableLatency) \
BINDER_METHOD_ENTRY(getSoundDoseInterface) \
BINDER_METHOD_ENTRY(getAudioPolicyConfig) \
+BINDER_METHOD_ENTRY(getAudioMixPort) \
// singleton for Binder Method Statistics for IAudioFlinger
static auto& getIAudioFlingerStatistics() {
@@ -4269,7 +4270,7 @@
response->id = idOut;
response->enabled = enabledOut != 0;
- response->effect = handle->asIEffect();
+ response->effect = handle.get() ? handle->asIEffect() : nullptr;
response->desc = VALUE_OR_RETURN_STATUS(
legacy2aidl_effect_descriptor_t_EffectDescriptor(descOut));
@@ -4607,6 +4608,24 @@
return mPatchPanel->listAudioPatches_l(num_patches, patches);
}
+/**
+ * Get the attributes of the mix port when connecting to the given device port.
+ */
+status_t AudioFlinger::getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *mixPort) const {
+ if (status_t status = AudioValidator::validateAudioPort(*devicePort); status != NO_ERROR) {
+ ALOGE("%s, invalid device port, status=%d", __func__, status);
+ return status;
+ }
+ if (status_t status = AudioValidator::validateAudioPort(*mixPort); status != NO_ERROR) {
+ ALOGE("%s, invalid mix port, status=%d", __func__, status);
+ return status;
+ }
+
+ audio_utils::lock_guard _l(mutex());
+ return mPatchPanel->getAudioMixPort_l(devicePort, mixPort);
+}
+
// ----------------------------------------------------------------------------
status_t AudioFlinger::onTransactWrapper(TransactionCode code,
@@ -4640,6 +4659,7 @@
case TransactionCode::GET_SUPPORTED_LATENCY_MODES:
case TransactionCode::INVALIDATE_TRACKS:
case TransactionCode::GET_AUDIO_POLICY_CONFIG:
+ case TransactionCode::GET_AUDIO_MIX_PORT:
ALOGW("%s: transaction %d received from PID %d",
__func__, code, IPCThreadState::self()->getCallingPid());
// return status only for non void methods
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2c34144..e7f9255 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -255,6 +255,10 @@
status_t getAudioPolicyConfig(media::AudioPolicyConfig* config) final
EXCLUDES_AudioFlinger_Mutex;
+ // Get the attributes of the mix port when connecting to the given device port.
+ status_t getAudioMixPort(const struct audio_port_v7* devicePort,
+ struct audio_port_v7* mixPort) const final EXCLUDES_AudioFlinger_Mutex;
+
status_t onTransactWrapper(TransactionCode code, const Parcel& data, uint32_t flags,
const std::function<status_t()>& delegate) final EXCLUDES_AudioFlinger_Mutex;
diff --git a/services/audioflinger/IAfPatchPanel.h b/services/audioflinger/IAfPatchPanel.h
index 5a6621e..6110e4c 100644
--- a/services/audioflinger/IAfPatchPanel.h
+++ b/services/audioflinger/IAfPatchPanel.h
@@ -302,6 +302,13 @@
virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const
REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
+
+ /**
+ * Get the attributes of the mix port when connecting to the given device port.
+ */
+ virtual status_t getAudioMixPort_l(
+ const struct audio_port_v7* devicePort,
+ struct audio_port_v7* mixPort) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
};
} // namespace android
diff --git a/services/audioflinger/OWNERS b/services/audioflinger/OWNERS
index 17d4c37..e1f69cc 100644
--- a/services/audioflinger/OWNERS
+++ b/services/audioflinger/OWNERS
@@ -1,4 +1,6 @@
+# Bug component: 48436
+elaurent@google.com
hunga@google.com
-jmtrivi@google.com
+jiabin@google.com
mnaganov@google.com
-philburk@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 7d3900b..17591dd 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -447,6 +447,24 @@
return status;
}
+status_t PatchPanel::getAudioMixPort_l(const audio_port_v7 *devicePort,
+ audio_port_v7 *mixPort) {
+ if (devicePort->type != AUDIO_PORT_TYPE_DEVICE) {
+ ALOGE("%s the type of given device port is not DEVICE", __func__);
+ return INVALID_OPERATION;
+ }
+ if (mixPort->type != AUDIO_PORT_TYPE_MIX) {
+ ALOGE("%s the type of given mix port is not MIX", __func__);
+ return INVALID_OPERATION;
+ }
+ AudioHwDevice* hwDevice = findAudioHwDeviceByModule_l(devicePort->ext.device.hw_module);
+ if (hwDevice == nullptr) {
+ ALOGW("%s cannot find hw module %d", __func__, devicePort->ext.device.hw_module);
+ return BAD_VALUE;
+ }
+ return hwDevice->getAudioMixPort(devicePort, mixPort);
+}
+
PatchPanel::Patch::~Patch()
{
ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d",
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 1ff8fff..b107eb0 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -73,6 +73,12 @@
void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final
REQUIRES(audio_utils::AudioFlinger_Mutex);
+ /**
+ * Get the attributes of the mix port when connecting to the given device port
+ */
+ status_t getAudioMixPort_l(const audio_port_v7* devicePort, audio_port_v7* mixPort) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
+
private:
AudioHwDevice* findAudioHwDeviceByModule_l(audio_module_handle_t module)
REQUIRES(audio_utils::AudioFlinger_Mutex);
diff --git a/services/audioflinger/datapath/AudioHwDevice.cpp b/services/audioflinger/datapath/AudioHwDevice.cpp
index 9ff316c..67e9991 100644
--- a/services/audioflinger/datapath/AudioHwDevice.cpp
+++ b/services/audioflinger/datapath/AudioHwDevice.cpp
@@ -118,5 +118,10 @@
return mHwDevice->getAAudioHardwareBurstMinUsec();
}
+status_t AudioHwDevice::getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *mixPort) const {
+ return mHwDevice->getAudioMixPort(devicePort, mixPort);
+}
+
}; // namespace android
diff --git a/services/audioflinger/datapath/AudioHwDevice.h b/services/audioflinger/datapath/AudioHwDevice.h
index f9cb80e..cfb6fbd 100644
--- a/services/audioflinger/datapath/AudioHwDevice.h
+++ b/services/audioflinger/datapath/AudioHwDevice.h
@@ -101,6 +101,9 @@
[[nodiscard]] int32_t getAAudioHardwareBurstMinUsec() const;
+ [[nodiscard]] status_t getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *mixPort) const;
+
private:
const audio_module_handle_t mHandle;
const char * const mModuleName;
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index da0df5f..d49a002 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -574,6 +574,10 @@
media::DeviceConnectedState state) = 0;
virtual status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) = 0;
+
+ // Get the attributes of the mix port when connecting to the given device port.
+ virtual status_t getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *mixPort) = 0;
};
// These are the signatures of createAudioPolicyManager/destroyAudioPolicyManager
diff --git a/services/audiopolicy/OWNERS b/services/audiopolicy/OWNERS
index da9d32f..50ceadf 100644
--- a/services/audiopolicy/OWNERS
+++ b/services/audiopolicy/OWNERS
@@ -1,2 +1,6 @@
+# Bug component: 48436
+elaurent@google.com
+jiabin@google.com
jmtrivi@google.com
mnaganov@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index c489eed..f3a9518 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -63,13 +63,7 @@
if (getRole() == AUDIO_PORT_ROLE_SINK && (flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
maxActiveCount = 0;
}
- if (getRole() == AUDIO_PORT_ROLE_SOURCE) {
- mMixerBehaviors.clear();
- mMixerBehaviors.insert(AUDIO_MIXER_BEHAVIOR_DEFAULT);
- if (mFlags.output & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
- mMixerBehaviors.insert(AUDIO_MIXER_BEHAVIOR_BIT_PERFECT);
- }
- }
+ refreshMixerBehaviors();
}
const MixerBehaviorSet& getMixerBehaviors() const {
@@ -222,6 +216,10 @@
void toSupportedMixerAttributes(std::vector<audio_mixer_attributes_t>* mixerAttributes) const;
+ status_t readFromParcelable(const media::AudioPortFw& parcelable);
+
+ void importAudioPort(const audio_port_v7& port) override;
+
// Number of streams currently opened for this profile.
uint32_t curOpenCount;
// Number of streams currently active for this profile. This is not the number of active clients
@@ -229,6 +227,8 @@
uint32_t curActiveCount;
private:
+ void refreshMixerBehaviors();
+
DeviceVector mSupportedDevices; // supported devices: this input/output can be routed from/to
MixerBehaviorSet mMixerBehaviors;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 4877166..475059c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -322,7 +322,7 @@
mOutput1(0), mOutput2(0), mDirectOpenCount(0),
mDirectClientSession(AUDIO_SESSION_NONE)
{
- if (profile != NULL) {
+ if (profile != nullptr) {
// By default, opening the output without immutable flags, the bit-perfect flags should be
// applied when the apps explicitly request.
mFlags = (audio_output_flags_t)(profile->getFlags() & (~AUDIO_OUTPUT_FLAG_BIT_PERFECT));
@@ -376,7 +376,10 @@
supportedDevices.merge(mOutput2->supportedDevices());
return supportedDevices;
}
- return mProfile->getSupportedDevices();
+ if (mProfile != nullptr) {
+ return mProfile->getSupportedDevices();
+ }
+ return DeviceVector();
}
bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
@@ -407,9 +410,10 @@
if (isDuplicated()) {
return (mOutput1->devicesSupportEncodedFormats(deviceTypes)
|| mOutput2->devicesSupportEncodedFormats(deviceTypes));
- } else {
+ } else if (mProfile != nullptr) {
return mProfile->devicesSupportEncodedFormats(deviceTypes);
}
+ return false;
}
bool SwAudioOutputDescriptor::containsSingleDeviceSupportingEncodedFormats(
@@ -419,7 +423,10 @@
return (mOutput1->containsSingleDeviceSupportingEncodedFormats(device) &&
mOutput2->containsSingleDeviceSupportingEncodedFormats(device));
}
- return mProfile->containsSingleDeviceSupportingEncodedFormats(device);
+ if (mProfile != nullptr) {
+ return mProfile->containsSingleDeviceSupportingEncodedFormats(device);
+ }
+ return false;
}
uint32_t SwAudioOutputDescriptor::latency()
@@ -578,6 +585,11 @@
"with the requested devices, all device types: %s",
__func__, dumpDeviceTypes(devices.types()).c_str());
+ if (mProfile == nullptr) {
+ ALOGE("%s : Cannot open descriptor without a profile ", __func__);
+ return INVALID_OPERATION;
+ }
+
audio_config_t lHalConfig;
if (halConfig == nullptr) {
lHalConfig = AUDIO_CONFIG_INITIALIZER;
@@ -662,7 +674,7 @@
}
return NO_ERROR;
}
- if (!isActive()) {
+ if (mProfile != nullptr && !isActive()) {
if (!mProfile->canStartNewIo()) {
return INVALID_OPERATION;
}
@@ -679,7 +691,7 @@
return;
}
- if (!isActive()) {
+ if (mProfile != nullptr && !isActive()) {
LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
"%s invalid profile active count %u",
__func__, mProfile->curActiveCount);
@@ -702,10 +714,11 @@
}
mClientInterface->closeOutput(mIoHandle);
-
- LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
- __FUNCTION__, mProfile->curOpenCount);
- mProfile->curOpenCount--;
+ if (mProfile != nullptr) {
+ LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
+ __FUNCTION__, mProfile->curOpenCount);
+ mProfile->curOpenCount--;
+ }
mIoHandle = AUDIO_IO_HANDLE_NONE;
}
}
@@ -740,7 +753,10 @@
return std::max(mOutput1->getRecommendedMuteDurationMs(),
mOutput2->getRecommendedMuteDurationMs());
}
- return mProfile->recommendedMuteDurationMs;
+ if (mProfile != nullptr) {
+ return mProfile->recommendedMuteDurationMs;
+ }
+ return 0;
}
void SwAudioOutputDescriptor::setTracksInvalidatedStatusByStrategy(product_strategy_t strategy) {
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index 03ab3f8..dd222de 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -171,6 +171,49 @@
}
}
+void IOProfile::refreshMixerBehaviors() {
+ if (getRole() == AUDIO_PORT_ROLE_SOURCE) {
+ mMixerBehaviors.clear();
+ mMixerBehaviors.insert(AUDIO_MIXER_BEHAVIOR_DEFAULT);
+ if (mFlags.output & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
+ mMixerBehaviors.insert(AUDIO_MIXER_BEHAVIOR_BIT_PERFECT);
+ }
+ }
+}
+
+status_t IOProfile::readFromParcelable(const media::AudioPortFw &parcelable) {
+ status_t status = AudioPort::readFromParcelable(parcelable);
+ if (status == OK) {
+ refreshMixerBehaviors();
+ }
+ return status;
+}
+
+void IOProfile::importAudioPort(const audio_port_v7 &port) {
+ if (mProfiles.hasDynamicFormat()) {
+ std::set<audio_format_t> formats;
+ for (size_t i = 0; i < port.num_audio_profiles; ++i) {
+ formats.insert(port.audio_profiles[i].format);
+ }
+ addProfilesForFormats(mProfiles, FormatVector(formats.begin(), formats.end()));
+ }
+ for (audio_format_t format : mProfiles.getSupportedFormats()) {
+ for (size_t i = 0; i < port.num_audio_profiles; ++i) {
+ if (port.audio_profiles[i].format == format) {
+ ChannelMaskSet channelMasks(port.audio_profiles[i].channel_masks,
+ port.audio_profiles[i].channel_masks +
+ port.audio_profiles[i].num_channel_masks);
+ SampleRateSet sampleRates(port.audio_profiles[i].sample_rates,
+ port.audio_profiles[i].sample_rates +
+ port.audio_profiles[i].num_sample_rates);
+ addDynamicAudioProfileAndSort(
+ mProfiles, sp<AudioProfile>::make(
+ format, channelMasks, sampleRates));
+ }
+ }
+ }
+}
+
void IOProfile::dump(String8 *dst, int spaces) const
{
String8 extraInfo;
@@ -195,6 +238,10 @@
spaces - 2, "", maxActiveCount, curActiveCount);
dst->appendFormat("%*s- recommendedMuteDurationMs: %u ms\n",
spaces - 2, "", recommendedMuteDurationMs);
+ if (hasDynamicAudioProfile() && !mMixerBehaviors.empty()) {
+ dst->appendFormat("%*s- mixerBehaviors: %s\n",
+ spaces - 2, "", dumpMixerBehaviors(mMixerBehaviors).c_str());
+ }
}
void IOProfile::log()
diff --git a/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp b/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp
index 93122e0..fcf410b 100644
--- a/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp
+++ b/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp
@@ -79,6 +79,7 @@
case AUDIO_DEVICE_OUT_USB_ACCESSORY:
case AUDIO_DEVICE_OUT_USB_DEVICE:
case AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
+ case AUDIO_DEVICE_OUT_AUX_DIGITAL:
return GROUP_WIRED;
case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 15f7842..e06bbb3 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -296,7 +296,8 @@
// excluding HEARING_AID and BLE_HEADSET because Dialer uses
// setCommunicationDevice to select them explicitly
AUDIO_DEVICE_OUT_HEARING_AID,
- AUDIO_DEVICE_OUT_BLE_HEADSET
+ AUDIO_DEVICE_OUT_BLE_HEADSET,
+ AUDIO_DEVICE_OUT_AUX_DIGITAL
}));
if (!devices.isEmpty()) break;
devices = availableOutputDevices.getFirstDevicesFromTypes({
@@ -399,20 +400,21 @@
}
if (devices2.isEmpty() && (getLastRemovableMediaDevices().size() > 0)) {
+ std::vector<audio_devices_t> excludedDevices;
+ // no sonification on aux digital (e.g. HDMI)
+ if (strategy == STRATEGY_SONIFICATION) {
+ excludedDevices.push_back(AUDIO_DEVICE_OUT_AUX_DIGITAL);
+ }
if ((getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
// Get the last connected device of wired and bluetooth a2dp
devices2 = availableOutputDevices.getFirstDevicesFromTypes(
- getLastRemovableMediaDevices());
+ getLastRemovableMediaDevices(GROUP_NONE, excludedDevices));
} else {
// Get the last connected device of wired except bluetooth a2dp
devices2 = availableOutputDevices.getFirstDevicesFromTypes(
- getLastRemovableMediaDevices(GROUP_WIRED));
+ getLastRemovableMediaDevices(GROUP_WIRED, excludedDevices));
}
}
- if ((devices2.isEmpty()) && (strategy != STRATEGY_SONIFICATION)) {
- // no sonification on aux digital (e.g. HDMI)
- devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_AUX_DIGITAL);
- }
if ((devices2.isEmpty()) &&
(getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
devices2 = availableOutputDevices.getDevicesFromType(
diff --git a/services/audiopolicy/fuzzer/aidl/Android.bp b/services/audiopolicy/fuzzer/aidl/Android.bp
new file mode 100644
index 0000000..38a2cde
--- /dev/null
+++ b/services/audiopolicy/fuzzer/aidl/Android.bp
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+cc_defaults {
+ name: "audiopolicy_aidl_fuzzer_defaults",
+ shared_libs: [
+ "audiopolicy-aidl-cpp",
+ "audiopolicy-types-aidl-cpp",
+ "framework-permission-aidl-cpp",
+ "libaudiopolicy",
+ "libaudiopolicymanagerdefault",
+ "libactivitymanager_aidl",
+ "libaudiohal",
+ "libaudiopolicyservice",
+ "libaudioflinger",
+ "libaudioclient",
+ "libaudioprocessing",
+ "libhidlbase",
+ "liblog",
+ "libmediautils",
+ "libnblog",
+ "libnbaio",
+ "libpowermanager",
+ "libvibrator",
+ "packagemanager_aidl-cpp",
+ ],
+ static_libs: [
+ "libfakeservicemanager",
+ "libmediaplayerservice",
+ ],
+ header_libs: [
+ "libaudiohal_headers",
+ "libaudioflinger_headers",
+ "libaudiopolicymanager_interface_headers",
+ "libbinder_headers",
+ "libmedia_headers",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ hotlists: ["4593311"],
+ description: "The fuzzer targets the APIs of libaudiopolicy",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
+ },
+}
+
+cc_fuzz {
+ name: "audiopolicy_aidl_fuzzer",
+ srcs: ["audiopolicy_aidl_fuzzer.cpp"],
+ defaults: [
+ "audiopolicy_aidl_fuzzer_defaults",
+ "service_fuzzer_defaults",
+ ],
+}
diff --git a/services/audiopolicy/fuzzer/aidl/audiopolicy_aidl_fuzzer.cpp b/services/audiopolicy/fuzzer/aidl/audiopolicy_aidl_fuzzer.cpp
new file mode 100644
index 0000000..ca79c49
--- /dev/null
+++ b/services/audiopolicy/fuzzer/aidl/audiopolicy_aidl_fuzzer.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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 <AudioFlinger.h>
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_process.h>
+#include <android/media/IAudioPolicyService.h>
+#include <fakeservicemanager/FakeServiceManager.h>
+#include <fuzzbinder/libbinder_driver.h>
+#include <fuzzbinder/random_binder.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/IAudioFlinger.h>
+#include <service/AudioPolicyService.h>
+
+using namespace android;
+using namespace android::binder;
+using namespace android::hardware;
+using android::fuzzService;
+
+[[clang::no_destroy]] static std::once_flag gSmOnce;
+sp<FakeServiceManager> gFakeServiceManager;
+
+bool addService(const String16& serviceName, const sp<FakeServiceManager>& fakeServiceManager,
+ FuzzedDataProvider& fdp) {
+ sp<IBinder> binder = getRandomBinder(&fdp);
+ if (binder == nullptr) {
+ return false;
+ }
+ CHECK_EQ(NO_ERROR, fakeServiceManager->addService(serviceName, binder));
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+
+ std::call_once(gSmOnce, [&] {
+ /* Create a FakeServiceManager instance and add required services */
+ gFakeServiceManager = sp<FakeServiceManager>::make();
+ setDefaultServiceManager(gFakeServiceManager);
+ });
+ gFakeServiceManager->clear();
+
+ for (const char* service :
+ {"activity", "sensor_privacy", "permission", "scheduling_policy",
+ "android.hardware.audio.core.IConfig", "batterystats", "media.metrics"}) {
+ if (!addService(String16(service), gFakeServiceManager, fdp)) {
+ return 0;
+ }
+ }
+
+ const auto audioFlinger = sp<AudioFlinger>::make();
+ const auto afAdapter = sp<AudioFlingerServerAdapter>::make(audioFlinger);
+
+ CHECK_EQ(NO_ERROR,
+ gFakeServiceManager->addService(
+ String16(IAudioFlinger::DEFAULT_SERVICE_NAME), IInterface::asBinder(afAdapter),
+ false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT));
+
+ AudioSystem::get_audio_flinger_for_fuzzer();
+ const auto audioPolicyService = sp<AudioPolicyService>::make();
+
+ CHECK_EQ(NO_ERROR,
+ gFakeServiceManager->addService(String16("media.audio_policy"), audioPolicyService,
+ false /* allowIsolated */,
+ IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT));
+
+ fuzzService(media::IAudioPolicyService::asBinder(audioPolicyService),
+ FuzzedDataProvider(data, size));
+
+ return 0;
+}
diff --git a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
index 8793085..58fcb5c 100644
--- a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
+++ b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
@@ -661,7 +661,9 @@
}
AudioPolicyManagerFuzzerDPPlaybackReRouting::~AudioPolicyManagerFuzzerDPPlaybackReRouting() {
- mManager->stopInput(mPortId);
+ if (mManager) {
+ mManager->stopInput(mPortId);
+ }
}
bool AudioPolicyManagerFuzzerDPPlaybackReRouting::initialize() {
@@ -773,7 +775,9 @@
}
AudioPolicyManagerFuzzerDPMixRecordInjection::~AudioPolicyManagerFuzzerDPMixRecordInjection() {
- mManager->stopOutput(mPortId);
+ if (mManager) {
+ mManager->stopOutput(mPortId);
+ }
}
bool AudioPolicyManagerFuzzerDPMixRecordInjection::initialize() {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index cc32aec..e70af52 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1736,7 +1736,8 @@
// Compressed formats for MSD module, ordered from most preferred to least preferred.
static const std::vector<audio_format_t> formatsOrder = {{
AUDIO_FORMAT_IEC60958, AUDIO_FORMAT_MAT_2_1, AUDIO_FORMAT_MAT_2_0, AUDIO_FORMAT_E_AC3,
- AUDIO_FORMAT_AC3, AUDIO_FORMAT_PCM_16_BIT }};
+ AUDIO_FORMAT_AC3, AUDIO_FORMAT_PCM_FLOAT, AUDIO_FORMAT_PCM_32_BIT,
+ AUDIO_FORMAT_PCM_8_24_BIT, AUDIO_FORMAT_PCM_24_BIT_PACKED, AUDIO_FORMAT_PCM_16_BIT }};
static const std::vector<audio_channel_mask_t> channelMasksOrder = [](){
// Channel position masks for MSD module, 3D > 2D > 1D ordering (most preferred to least
// preferred).
@@ -6519,7 +6520,7 @@
mpClientInterface->setParameters(input, String8(param));
free(param);
}
- updateAudioProfiles(device, input, profile->getAudioProfiles());
+ updateAudioProfiles(device, input, profile);
if (!profile->hasValidAudioProfile()) {
ALOGW("checkInputsForDevice() direct input missing param");
desc->close();
@@ -8049,77 +8050,54 @@
void AudioPolicyManager::updateAudioProfiles(const sp<DeviceDescriptor>& devDesc,
audio_io_handle_t ioHandle,
- AudioProfileVector &profiles)
-{
- String8 reply;
- audio_devices_t device = devDesc->type();
-
- // Format MUST be checked first to update the list of AudioProfile
- if (profiles.hasDynamicFormat()) {
- reply = mpClientInterface->getParameters(
- ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
- ALOGV("%s: supported formats %d, %s", __FUNCTION__, ioHandle, reply.c_str());
- AudioParameter repliedParameters(reply);
- FormatVector formats;
- if (repliedParameters.get(
- String8(AudioParameter::keyStreamSupportedFormats), reply) == NO_ERROR) {
- formats = formatsFromString(reply.c_str());
- } else if (devDesc->hasValidAudioProfile()) {
- ALOGD("%s: using the device profiles", __func__);
- formats = devDesc->getAudioProfiles().getSupportedFormats();
- } else {
- ALOGE("%s: failed to retrieve format, bailing out", __func__);
- return;
- }
- mReportedFormatsMap[devDesc] = formats;
- if (device == AUDIO_DEVICE_OUT_HDMI
- || isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD)) {
- modifySurroundFormats(devDesc, &formats);
- }
- addProfilesForFormats(profiles, formats);
+ const sp<IOProfile>& profile) {
+ if (!profile->hasDynamicAudioProfile()) {
+ return;
}
- for (audio_format_t format : profiles.getSupportedFormats()) {
- std::optional<ChannelMaskSet> channelMasks;
- SampleRateSet samplingRates;
- AudioParameter requestedParameters;
- requestedParameters.addInt(String8(AudioParameter::keyFormat), format);
+ audio_port_v7 devicePort;
+ devDesc->toAudioPort(&devicePort);
- if (profiles.hasDynamicRateFor(format)) {
- reply = mpClientInterface->getParameters(
- ioHandle,
- requestedParameters.toString() + ";" +
- AudioParameter::keyStreamSupportedSamplingRates);
- ALOGV("%s: supported sampling rates %s", __FUNCTION__, reply.c_str());
- AudioParameter repliedParameters(reply);
- if (repliedParameters.get(
- String8(AudioParameter::keyStreamSupportedSamplingRates), reply) == NO_ERROR) {
- samplingRates = samplingRatesFromString(reply.c_str());
- } else {
- samplingRates = devDesc->getAudioProfiles().getSampleRatesFor(format);
- }
- }
- if (profiles.hasDynamicChannelsFor(format)) {
- reply = mpClientInterface->getParameters(ioHandle,
- requestedParameters.toString() + ";" +
- AudioParameter::keyStreamSupportedChannels);
- ALOGV("%s: supported channel masks %s", __FUNCTION__, reply.c_str());
- AudioParameter repliedParameters(reply);
- if (repliedParameters.get(
- String8(AudioParameter::keyStreamSupportedChannels), reply) == NO_ERROR) {
- channelMasks = channelMasksFromString(reply.c_str());
- } else {
- channelMasks = devDesc->getAudioProfiles().getChannelMasksFor(format);
- }
- if (channelMasks.has_value() && (device == AUDIO_DEVICE_OUT_HDMI
- || isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD))) {
- modifySurroundChannelMasks(&channelMasks.value());
- }
- }
- addDynamicAudioProfileAndSort(
- profiles, new AudioProfile(
- format, channelMasks.value_or(ChannelMaskSet()), samplingRates));
+ audio_port_v7 mixPort;
+ profile->toAudioPort(&mixPort);
+ mixPort.ext.mix.handle = ioHandle;
+
+ status_t status = mpClientInterface->getAudioMixPort(&devicePort, &mixPort);
+ if (status != NO_ERROR) {
+ ALOGE("%s failed to query the attributes of the mix port", __func__);
+ return;
}
+
+ std::set<audio_format_t> supportedFormats;
+ for (size_t i = 0; i < mixPort.num_audio_profiles; ++i) {
+ supportedFormats.insert(mixPort.audio_profiles[i].format);
+ }
+ FormatVector formats(supportedFormats.begin(), supportedFormats.end());
+ mReportedFormatsMap[devDesc] = formats;
+
+ if (devDesc->type() == AUDIO_DEVICE_OUT_HDMI ||
+ isDeviceOfModule(devDesc,AUDIO_HARDWARE_MODULE_ID_MSD)) {
+ modifySurroundFormats(devDesc, &formats);
+ size_t modifiedNumProfiles = 0;
+ for (size_t i = 0; i < mixPort.num_audio_profiles; ++i) {
+ if (std::find(formats.begin(), formats.end(), mixPort.audio_profiles[i].format) ==
+ formats.end()) {
+ // Skip the format that is not present after modifying surround formats.
+ continue;
+ }
+ memcpy(&mixPort.audio_profiles[modifiedNumProfiles], &mixPort.audio_profiles[i],
+ sizeof(struct audio_profile));
+ ChannelMaskSet channels(mixPort.audio_profiles[modifiedNumProfiles].channel_masks,
+ mixPort.audio_profiles[modifiedNumProfiles].channel_masks +
+ mixPort.audio_profiles[modifiedNumProfiles].num_channel_masks);
+ modifySurroundChannelMasks(&channels);
+ std::copy(channels.begin(), channels.end(),
+ std::begin(mixPort.audio_profiles[modifiedNumProfiles].channel_masks));
+ mixPort.audio_profiles[modifiedNumProfiles++].num_channel_masks = channels.size();
+ }
+ mixPort.num_audio_profiles = modifiedNumProfiles;
+ }
+ profile->importAudioPort(mixPort);
}
status_t AudioPolicyManager::installPatch(const char *caller,
@@ -8246,7 +8224,7 @@
mpClientInterface->setParameters(output, String8(param));
free(param);
}
- updateAudioProfiles(device, output, profile->getAudioProfiles());
+ updateAudioProfiles(device, output, profile);
if (!profile->hasValidAudioProfile()) {
ALOGW("%s() missing param", __func__);
desc->close();
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 88bafef..440fd01 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -1040,9 +1040,9 @@
void modifySurroundFormats(const sp<DeviceDescriptor>& devDesc, FormatVector *formatsPtr);
void modifySurroundChannelMasks(ChannelMaskSet *channelMasksPtr);
- // If any, resolve any "dynamic" fields of an Audio Profiles collection
+ // If any, resolve any "dynamic" fields of the Audio Profiles collection of and IOProfile
void updateAudioProfiles(const sp<DeviceDescriptor>& devDesc, audio_io_handle_t ioHandle,
- AudioProfileVector &profiles);
+ const sp<IOProfile> &profiles);
// Notify the policy client to prepare for disconnecting external device.
void prepareToDisconnectExternalDevice(const sp<DeviceDescriptor> &device);
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 2874824..7584632 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -340,4 +340,14 @@
return af->invalidateTracks(portIds);
}
+status_t AudioPolicyService::AudioPolicyClient::getAudioMixPort(
+ const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *port) {
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == 0) {
+ return PERMISSION_DENIED;
+ }
+ return af->getAudioMixPort(devicePort, port);
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index d7aa5c9..104e01a 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -51,6 +51,7 @@
namespace android {
using binder::Status;
+using media::audio::common::Spatialization;
static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
@@ -552,7 +553,7 @@
if (mSpatializer != nullptr) {
// Note: mSpatializer != nullptr => mAudioPolicyManager != nullptr
- if (mSpatializer->getLevel() != media::SpatializationLevel::NONE) {
+ if (mSpatializer->getLevel() != Spatialization::Level::NONE) {
audio_io_handle_t currentOutput = mSpatializer->getOutput();
audio_io_handle_t newOutput;
const audio_attributes_t attr = attributes_initializer(AUDIO_USAGE_MEDIA);
@@ -577,8 +578,8 @@
if (status != NO_ERROR) {
mAudioPolicyManager->releaseSpatializerOutput(newOutput);
}
- } else if (mSpatializer->getLevel() == media::SpatializationLevel::NONE
- && mSpatializer->getOutput() != AUDIO_IO_HANDLE_NONE) {
+ } else if (mSpatializer->getLevel() == Spatialization::Level::NONE &&
+ mSpatializer->getOutput() != AUDIO_IO_HANDLE_NONE) {
audio_io_handle_t output = mSpatializer->detachOutput();
if (output != AUDIO_IO_HANDLE_NONE) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index d0cde64..8d5628f 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -856,6 +856,9 @@
status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
+ status_t getAudioMixPort(const struct audio_port_v7 *devicePort,
+ struct audio_port_v7 *port) override;
+
private:
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 1245b1e..7859c2c 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -43,16 +43,16 @@
namespace android {
-using aidl_utils::statusTFromBinderStatus;
using aidl_utils::binderStatusFromStatusT;
+using aidl_utils::statusTFromBinderStatus;
using android::content::AttributionSourceState;
using binder::Status;
using media::HeadTrackingMode;
using media::Pose3f;
-using media::SpatializationLevel;
-using media::SpatializationMode;
-using media::SpatializerHeadTrackingMode;
using media::SensorPoseProvider;
+using media::audio::common::HeadTracking;
+using media::audio::common::Spatialization;
+using ::android::internal::ToString;
using namespace std::chrono_literals;
@@ -302,7 +302,7 @@
}
mSupportsHeadTracking = supportsHeadTracking[0];
- std::vector<media::SpatializationLevel> spatializationLevels;
+ std::vector<Spatialization::Level> spatializationLevels;
status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_LEVELS,
&spatializationLevels);
if (status != NO_ERROR) {
@@ -316,7 +316,7 @@
ALOGW("%s: ignoring spatializationLevel:%d", __func__, (int)spatializationLevel);
continue;
}
- if (spatializationLevel == media::SpatializationLevel::NONE) {
+ if (spatializationLevel == Spatialization::Level::NONE) {
noneLevelFound = true;
} else {
activeLevelFound = true;
@@ -330,7 +330,7 @@
return BAD_VALUE;
}
- std::vector<media::SpatializationMode> spatializationModes;
+ std::vector<Spatialization::Mode> spatializationModes;
status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES,
&spatializationModes);
if (status != NO_ERROR) {
@@ -373,9 +373,9 @@
// Currently we expose only RELATIVE_WORLD.
// This is a limitation of the head tracking library based on a UX choice.
- mHeadTrackingModes.push_back(SpatializerHeadTrackingMode::DISABLED);
+ mHeadTrackingModes.push_back(HeadTracking::Mode::DISABLED);
if (mSupportsHeadTracking) {
- mHeadTrackingModes.push_back(SpatializerHeadTrackingMode::RELATIVE_WORLD);
+ mHeadTrackingModes.push_back(HeadTracking::Mode::RELATIVE_WORLD);
}
mediametrics::LogItem(mMetricsId)
.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE)
@@ -440,7 +440,7 @@
void Spatializer::binderDied(__unused const wp<IBinder> &who) {
{
std::lock_guard lock(mLock);
- mLevel = SpatializationLevel::NONE;
+ mLevel = Spatialization::Level::NONE;
mSpatializerCallback.clear();
}
ALOGV("%s", __func__);
@@ -448,20 +448,20 @@
}
// ISpatializer
-Status Spatializer::getSupportedLevels(std::vector<SpatializationLevel> *levels) {
+Status Spatializer::getSupportedLevels(std::vector<Spatialization::Level> *levels) {
ALOGV("%s", __func__);
if (levels == nullptr) {
return binderStatusFromStatusT(BAD_VALUE);
}
- // SpatializationLevel::NONE is already required from the effect or we don't load it.
+ // Spatialization::Level::NONE is already required from the effect or we don't load it.
levels->insert(levels->end(), mLevels.begin(), mLevels.end());
return Status::ok();
}
-Status Spatializer::setLevel(SpatializationLevel level) {
- ALOGV("%s level %s", __func__, media::toString(level).c_str());
- mLocalLog.log("%s with %s", __func__, media::toString(level).c_str());
- if (level != SpatializationLevel::NONE
+Status Spatializer::setLevel(Spatialization::Level level) {
+ ALOGV("%s level %s", __func__, ToString(level).c_str());
+ mLocalLog.log("%s with %s", __func__, ToString(level).c_str());
+ if (level != Spatialization::Level::NONE
&& std::find(mLevels.begin(), mLevels.end(), level) == mLevels.end()) {
return binderStatusFromStatusT(BAD_VALUE);
}
@@ -488,7 +488,7 @@
return Status::ok();
}
-Status Spatializer::getLevel(SpatializationLevel *level) {
+Status Spatializer::getLevel(Spatialization::Level *level) {
if (level == nullptr) {
return binderStatusFromStatusT(BAD_VALUE);
}
@@ -509,7 +509,7 @@
}
Status Spatializer::getSupportedHeadTrackingModes(
- std::vector<SpatializerHeadTrackingMode>* modes) {
+ std::vector<HeadTracking::Mode>* modes) {
std::lock_guard lock(mLock);
ALOGV("%s", __func__);
if (modes == nullptr) {
@@ -519,24 +519,24 @@
return Status::ok();
}
-Status Spatializer::setDesiredHeadTrackingMode(SpatializerHeadTrackingMode mode) {
- ALOGV("%s mode %s", __func__, media::toString(mode).c_str());
+Status Spatializer::setDesiredHeadTrackingMode(HeadTracking::Mode mode) {
+ ALOGV("%s mode %s", __func__, ToString(mode).c_str());
if (!mSupportsHeadTracking) {
return binderStatusFromStatusT(INVALID_OPERATION);
}
- mLocalLog.log("%s with %s", __func__, media::toString(mode).c_str());
+ mLocalLog.log("%s with %s", __func__, ToString(mode).c_str());
std::lock_guard lock(mLock);
switch (mode) {
- case SpatializerHeadTrackingMode::OTHER:
+ case HeadTracking::Mode::OTHER:
return binderStatusFromStatusT(BAD_VALUE);
- case SpatializerHeadTrackingMode::DISABLED:
+ case HeadTracking::Mode::DISABLED:
mDesiredHeadTrackingMode = HeadTrackingMode::STATIC;
break;
- case SpatializerHeadTrackingMode::RELATIVE_WORLD:
+ case HeadTracking::Mode::RELATIVE_WORLD:
mDesiredHeadTrackingMode = HeadTrackingMode::WORLD_RELATIVE;
break;
- case SpatializerHeadTrackingMode::RELATIVE_SCREEN:
+ case HeadTracking::Mode::RELATIVE_SCREEN:
mDesiredHeadTrackingMode = HeadTrackingMode::SCREEN_RELATIVE;
break;
}
@@ -547,7 +547,7 @@
return Status::ok();
}
-Status Spatializer::getActualHeadTrackingMode(SpatializerHeadTrackingMode *mode) {
+Status Spatializer::getActualHeadTrackingMode(HeadTracking::Mode *mode) {
if (mode == nullptr) {
return binderStatusFromStatusT(BAD_VALUE);
}
@@ -600,8 +600,8 @@
binder->unlinkToDeath(this);
mSpatializerCallback.clear();
- levelChanged = mLevel != SpatializationLevel::NONE;
- mLevel = SpatializationLevel::NONE;
+ levelChanged = mLevel != Spatialization::Level::NONE;
+ mLevel = Spatialization::Level::NONE;
}
if (levelChanged) {
@@ -690,7 +690,7 @@
return Status::ok();
}
-Status Spatializer::getSupportedModes(std::vector<SpatializationMode> *modes) {
+Status Spatializer::getSupportedModes(std::vector<Spatialization::Mode> *modes) {
ALOGV("%s", __func__);
if (modes == nullptr) {
return binderStatusFromStatusT(BAD_VALUE);
@@ -771,7 +771,7 @@
const std::vector<float> headToStage(6, 0.0);
setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE,
- std::vector<SpatializerHeadTrackingMode>{SpatializerHeadTrackingMode::DISABLED});
+ std::vector<HeadTracking::Mode>{HeadTracking::Mode::DISABLED});
}
void Spatializer::onHeadToStagePoseMsg(const std::vector<float>& headToStage) {
@@ -804,21 +804,21 @@
void Spatializer::onActualModeChangeMsg(HeadTrackingMode mode) {
ALOGV("%s(%d)", __func__, (int) mode);
sp<media::ISpatializerHeadTrackingCallback> callback;
- SpatializerHeadTrackingMode spatializerMode;
+ HeadTracking::Mode spatializerMode;
{
std::lock_guard lock(mLock);
if (!mSupportsHeadTracking) {
- spatializerMode = SpatializerHeadTrackingMode::DISABLED;
+ spatializerMode = HeadTracking::Mode::DISABLED;
} else {
switch (mode) {
case HeadTrackingMode::STATIC:
- spatializerMode = SpatializerHeadTrackingMode::DISABLED;
+ spatializerMode = HeadTracking::Mode::DISABLED;
break;
case HeadTrackingMode::WORLD_RELATIVE:
- spatializerMode = SpatializerHeadTrackingMode::RELATIVE_WORLD;
+ spatializerMode = HeadTracking::Mode::RELATIVE_WORLD;
break;
case HeadTrackingMode::SCREEN_RELATIVE:
- spatializerMode = SpatializerHeadTrackingMode::RELATIVE_SCREEN;
+ spatializerMode = HeadTracking::Mode::RELATIVE_SCREEN;
break;
default:
LOG_ALWAYS_FATAL("Unknown mode: %d", mode);
@@ -826,11 +826,11 @@
}
mActualHeadTrackingMode = spatializerMode;
if (mEngine != nullptr) {
- if (spatializerMode == SpatializerHeadTrackingMode::DISABLED) {
+ if (spatializerMode == HeadTracking::Mode::DISABLED) {
resetEngineHeadPose_l();
} else {
setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE,
- std::vector<SpatializerHeadTrackingMode>{spatializerMode});
+ std::vector<HeadTracking::Mode>{spatializerMode});
}
}
callback = mHeadTrackingCallback;
@@ -974,12 +974,12 @@
if (mPoseController != nullptr) {
// TODO(b/253297301, b/255433067) reenable low latency condition check
// for Head Tracking after Bluetooth HAL supports it correctly.
- if (mNumActiveTracks > 0 && mLevel != SpatializationLevel::NONE
+ if (mNumActiveTracks > 0 && mLevel != Spatialization::Level::NONE
&& mDesiredHeadTrackingMode != HeadTrackingMode::STATIC
&& mHeadSensor != SpatializerPoseController::INVALID_SENSOR) {
if (mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE,
- std::vector<SpatializerHeadTrackingMode>{mActualHeadTrackingMode});
+ std::vector<HeadTracking::Mode>{mActualHeadTrackingMode});
}
mPoseController->setHeadSensor(mHeadSensor);
mPoseController->setScreenSensor(mScreenSensor);
@@ -996,20 +996,20 @@
if (mOutput != AUDIO_IO_HANDLE_NONE && supportsSetLatencyMode) {
const status_t status =
AudioSystem::setRequestedLatencyMode(mOutput, requestedLatencyMode);
- ALOGD("%s: setRequestedLatencyMode for output thread(%d) to %s returned %d",
- __func__, mOutput, toString(requestedLatencyMode).c_str(), status);
+ ALOGD("%s: setRequestedLatencyMode for output thread(%d) to %s returned %d", __func__,
+ mOutput, toString(requestedLatencyMode).c_str(), status);
}
}
void Spatializer::checkEngineState_l() {
if (mEngine != nullptr) {
- if (mLevel != SpatializationLevel::NONE && mNumActiveTracks > 0) {
+ if (mLevel != Spatialization::Level::NONE && mNumActiveTracks > 0) {
mEngine->setEnabled(true);
setEffectParameter_l(SPATIALIZER_PARAM_LEVEL,
- std::vector<SpatializationLevel>{mLevel});
+ std::vector<Spatialization::Level>{mLevel});
} else {
setEffectParameter_l(SPATIALIZER_PARAM_LEVEL,
- std::vector<SpatializationLevel>{SpatializationLevel::NONE});
+ std::vector<Spatialization::Level>{Spatialization::Level::NONE});
mEngine->setEnabled(false);
}
}
@@ -1067,21 +1067,21 @@
// 1. Capabilities (mLevels, mHeadTrackingModes, mSpatializationModes, mChannelMasks, etc)
ss.append(prefixSpace).append("Supported levels: [");
for (auto& level : mLevels) {
- base::StringAppendF(&ss, " %s", media::toString(level).c_str());
+ base::StringAppendF(&ss, " %s", ToString(level).c_str());
}
- base::StringAppendF(&ss, "], mLevel: %s", media::toString(mLevel).c_str());
+ base::StringAppendF(&ss, "], mLevel: %s", ToString(mLevel).c_str());
base::StringAppendF(&ss, "\n%smHeadTrackingModes: [", prefixSpace.c_str());
for (auto& mode : mHeadTrackingModes) {
- base::StringAppendF(&ss, " %s", media::toString(mode).c_str());
+ base::StringAppendF(&ss, " %s", ToString(mode).c_str());
}
base::StringAppendF(&ss, "], Desired: %s, Actual %s\n",
media::toString(mDesiredHeadTrackingMode).c_str(),
- media::toString(mActualHeadTrackingMode).c_str());
+ ToString(mActualHeadTrackingMode).c_str());
base::StringAppendF(&ss, "%smSpatializationModes: [", prefixSpace.c_str());
for (auto& mode : mSpatializationModes) {
- base::StringAppendF(&ss, " %s", media::toString(mode).c_str());
+ base::StringAppendF(&ss, " %s", ToString(mode).c_str());
}
ss += "]\n";
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index 0d4d3f6..4ef07ce 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -20,10 +20,9 @@
#include <android-base/stringprintf.h>
#include <android/media/BnEffect.h>
#include <android/media/BnSpatializer.h>
-#include <android/media/SpatializationLevel.h>
-#include <android/media/SpatializationMode.h>
-#include <android/media/SpatializerHeadTrackingMode.h>
#include <android/media/audio/common/AudioLatencyMode.h>
+#include <android/media/audio/common/HeadTracking.h>
+#include <android/media/audio/common/Spatialization.h>
#include <audio_utils/SimpleLog.h>
#include <math.h>
#include <media/AudioEffect.h>
@@ -106,16 +105,17 @@
/** ISpatializer, see ISpatializer.aidl */
binder::Status release() override;
- binder::Status getSupportedLevels(std::vector<media::SpatializationLevel>* levels) override;
- binder::Status setLevel(media::SpatializationLevel level) override;
- binder::Status getLevel(media::SpatializationLevel *level) override;
+ binder::Status getSupportedLevels(
+ std::vector<media::audio::common::Spatialization::Level>* levels) override;
+ binder::Status setLevel(media::audio::common::Spatialization::Level level) override;
+ binder::Status getLevel(media::audio::common::Spatialization::Level *level) override;
binder::Status isHeadTrackingSupported(bool *supports);
binder::Status getSupportedHeadTrackingModes(
- std::vector<media::SpatializerHeadTrackingMode>* modes) override;
+ std::vector<media::audio::common::HeadTracking::Mode>* modes) override;
binder::Status setDesiredHeadTrackingMode(
- media::SpatializerHeadTrackingMode mode) override;
+ media::audio::common::HeadTracking::Mode mode) override;
binder::Status getActualHeadTrackingMode(
- media::SpatializerHeadTrackingMode* mode) override;
+ media::audio::common::HeadTracking::Mode* mode) override;
binder::Status recenterHeadTracker() override;
binder::Status setGlobalTransform(const std::vector<float>& screenToStage) override;
binder::Status setHeadSensor(int sensorHandle) override;
@@ -123,7 +123,8 @@
binder::Status setDisplayOrientation(float physicalToLogicalAngle) override;
binder::Status setHingeAngle(float hingeAngle) override;
binder::Status setFoldState(bool folded) override;
- binder::Status getSupportedModes(std::vector<media::SpatializationMode>* modes) override;
+ binder::Status getSupportedModes(
+ std::vector<media::audio::common::Spatialization::Mode>* modes) override;
binder::Status registerHeadTrackingCallback(
const sp<media::ISpatializerHeadTrackingCallback>& callback) override;
binder::Status setParameter(int key, const std::vector<unsigned char>& value) override;
@@ -145,7 +146,10 @@
status_t loadEngineConfiguration(sp<EffectHalInterface> effect);
/** Level getter for use by local classes. */
- media::SpatializationLevel getLevel() const { std::lock_guard lock(mLock); return mLevel; }
+ media::audio::common::Spatialization::Level getLevel() const {
+ std::lock_guard lock(mLock);
+ return mLevel;
+ }
/** Called by audio policy service when the special output mixer dedicated to spatialization
* is opened and the spatializer engine must be created.
@@ -360,7 +364,8 @@
sp<media::ISpatializerHeadTrackingCallback> mHeadTrackingCallback GUARDED_BY(mLock);
/** Requested spatialization level */
- media::SpatializationLevel mLevel GUARDED_BY(mLock) = media::SpatializationLevel::NONE;
+ media::audio::common::Spatialization::Level mLevel GUARDED_BY(mLock) =
+ media::audio::common::Spatialization::Level::NONE;
/** Control logic for head-tracking, etc. */
std::shared_ptr<SpatializerPoseController> mPoseController GUARDED_BY(mLock);
@@ -370,8 +375,8 @@
= media::HeadTrackingMode::STATIC;
/** Last-reported actual head-tracking mode. */
- media::SpatializerHeadTrackingMode mActualHeadTrackingMode GUARDED_BY(mLock)
- = media::SpatializerHeadTrackingMode::DISABLED;
+ media::audio::common::HeadTracking::Mode mActualHeadTrackingMode GUARDED_BY(mLock)
+ = media::audio::common::HeadTracking::Mode::DISABLED;
/** Selected Head pose sensor */
int32_t mHeadSensor GUARDED_BY(mLock) = SpatializerPoseController::INVALID_SENSOR;
@@ -388,9 +393,9 @@
/** Last hinge angle */
float mHingeAngle GUARDED_BY(mLock) = 0.f; // foldable: 0.f is closed, M_PI flat open.
- std::vector<media::SpatializationLevel> mLevels;
- std::vector<media::SpatializerHeadTrackingMode> mHeadTrackingModes;
- std::vector<media::SpatializationMode> mSpatializationModes;
+ std::vector<media::audio::common::Spatialization::Level> mLevels;
+ std::vector<media::audio::common::HeadTracking::Mode> mHeadTrackingModes;
+ std::vector<media::audio::common::Spatialization::Mode> mSpatializationModes;
std::vector<audio_channel_mask_t> mChannelMasks;
bool mSupportsHeadTracking;
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index 3629c16..7ef0266 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -201,6 +201,26 @@
return mAudioParameters.toString();
}
+ status_t getAudioMixPort(const struct audio_port_v7 *devicePort __unused,
+ struct audio_port_v7 *mixPort) override {
+ mixPort->num_audio_profiles = 0;
+ for (auto format : mSupportedFormats) {
+ const int i = mixPort->num_audio_profiles;
+ mixPort->audio_profiles[i].format = format;
+ mixPort->audio_profiles[i].num_sample_rates = 1;
+ mixPort->audio_profiles[i].sample_rates[0] = 48000;
+ mixPort->audio_profiles[i].num_channel_masks = 0;
+ for (const auto& cm : mSupportedChannelMasks) {
+ if (audio_channel_mask_is_valid(cm)) {
+ mixPort->audio_profiles[i].channel_masks[
+ mixPort->audio_profiles[i].num_channel_masks++] = cm;
+ }
+ }
+ mixPort->num_audio_profiles++;
+ }
+ return NO_ERROR;
+ }
+
void addSupportedFormat(audio_format_t format) {
mSupportedFormats.insert(format);
}
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index 2ae0e97..e55e935 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -106,6 +106,10 @@
status_t invalidateTracks(const std::vector<audio_port_handle_t>& /*portIds*/) override {
return NO_INIT;
}
+ status_t getAudioMixPort(const struct audio_port_v7 *devicePort __unused,
+ struct audio_port_v7 *mixPort __unused) override {
+ return INVALID_OPERATION;
+ }
};
} // namespace android
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 5e58dbb..378255d 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -1423,6 +1423,7 @@
ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUp());
mClient->addSupportedFormat(AUDIO_FORMAT_AC3);
mClient->addSupportedFormat(AUDIO_FORMAT_E_AC3);
+ mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
mManager->setDeviceConnectionState(
AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
"" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT);
@@ -1548,13 +1549,13 @@
mManager->setForceUse(
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
- ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/));
- auto formats = getFormatsFromPorts();
- ASSERT_EQ(0, formats.count(GetParam()));
-
ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/));
- formats = getFormatsFromPorts();
+ auto formats = getFormatsFromPorts();
ASSERT_EQ(1, formats.count(GetParam()));
+
+ ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/));
+ formats = getFormatsFromPorts();
+ ASSERT_EQ(0, formats.count(GetParam()));
}
TEST_P(AudioPolicyManagerTestForHdmi,
diff --git a/services/medialog/OWNERS b/services/medialog/OWNERS
index 21723ba..fe3205a 100644
--- a/services/medialog/OWNERS
+++ b/services/medialog/OWNERS
@@ -1,3 +1,4 @@
-elaurent@google.com
-gkasten@google.com
+# Bug component: 48436
+atneya@google.com
hunga@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}
diff --git a/services/mediametrics/OWNERS b/services/mediametrics/OWNERS
index e37a1f8..14aa2c1 100644
--- a/services/mediametrics/OWNERS
+++ b/services/mediametrics/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1344
essick@google.com
hunga@google.com
diff --git a/services/oboeservice/OWNERS b/services/oboeservice/OWNERS
index f4d51f9..3285bf3 100644
--- a/services/oboeservice/OWNERS
+++ b/services/oboeservice/OWNERS
@@ -1 +1,4 @@
+# Bug component: 48436
+jiabin@google.com
philburk@google.com
+include platform/frameworks/av:/media/janitors/audio_OWNERS #{LAST_RESORT_SUGGESTION}