Merge "Avoid callback promotion in set" into tm-dev
diff --git a/METADATA b/METADATA
index aabda36..146bfcb 100644
--- a/METADATA
+++ b/METADATA
@@ -2,22 +2,22 @@
# CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
# DEPENDING ON IT IN YOUR PROJECT. ***
third_party {
- # would be NOTICE save for Widevine Master License Agreement in:
- # drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp
- # drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
- # drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h
- # drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto
- # drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h
- # and patent disclaimers in:
- # media/codec2/components/aac/patent_disclaimer.txt
- # media/codec2/components/amr_nb_wb/patent_disclaimer.txt
- # media/codec2/components/mp3/patent_disclaimer.txt
- # media/codec2/components/mpeg4_h263/patent_disclaimer.txt
- # media/codecs/amrnb/patent_disclaimer.txt
- # media/codecs/amrwb/dec/patent_disclaimer.txt
- # media/codecs/amrwb/enc/patent_disclaimer.txt
- # media/codecs/m4v_h263/patent_disclaimer.txt
- # media/codecs/mp3dec/patent_disclaimer.txt
- # media/libstagefright/codecs/aacenc/patent_disclaimer.txt
+ license_note: "would be NOTICE save for Widevine Master License Agreement in:\n"
+ " drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp\n"
+ " drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp\n"
+ " drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h\n"
+ " drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto\n"
+ " drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h\n"
+ " and patent disclaimers in:\n"
+ " media/codec2/components/aac/patent_disclaimer.txt\n"
+ " media/codec2/components/amr_nb_wb/patent_disclaimer.txt\n"
+ " media/codec2/components/mp3/patent_disclaimer.txt\n"
+ " media/codec2/components/mpeg4_h263/patent_disclaimer.txt\n"
+ " media/codecs/amrnb/patent_disclaimer.txt\n"
+ " media/codecs/amrwb/dec/patent_disclaimer.txt\n"
+ " media/codecs/amrwb/enc/patent_disclaimer.txt\n"
+ " media/codecs/m4v_h263/patent_disclaimer.txt\n"
+ " media/codecs/mp3dec/patent_disclaimer.txt\n"
+ " media/libstagefright/codecs/aacenc/patent_disclaimer.txt"
license_type: BY_EXCEPTION_ONLY
}
diff --git a/media/bufferpool/2.0/tests/BufferpoolUnitTest.cpp b/media/bufferpool/2.0/tests/BufferpoolUnitTest.cpp
index d9bc2ce..b448405 100644
--- a/media/bufferpool/2.0/tests/BufferpoolUnitTest.cpp
+++ b/media/bufferpool/2.0/tests/BufferpoolUnitTest.cpp
@@ -72,6 +72,7 @@
public:
BufferpoolTest() : mConnectionValid(false), mManager(nullptr), mAllocator(nullptr) {
mConnectionId = -1;
+ mReceiverId = -1;
}
~BufferpoolTest() {
@@ -83,6 +84,7 @@
protected:
bool mConnectionValid;
ConnectionId mConnectionId;
+ ConnectionId mReceiverId;
android::sp<ClientManager> mManager;
std::shared_ptr<BufferPoolAllocator> mAllocator;
@@ -299,6 +301,89 @@
allocHandle.clear();
}
+// Validate cache evict and invalidate APIs.
+TEST_F(BufferpoolUnitTest, FlushTest) {
+ std::vector<uint8_t> vecParams;
+ getTestAllocatorParams(&vecParams);
+
+ ResultStatus status = mManager->registerSender(mManager, mConnectionId, &mReceiverId);
+ ASSERT_TRUE(status == ResultStatus::ALREADY_EXISTS && mReceiverId == mConnectionId);
+
+ // testing empty flush
+ status = mManager->flush(mConnectionId);
+ ASSERT_EQ(status, ResultStatus::OK) << "failed to flush connection : " << mConnectionId;
+
+ std::vector<std::shared_ptr<BufferPoolData>> senderBuffer{};
+ std::vector<native_handle_t*> allocHandle{};
+ std::vector<TransactionId> tid{};
+ std::vector<int64_t> timestampUs{};
+
+ std::map<TransactionId, BufferId> bufferMap{};
+
+ for (int i = 0; i < kNumIterationCount; i++) {
+ int64_t postUs;
+ TransactionId transactionId;
+ native_handle_t* handle = nullptr;
+ std::shared_ptr<BufferPoolData> buffer{};
+ status = mManager->allocate(mConnectionId, vecParams, &handle, &buffer);
+ ASSERT_EQ(status, ResultStatus::OK) << "allocate failed for " << i << " iteration";
+
+ ASSERT_TRUE(TestBufferPoolAllocator::Fill(handle, i));
+
+ status = mManager->postSend(mReceiverId, buffer, &transactionId, &postUs);
+ ASSERT_EQ(status, ResultStatus::OK) << "unable to post send transaction on bufferpool";
+
+ timestampUs.push_back(postUs);
+ tid.push_back(transactionId);
+ bufferMap.insert({transactionId, buffer->mId});
+
+ senderBuffer.push_back(std::move(buffer));
+ if (handle) {
+ allocHandle.push_back(std::move(handle));
+ }
+ buffer.reset();
+ }
+
+ status = mManager->flush(mConnectionId);
+ ASSERT_EQ(status, ResultStatus::OK) << "failed to flush connection : " << mConnectionId;
+
+ std::shared_ptr<BufferPoolData> receiverBuffer{};
+ native_handle_t* recvHandle = nullptr;
+ for (int i = 0; i < kNumIterationCount; i++) {
+ status = mManager->receive(mReceiverId, tid[i], senderBuffer[i]->mId, timestampUs[i],
+ &recvHandle, &receiverBuffer);
+ ASSERT_EQ(status, ResultStatus::OK) << "receive failed for buffer " << senderBuffer[i]->mId;
+
+ // find the buffer id from transaction id
+ auto findIt = bufferMap.find(tid[i]);
+ ASSERT_NE(findIt, bufferMap.end()) << "inconsistent buffer mapping";
+
+ // buffer id received must be same as the buffer id sent
+ ASSERT_EQ(findIt->second, receiverBuffer->mId) << "invalid buffer received";
+
+ ASSERT_TRUE(TestBufferPoolAllocator::Verify(recvHandle, i))
+ << "Message received not same as that sent";
+
+ bufferMap.erase(findIt);
+ if (recvHandle) {
+ native_handle_close(recvHandle);
+ native_handle_delete(recvHandle);
+ }
+ recvHandle = nullptr;
+ receiverBuffer.reset();
+ }
+
+ ASSERT_EQ(bufferMap.size(), 0) << "buffers received is less than the number of buffers sent";
+
+ for (auto handle : allocHandle) {
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ }
+ allocHandle.clear();
+ senderBuffer.clear();
+ timestampUs.clear();
+}
+
// Buffer transfer test between processes.
TEST_F(BufferpoolFunctionalityTest, TransferBuffer) {
// initialize the receiver
@@ -359,6 +444,94 @@
<< "received error during buffer transfer\n";
}
+/* Validate bufferpool for following corner cases:
+ 1. invalid connectionID
+ 2. invalid receiver
+ 3. when sender is not registered
+ 4. when connection is closed
+*/
+// TODO: Enable when the issue in b/212196495 is fixed
+TEST_F(BufferpoolFunctionalityTest, DISABLED_ValidityTest) {
+ std::vector<uint8_t> vecParams;
+ getTestAllocatorParams(&vecParams);
+
+ std::shared_ptr<BufferPoolData> senderBuffer;
+ native_handle_t* allocHandle = nullptr;
+
+ // call allocate() on a random connection id
+ ConnectionId randomId = rand();
+ ResultStatus status = mManager->allocate(randomId, vecParams, &allocHandle, &senderBuffer);
+ EXPECT_TRUE(status == ResultStatus::NOT_FOUND);
+
+ // initialize the receiver
+ PipeMessage message;
+ message.data.command = PipeCommand::INIT;
+ sendMessage(mCommandPipeFds, message);
+ ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
+ ASSERT_EQ(message.data.command, PipeCommand::INIT_OK) << "receiver init failed";
+
+ allocHandle = nullptr;
+ senderBuffer.reset();
+ status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &senderBuffer);
+
+ ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x77));
+
+ // send buffers w/o registering sender
+ int64_t postUs;
+ TransactionId transactionId;
+
+ // random receiver
+ status = mManager->postSend(randomId, senderBuffer, &transactionId, &postUs);
+ ASSERT_NE(status, ResultStatus::OK) << "bufferpool shouldn't allow send on random receiver";
+
+ // establish connection
+ android::sp<IClientManager> receiver = IClientManager::getService();
+ ASSERT_NE(receiver, nullptr) << "getService failed for receiver\n";
+
+ ConnectionId receiverId;
+ status = mManager->registerSender(receiver, mConnectionId, &receiverId);
+ ASSERT_EQ(status, ResultStatus::OK)
+ << "registerSender failed for connection id " << mConnectionId << "\n";
+
+ allocHandle = nullptr;
+ senderBuffer.reset();
+ status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &senderBuffer);
+ ASSERT_EQ(status, ResultStatus::OK) << "allocate failed for connection " << mConnectionId;
+
+ ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x88));
+
+ // send the buffer to the receiver
+ status = mManager->postSend(receiverId, senderBuffer, &transactionId, &postUs);
+ ASSERT_EQ(status, ResultStatus::OK) << "postSend failed for receiver " << receiverId << "\n";
+
+ // PipeMessage message;
+ message.data.command = PipeCommand::TRANSFER;
+ message.data.memsetValue = 0x88;
+ message.data.bufferId = senderBuffer->mId;
+ message.data.connectionId = receiverId;
+ message.data.transactionId = transactionId;
+ message.data.timestampUs = postUs;
+ sendMessage(mCommandPipeFds, message);
+ ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
+ ASSERT_EQ(message.data.command, PipeCommand::TRANSFER_OK)
+ << "received error during buffer transfer\n";
+
+ if (allocHandle) {
+ native_handle_close(allocHandle);
+ native_handle_delete(allocHandle);
+ }
+
+ message.data.command = PipeCommand::STOP;
+ sendMessage(mCommandPipeFds, message);
+ ASSERT_TRUE(receiveMessage(mResultPipeFds, &message)) << "receiveMessage failed\n";
+ ASSERT_EQ(message.data.command, PipeCommand::STOP_OK)
+ << "received error during buffer transfer\n";
+
+ // try to send msg to closed connection
+ status = mManager->postSend(receiverId, senderBuffer, &transactionId, &postUs);
+ ASSERT_NE(status, ResultStatus::OK) << "bufferpool shouldn't allow send on closed connection";
+}
+
int main(int argc, char** argv) {
android::hardware::details::setTrebleTestingOverride(true);
::testing::InitGoogleTest(&argc, argv);
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
index bb63e1f..7afea91 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
@@ -225,7 +225,7 @@
work->result = C2_CORRUPTED;
return;
}
- uint64_t outTimeStamp =
+ int64_t outTimeStamp =
mProcessedSamples * 1000000ll / mIntf->getSampleRate();
size_t inPos = 0;
size_t outPos = 0;
@@ -266,7 +266,7 @@
ALOGV("causal sample size %d", mFilledLen);
if (mIsFirst && outPos != 0) {
mIsFirst = false;
- mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
+ mAnchorTimeStamp = work->input.ordinal.timestamp.peekll();
}
fillEmptyWork(work);
if (outPos != 0) {
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.h b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.h
index 6ab14db..4920b23 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.h
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.h
@@ -54,7 +54,7 @@
bool mIsFirst;
bool mSignalledError;
bool mSignalledOutputEos;
- uint64_t mAnchorTimeStamp;
+ int64_t mAnchorTimeStamp;
uint64_t mProcessedSamples;
int32_t mFilledLen;
int16_t mInputFrame[kNumSamplesPerFrame];
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
index 84728ae..29b1040 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
@@ -307,7 +307,7 @@
work->result = wView.error();
return;
}
- uint64_t outTimeStamp =
+ int64_t outTimeStamp =
mProcessedSamples * 1000000ll / mIntf->getSampleRate();
size_t inPos = 0;
size_t outPos = 0;
@@ -341,7 +341,7 @@
ALOGV("causal sample size %d", mFilledLen);
if (mIsFirst && outPos != 0) {
mIsFirst = false;
- mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
+ mAnchorTimeStamp = work->input.ordinal.timestamp.peekll();
}
fillEmptyWork(work);
if (outPos != 0) {
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.h b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.h
index 0cc9e9f..72990c3 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.h
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.h
@@ -55,7 +55,7 @@
bool mIsFirst;
bool mSignalledError;
bool mSignalledOutputEos;
- uint64_t mAnchorTimeStamp;
+ int64_t mAnchorTimeStamp;
uint64_t mProcessedSamples;
int32_t mFilledLen;
int16_t mInputFrame[kNumSamplesPerFrame];
diff --git a/media/codec2/components/base/SimpleC2Component.cpp b/media/codec2/components/base/SimpleC2Component.cpp
index 434246f..5295822 100644
--- a/media/codec2/components/base/SimpleC2Component.cpp
+++ b/media/codec2/components/base/SimpleC2Component.cpp
@@ -45,23 +45,23 @@
if (isMonochrome) {
// Fill with neutral U/V values.
- for (size_t i = 0; i < height / 2; ++i) {
- memset(dstV, kNeutralUVBitDepth8, width / 2);
- memset(dstU, kNeutralUVBitDepth8, width / 2);
+ for (size_t i = 0; i < (height + 1) / 2; ++i) {
+ memset(dstV, kNeutralUVBitDepth8, (width + 1) / 2);
+ memset(dstU, kNeutralUVBitDepth8, (width + 1) / 2);
dstV += dstUVStride;
dstU += dstUVStride;
}
return;
}
- for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dstV, srcV, width / 2);
+ for (size_t i = 0; i < (height + 1) / 2; ++i) {
+ memcpy(dstV, srcV, (width + 1) / 2);
srcV += srcVStride;
dstV += dstUVStride;
}
- for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dstU, srcU, width / 2);
+ for (size_t i = 0; i < (height + 1) / 2; ++i) {
+ memcpy(dstU, srcU, (width + 1) / 2);
srcU += srcUStride;
dstU += dstUVStride;
}
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 2ed8541..e5fbe99 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -55,8 +55,8 @@
DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
.withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
.withFields({
- C2F(mSize, width).inRange(2, 4096, 2),
- C2F(mSize, height).inRange(2, 4096, 2),
+ C2F(mSize, width).inRange(2, 4096),
+ C2F(mSize, height).inRange(2, 4096),
})
.withSetter(SizeSetter)
.build());
@@ -650,8 +650,12 @@
}
C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
- c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight, format,
- usage, &block);
+ // We always create a graphic block that is width aligned to 16 and height
+ // aligned to 2. We set the correct "crop" value of the image in the call to
+ // createGraphicBuffer() by setting the correct image dimensions.
+ c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16),
+ align(mHeight, 2), format, usage,
+ &block);
if (err != C2_OK) {
ALOGE("fetchGraphicBlock for Output failed with status %d", err);
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index 598500d..4047173 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -100,7 +100,6 @@
"libdmabufheap",
"libfmq",
"libgralloctypes",
- "libhardware",
"libhidlbase",
"libion",
"liblog",
@@ -149,7 +148,6 @@
shared_libs: [
"libui",
"libdl",
- "libhardware",
"libvndksupport",
"libprocessgroup",
],
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index b5200a5..d8d6f06 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -265,6 +265,7 @@
for (const PlaneLayoutComponent &component : plane.components) {
if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
+ mapper.unlock(handle);
return C2_CANNOT_DO;
}
@@ -287,6 +288,7 @@
channel = C2PlaneInfo::CHANNEL_CR;
break;
default:
+ mapper.unlock(handle);
return C2_CORRUPTED;
}
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index fb935b6..e0cc5bf 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -3501,7 +3501,7 @@
}
unsigned mask = br.getBits(8);
for (unsigned i = 0; i < 8; i++) {
- if (((0x1 << i) && mask) == 0)
+ if (((0x1 << i) & mask) == 0)
continue;
if (br.numBitsLeft() < 8) {
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 8faecae..aa59a0c 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -65,6 +65,7 @@
"libhidlbase",
"libhidlmemory",
"libjsoncpp",
+ "libmedia_helper",
"libprocessgroup",
"libstagefright_esds",
"libstagefright_foundation_without_imemory",
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index a5fb394..0871365 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -307,6 +307,8 @@
int32_t maxSharedAudioHistoryMs)
{
status_t status = NO_ERROR;
+ LOG_ALWAYS_FATAL_IF(mInitialized, "%s: should not be called twice", __func__);
+ mInitialized = true;
// Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set.
ALOGV("%s(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
"notificationFrames %u, sessionId %d, transferType %d, flags %#x, attributionSource %s"
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 4c2284b..a7b10b2 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1253,24 +1253,9 @@
return result.value_or(PRODUCT_STRATEGY_NONE);
}
-DeviceTypeSet AudioSystem::getDevicesForStream(audio_stream_type_t stream) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- if (aps == 0) return DeviceTypeSet{};
-
- auto result = [&]() -> ConversionResult<DeviceTypeSet> {
- AudioStreamType streamAidl = VALUE_OR_RETURN(
- legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
- std::vector<AudioDeviceDescription> resultAidl;
- RETURN_IF_ERROR(statusTFromBinderStatus(
- aps->getDevicesForStream(streamAidl, &resultAidl)));
- return convertContainer<DeviceTypeSet>(resultAidl,
- aidl2legacy_AudioDeviceDescription_audio_devices_t);
- }();
- return result.value_or(DeviceTypeSet{});
-}
-
status_t AudioSystem::getDevicesForAttributes(const AudioAttributes& aa,
- AudioDeviceTypeAddrVector* devices) {
+ AudioDeviceTypeAddrVector* devices,
+ bool forVolume) {
if (devices == nullptr) {
return BAD_VALUE;
}
@@ -1281,7 +1266,7 @@
legacy2aidl_AudioAttributes_AudioAttributesEx(aa));
std::vector<AudioDevice> retAidl;
RETURN_STATUS_IF_ERROR(
- statusTFromBinderStatus(aps->getDevicesForAttributes(aaAidl, &retAidl)));
+ statusTFromBinderStatus(aps->getDevicesForAttributes(aaAidl, forVolume, &retAidl)));
*devices = VALUE_OR_RETURN_STATUS(
convertContainer<AudioDeviceTypeAddrVector>(
retAidl,
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 513c4e6..bec6b10 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -277,10 +277,12 @@
{
mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
- (void)set(streamType, sampleRate, format, channelMask,
- frameCount, flags, callback, notificationFrames,
- 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo,
- attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId);
+ // make_unique does not aggregate init until c++20
+ mSetParams = std::unique_ptr<SetParams>{
+ new SetParams{streamType, sampleRate, format, channelMask, frameCount, flags, callback,
+ notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/,
+ sessionId, transferType, offloadInfo, attributionSource, pAttributes,
+ doNotReconnect, maxRequiredSpeed, selectedDeviceId}};
}
namespace {
@@ -355,10 +357,11 @@
} else if (user) {
LOG_ALWAYS_FATAL("Callback data provided without callback pointer!");
}
- (void)set(streamType, sampleRate, format, channelMask,
- frameCount, flags, mLegacyCallbackWrapper, notificationFrames,
- 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo,
- attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId);
+ mSetParams = std::unique_ptr<SetParams>{new SetParams{
+ streamType, sampleRate, format, channelMask, frameCount, flags, mLegacyCallbackWrapper,
+ notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId,
+ transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect,
+ maxRequiredSpeed, selectedDeviceId}};
}
AudioTrack::AudioTrack(
@@ -387,10 +390,11 @@
{
mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
- (void)set(streamType, sampleRate, format, channelMask,
- 0 /*frameCount*/, flags, callback, notificationFrames,
- sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo,
- attributionSource, pAttributes, doNotReconnect, maxRequiredSpeed);
+ mSetParams = std::unique_ptr<SetParams>{
+ new SetParams{streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags,
+ callback, notificationFrames, sharedBuffer, false /*threadCanCallJava*/,
+ sessionId, transferType, offloadInfo, attributionSource, pAttributes,
+ doNotReconnect, maxRequiredSpeed, AUDIO_PORT_HANDLE_NONE}};
}
AudioTrack::AudioTrack(
@@ -424,11 +428,18 @@
} else if (user) {
LOG_ALWAYS_FATAL("Callback data provided without callback pointer!");
}
+ mSetParams = std::unique_ptr<SetParams>{new SetParams{
+ streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags,
+ mLegacyCallbackWrapper, notificationFrames, sharedBuffer, false /*threadCanCallJava*/,
+ sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect,
+ maxRequiredSpeed, AUDIO_PORT_HANDLE_NONE}};
+}
- (void)set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags,
- mLegacyCallbackWrapper, notificationFrames, sharedBuffer,
- false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, attributionSource,
- pAttributes, doNotReconnect, maxRequiredSpeed);
+void AudioTrack::onFirstRef() {
+ if (mSetParams) {
+ set(*mSetParams);
+ mSetParams.reset();
+ }
}
AudioTrack::~AudioTrack()
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index f10c5d0..e2ef772 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -137,9 +137,7 @@
int /* product_strategy_t */ getStrategyForStream(AudioStreamType stream);
- AudioDeviceDescription[] getDevicesForStream(AudioStreamType stream);
-
- AudioDevice[] getDevicesForAttributes(in AudioAttributesEx attr);
+ AudioDevice[] getDevicesForAttributes(in AudioAttributesEx attr, boolean forVolume);
int /* audio_io_handle_t */ getOutputForEffect(in EffectDescriptor desc);
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index faea716..cb05dd9 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -740,6 +740,7 @@
wp<IAudioRecordCallback> mCallback;
sp<IAudioRecordCallback> mLegacyCallbackWrapper;
+ bool mInitialized = false; // Protect against double set
// for notification APIs
uint32_t mNotificationFramesReq; // requested number of frames between each
// notification callback
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index a1fb125..e89ce15 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -328,9 +328,9 @@
static status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index);
static product_strategy_t getStrategyForStream(audio_stream_type_t stream);
- static DeviceTypeSet getDevicesForStream(audio_stream_type_t stream);
static status_t getDevicesForAttributes(const AudioAttributes &aa,
- AudioDeviceTypeAddrVector *devices);
+ AudioDeviceTypeAddrVector *devices,
+ bool forVolume);
static audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc);
static status_t registerEffect(const effect_descriptor_t *desc,
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 1708cc7..1cf6ef9 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -458,6 +458,38 @@
float maxRequiredSpeed = 1.0f,
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
+ struct SetParams {
+ audio_stream_type_t streamType;
+ uint32_t sampleRate;
+ audio_format_t format;
+ audio_channel_mask_t channelMask;
+ size_t frameCount;
+ audio_output_flags_t flags;
+ wp<IAudioTrackCallback> callback;
+ int32_t notificationFrames;
+ sp<IMemory> sharedBuffer;
+ bool threadCanCallJava;
+ audio_session_t sessionId;
+ transfer_type transferType;
+ // TODO don't take pointers here
+ const audio_offload_info_t *offloadInfo;
+ AttributionSourceState attributionSource;
+ const audio_attributes_t* pAttributes;
+ bool doNotReconnect;
+ float maxRequiredSpeed;
+ audio_port_handle_t selectedDeviceId;
+ };
+ private:
+ // Note: Consumes parameters
+ void set(SetParams& s) {
+ (void)set(s.streamType, s.sampleRate, s.format, s.channelMask, s.frameCount,
+ s.flags, std::move(s.callback), s.notificationFrames,
+ std::move(s.sharedBuffer), s.threadCanCallJava, s.sessionId,
+ s.transferType, s.offloadInfo, std::move(s.attributionSource),
+ s.pAttributes, s.doNotReconnect, s.maxRequiredSpeed, s.selectedDeviceId);
+ }
+ void onFirstRef() override;
+ public:
status_t set(audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
@@ -1349,6 +1381,8 @@
wp<IAudioTrackCallback> mCallback; // callback handler for events, or NULL
sp<IAudioTrackCallback> mLegacyCallbackWrapper; // wrapper for legacy callback interface
// for notification APIs
+ std::unique_ptr<SetParams> mSetParams; // Temporary copy of ctor params to allow for
+ // deferred set after first reference.
bool mInitialized = false; // Set after track is initialized
// next 2 fields are const after constructor or set()
diff --git a/media/libmediahelper/Android.bp b/media/libmediahelper/Android.bp
index a433fc6..b9d795d 100644
--- a/media/libmediahelper/Android.bp
+++ b/media/libmediahelper/Android.bp
@@ -29,6 +29,7 @@
cc_library {
name: "libmedia_helper",
vendor_available: true,
+ min_sdk_version: "29",
vndk: {
enabled: true,
},
@@ -58,4 +59,9 @@
enabled: false,
},
},
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ "test_com.android.media",
+ ],
}
diff --git a/media/libstagefright/data/media_codecs_google_c2_video.xml b/media/libstagefright/data/media_codecs_google_c2_video.xml
index 04041eb..3509ef8 100644
--- a/media/libstagefright/data/media_codecs_google_c2_video.xml
+++ b/media/libstagefright/data/media_codecs_google_c2_video.xml
@@ -79,7 +79,7 @@
</MediaCodec>
<MediaCodec name="c2.android.av1.decoder" type="video/av01">
<Limit name="size" min="96x96" max="1920x1080" />
- <Limit name="alignment" value="2x2" />
+ <Limit name="alignment" value="1x1" />
<Limit name="block-size" value="16x16" />
<Limit name="blocks-per-second" min="24" max="2073600" />
<Limit name="bitrate" range="1-120000000" />
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index 53ca4e7..d7e2d18 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -184,7 +184,7 @@
</MediaCodec>
<MediaCodec name="c2.android.av1.decoder" type="video/av01" variant="!slow-cpu">
<Limit name="size" min="2x2" max="2048x2048" />
- <Limit name="alignment" value="2x2" />
+ <Limit name="alignment" value="1x1" />
<Limit name="block-size" value="16x16" />
<Limit name="block-count" range="1-16384" />
<Limit name="blocks-per-second" range="1-2073600" />
diff --git a/media/libstagefright/foundation/ALooperRoster.cpp b/media/libstagefright/foundation/ALooperRoster.cpp
index 0a4e598..4334f1e 100644
--- a/media/libstagefright/foundation/ALooperRoster.cpp
+++ b/media/libstagefright/foundation/ALooperRoster.cpp
@@ -19,6 +19,8 @@
#include <utils/Log.h>
#include <utils/String8.h>
+#include <inttypes.h>
+
#include "ALooperRoster.h"
#include "ADebug.h"
@@ -142,7 +144,7 @@
sp<AHandler> handler = info.mHandler.promote();
if (handler != NULL) {
handler->mVerboseStats = verboseStats;
- s.appendFormat(": %u messages processed", handler->mMessageCounter);
+ s.appendFormat(": %" PRIu64 " messages processed", handler->mMessageCounter);
if (verboseStats) {
for (size_t j = 0; j < handler->mMessages.size(); j++) {
char fourcc[15];
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AHandler.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AHandler.h
index 53d8a9b..337460a 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AHandler.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AHandler.h
@@ -66,7 +66,7 @@
}
bool mVerboseStats;
- uint32_t mMessageCounter;
+ uint64_t mMessageCounter;
KeyedVector<uint32_t, uint32_t> mMessages;
void deliverMessage(const sp<AMessage> &msg);
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 5b2b87e..09f947c 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -210,12 +210,10 @@
// return the strategy corresponding to a given stream type
virtual product_strategy_t getStrategyForStream(audio_stream_type_t stream) = 0;
- // return the enabled output devices for the given stream type
- virtual DeviceTypeSet getDevicesForStream(audio_stream_type_t stream) = 0;
-
// retrieves the list of enabled output devices for the given audio attributes
virtual status_t getDevicesForAttributes(const audio_attributes_t &attr,
- AudioDeviceTypeAddrVector *devices) = 0;
+ AudioDeviceTypeAddrVector *devices,
+ bool forVolume) = 0;
// Audio effect management
virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc) = 0;
diff --git a/services/audiopolicy/TEST_MAPPING b/services/audiopolicy/TEST_MAPPING
index eb6c19e..9b4cc8a 100644
--- a/services/audiopolicy/TEST_MAPPING
+++ b/services/audiopolicy/TEST_MAPPING
@@ -2,6 +2,15 @@
"presubmit": [
{
"name": "audiopolicy_tests"
+ },
+ {
+ "name": "GtsGmscoreHostTestCases",
+ "keywords": ["primary-device"],
+ "options" : [
+ {
+ "include-filter": "com.google.android.gts.audio.AudioHostTest#testTwoChannelCapturing"
+ }
+ ]
}
]
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index fd42229..c3c9753 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3919,7 +3919,7 @@
status_t AudioPolicyManager::getDirectProfilesForAttributes(const audio_attributes_t* attr,
AudioProfileVector& audioProfilesVector) {
AudioDeviceTypeAddrVector devices;
- status_t status = getDevicesForAttributes(*attr, &devices);
+ status_t status = getDevicesForAttributes(*attr, &devices, false /* forVolume */);
if (status != OK) {
return status;
}
@@ -6430,66 +6430,71 @@
return (stream1 == stream2);
}
-DeviceTypeSet AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
- // By checking the range of stream before calling getStrategy, we avoid
- // getOutputDevicesForStream's behavior for invalid streams.
- // engine's getOutputDevicesForStream would fallback on its default behavior (most probably
- // device for music stream), but we want to return the empty set.
- if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
- return DeviceTypeSet{};
- }
- DeviceVector activeDevices;
- DeviceVector devices;
- for (int i = AUDIO_STREAM_MIN; i < AUDIO_STREAM_PUBLIC_CNT; ++i) {
- const audio_stream_type_t curStream{static_cast<audio_stream_type_t>(i)};
- if (!streamsMatchForvolume(stream, curStream)) {
- continue;
- }
- DeviceVector curDevices = mEngine->getOutputDevicesForStream(curStream, false/*fromCache*/);
- devices.merge(curDevices);
- for (audio_io_handle_t output : getOutputsForDevices(curDevices, mOutputs)) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
- if (outputDesc->isActive(toVolumeSource(curStream, false))) {
- activeDevices.merge(outputDesc->devices());
- }
- }
- }
-
- // Favor devices selected on active streams if any to report correct device in case of
- // explicit device selection
- if (!activeDevices.isEmpty()) {
- devices = activeDevices;
- }
- /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it
- and doesn't really need to.*/
- DeviceVector speakerSafeDevices = devices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER_SAFE);
- if (!speakerSafeDevices.isEmpty()) {
- devices.merge(mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
- devices.remove(speakerSafeDevices);
- }
- return devices.types();
-}
-
// TODO - consider MSD routes b/214971780
status_t AudioPolicyManager::getDevicesForAttributes(
- const audio_attributes_t &attr, AudioDeviceTypeAddrVector *devices) {
+ const audio_attributes_t &attr, AudioDeviceTypeAddrVector *devices, bool forVolume) {
if (devices == nullptr) {
return BAD_VALUE;
}
+
+ // Devices are determined in the following precedence:
+ //
+ // 1) Devices associated with a dynamic policy matching the attributes. This is often
+ // a remote submix from MIX_ROUTE_FLAG_LOOP_BACK.
+ //
+ // If no such dynamic policy then
+ // 2) Devices containing an active client using setPreferredDevice
+ // with same strategy as the attributes.
+ // (from the default Engine::getOutputDevicesForAttributes() implementation).
+ //
+ // If no corresponding active client with setPreferredDevice then
+ // 3) Devices associated with the strategy determined by the attributes
+ // (from the default Engine::getOutputDevicesForAttributes() implementation).
+ //
+ // See related getOutputForAttrInt().
+
// check dynamic policies but only for primary descriptors (secondary not used for audible
// audio routing, only used for duplication for playback capture)
sp<AudioPolicyMix> policyMix;
status_t status = mPolicyMixes.getOutputForAttr(attr, 0 /*uid unknown here*/,
- AUDIO_OUTPUT_FLAG_NONE, policyMix, nullptr);
+ AUDIO_OUTPUT_FLAG_NONE, policyMix, nullptr /* secondaryMixes */);
if (status != OK) {
return status;
}
- if (policyMix != nullptr && policyMix->getOutput() != nullptr) {
- AudioDeviceTypeAddr device(policyMix->mDeviceType, policyMix->mDeviceAddress.c_str());
- devices->push_back(device);
- return NO_ERROR;
+
+ DeviceVector curDevices;
+ if (policyMix != nullptr && policyMix->getOutput() != nullptr &&
+ // For volume control, skip LOOPBACK mixes which use AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+ // as they are unaffected by device/stream volume
+ // (per SwAudioOutputDescriptor::isFixedVolume()).
+ (!forVolume || policyMix->mDeviceType != AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
+ ) {
+ sp<DeviceDescriptor> deviceDesc = mAvailableOutputDevices.getDevice(
+ policyMix->mDeviceType, policyMix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
+ curDevices.add(deviceDesc);
+ } else {
+ // The default Engine::getOutputDevicesForAttributes() uses findPreferredDevice()
+ // which selects setPreferredDevice if active. This means forVolume call
+ // will take an active setPreferredDevice, if such exists.
+
+ curDevices = mEngine->getOutputDevicesForAttributes(
+ attr, nullptr /* preferredDevice */, false /* fromCache */);
}
- DeviceVector curDevices = mEngine->getOutputDevicesForAttributes(attr, nullptr, false);
+
+ if (forVolume) {
+ // We alias the device AUDIO_DEVICE_OUT_SPEAKER_SAFE to AUDIO_DEVICE_OUT_SPEAKER
+ // for single volume control in AudioService (such relationship should exist if
+ // SPEAKER_SAFE is present).
+ //
+ // (This is unrelated to a different device grouping as Volume::getDeviceCategory)
+ DeviceVector speakerSafeDevices =
+ curDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER_SAFE);
+ if (!speakerSafeDevices.isEmpty()) {
+ curDevices.merge(
+ mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
+ curDevices.remove(speakerSafeDevices);
+ }
+ }
for (const auto& device : curDevices) {
devices->push_back(device->getDeviceTypeAddr());
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index daa4faf..4d307cf 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -190,12 +190,37 @@
return mEngine->getProductStrategyForAttributes(attributes);
}
- // return the enabled output devices for the given stream type
- virtual DeviceTypeSet getDevicesForStream(audio_stream_type_t stream);
-
+ /**
+ * Returns a vector of devices associated with attributes.
+ *
+ * An AudioTrack opened with specified attributes should play on the returned devices.
+ * If forVolume is set to true, the caller is AudioService, determining the proper
+ * device volume to adjust.
+ *
+ * Devices are determined in the following precedence:
+ * 1) Devices associated with a dynamic policy matching the attributes. This is often
+ * a remote submix from MIX_ROUTE_FLAG_LOOP_BACK. Secondary mixes from a
+ * dynamic policy are not included.
+ *
+ * If no such dynamic policy then
+ * 2) Devices containing an active client using setPreferredDevice
+ * with same strategy as the attributes.
+ * (from the default Engine::getOutputDevicesForAttributes() implementation).
+ *
+ * If no corresponding active client with setPreferredDevice then
+ * 3) Devices associated with the strategy determined by the attributes
+ * (from the default Engine::getOutputDevicesForAttributes() implementation).
+ *
+ * @param attributes to be considered
+ * @param devices an AudioDeviceTypeAddrVector container passed in that
+ * will be filled on success.
+ * @param forVolume true if the devices are to be associated with current device volume.
+ * @return NO_ERROR on success.
+ */
virtual status_t getDevicesForAttributes(
const audio_attributes_t &attributes,
- AudioDeviceTypeAddrVector *devices);
+ AudioDeviceTypeAddrVector *devices,
+ bool forVolume);
virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc = NULL);
virtual status_t registerEffect(const effect_descriptor_t *desc,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 391d60a..ae4d174 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -485,6 +485,7 @@
status_t status = mAudioPolicyManager->startOutput(portId);
if (status == NO_ERROR) {
client->active = true;
+ onUpdateActiveSpatializerTracks_l();
}
return binderStatusFromStatusT(status);
}
@@ -522,6 +523,7 @@
status_t status = mAudioPolicyManager->stopOutput(portId);
if (status == NO_ERROR) {
client->active = false;
+ onUpdateActiveSpatializerTracks_l();
}
return status;
}
@@ -552,8 +554,10 @@
client->io, client->stream, client->session);
}
Mutex::Autolock _l(mLock);
+ if (client != nullptr && client->active) {
+ onUpdateActiveSpatializerTracks_l();
+ }
mAudioPlaybackClients.removeItem(portId);
-
// called from internal thread: no need to clear caller identity
mAudioPolicyManager->releaseOutput(portId);
}
@@ -1159,31 +1163,8 @@
return Status::ok();
}
-//audio policy: use audio_device_t appropriately
-
-Status AudioPolicyService::getDevicesForStream(
- AudioStreamType streamAidl,
- std::vector<AudioDeviceDescription>* _aidl_return) {
- audio_stream_type_t stream = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioStreamType_audio_stream_type_t(streamAidl));
-
- if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
- *_aidl_return = std::vector<AudioDeviceDescription>{};
- return Status::ok();
- }
- if (mAudioPolicyManager == NULL) {
- return binderStatusFromStatusT(NO_INIT);
- }
- Mutex::Autolock _l(mLock);
- AutoCallerClear acc;
- *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(
- convertContainer<std::vector<AudioDeviceDescription>>(
- mAudioPolicyManager->getDevicesForStream(stream),
- legacy2aidl_audio_devices_t_AudioDeviceDescription));
- return Status::ok();
-}
-
Status AudioPolicyService::getDevicesForAttributes(const media::AudioAttributesEx& attrAidl,
+ bool forVolume,
std::vector<AudioDevice>* _aidl_return)
{
AudioAttributes aa = VALUE_OR_RETURN_BINDER_STATUS(
@@ -1196,7 +1177,8 @@
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
- mAudioPolicyManager->getDevicesForAttributes(aa.getAttributes(), &devices)));
+ mAudioPolicyManager->getDevicesForAttributes(
+ aa.getAttributes(), &devices, forVolume)));
*_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(
convertContainer<std::vector<AudioDevice>>(devices,
legacy2aidl_AudioDeviceTypeAddress));
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 9b08044..3ee2aa3 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -397,6 +397,7 @@
if (status == NO_ERROR && currentOutput == newOutput) {
return;
}
+ size_t numActiveTracks = countActiveClientsOnOutput_l(newOutput);
mLock.unlock();
// It is OK to call detachOutput() is none is already attached.
mSpatializer->detachOutput();
@@ -404,7 +405,7 @@
mLock.lock();
return;
}
- status = mSpatializer->attachOutput(newOutput);
+ status = mSpatializer->attachOutput(newOutput, numActiveTracks);
mLock.lock();
if (status != NO_ERROR) {
mAudioPolicyManager->releaseSpatializerOutput(newOutput);
@@ -421,6 +422,34 @@
}
}
+size_t AudioPolicyService::countActiveClientsOnOutput_l(audio_io_handle_t output) REQUIRES(mLock) {
+ size_t count = 0;
+ for (size_t i = 0; i < mAudioPlaybackClients.size(); i++) {
+ auto client = mAudioPlaybackClients.valueAt(i);
+ if (client->io == output && client->active) {
+ count++;
+ }
+ }
+ return count;
+}
+
+void AudioPolicyService::onUpdateActiveSpatializerTracks_l() {
+ if (mSpatializer == nullptr) {
+ return;
+ }
+ mOutputCommandThread->updateActiveSpatializerTracksCommand();
+}
+
+void AudioPolicyService::doOnUpdateActiveSpatializerTracks()
+{
+ Mutex::Autolock _l(mLock);
+ if (mSpatializer == nullptr) {
+ return;
+ }
+ mSpatializer->updateActiveTracks(countActiveClientsOnOutput_l(mSpatializer->getOutput()));
+}
+
+
status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
audio_patch_handle_t *handle,
int delayMs)
@@ -580,11 +609,6 @@
char buffer[SIZE];
String8 result;
- snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager);
- result.append(buffer);
- snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
- result.append(buffer);
-
snprintf(buffer, SIZE, "Supported System Usages:\n ");
result.append(buffer);
std::stringstream msg;
@@ -1014,12 +1038,24 @@
}
dumpInternals(fd);
+
+ String8 actPtr = String8::format("AudioCommandThread: %p\n", mAudioCommandThread.get());
+ write(fd, actPtr.string(), actPtr.size());
if (mAudioCommandThread != 0) {
mAudioCommandThread->dump(fd);
}
+ String8 octPtr = String8::format("OutputCommandThread: %p\n", mOutputCommandThread.get());
+ write(fd, octPtr.string(), octPtr.size());
+ if (mOutputCommandThread != 0) {
+ mOutputCommandThread->dump(fd);
+ }
+
if (mAudioPolicyManager) {
mAudioPolicyManager->dump(fd);
+ } else {
+ String8 apmPtr = String8::format("AudioPolicyManager: %p\n", mAudioPolicyManager);
+ write(fd, apmPtr.string(), apmPtr.size());
}
mPackageManager.dump(fd);
@@ -1085,7 +1121,6 @@
case TRANSACTION_isStreamActive:
case TRANSACTION_isStreamActiveRemotely:
case TRANSACTION_isSourceActive:
- case TRANSACTION_getDevicesForStream:
case TRANSACTION_registerPolicyMixes:
case TRANSACTION_setMasterMono:
case TRANSACTION_getSurroundFormats:
@@ -1946,8 +1981,8 @@
mLock.lock();
} break;
- case CHECK_SPATIALIZER: {
- ALOGV("AudioCommandThread() processing updateUID states");
+ case CHECK_SPATIALIZER_OUTPUT: {
+ ALOGV("AudioCommandThread() processing check spatializer");
svc = mService.promote();
if (svc == 0) {
break;
@@ -1957,6 +1992,17 @@
mLock.lock();
} break;
+ case UPDATE_ACTIVE_SPATIALIZER_TRACKS: {
+ ALOGV("AudioCommandThread() processing update spatializer tracks");
+ svc = mService.promote();
+ if (svc == 0) {
+ break;
+ }
+ mLock.unlock();
+ svc->doOnUpdateActiveSpatializerTracks();
+ mLock.lock();
+ } break;
+
default:
ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
}
@@ -2010,10 +2056,6 @@
char buffer[SIZE];
String8 result;
- snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
- result.append(buffer);
- write(fd, result.string(), result.size());
-
const bool locked = dumpTryLock(mLock);
if (!locked) {
String8 result2(kCmdDeadlockedString);
@@ -2271,11 +2313,19 @@
void AudioPolicyService::AudioCommandThread::checkSpatializerCommand()
{
sp<AudioCommand>command = new AudioCommand();
- command->mCommand = CHECK_SPATIALIZER;
+ command->mCommand = CHECK_SPATIALIZER_OUTPUT;
ALOGV("AudioCommandThread() adding check spatializer");
sendCommand(command);
}
+void AudioPolicyService::AudioCommandThread::updateActiveSpatializerTracksCommand()
+{
+ sp<AudioCommand>command = new AudioCommand();
+ command->mCommand = UPDATE_ACTIVE_SPATIALIZER_TRACKS;
+ ALOGV("AudioCommandThread() adding update active spatializer tracks");
+ sendCommand(command);
+}
+
status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
{
{
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 0a01b7b..43b579f 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -134,10 +134,8 @@
int32_t* _aidl_return) override;
binder::Status getStrategyForStream(AudioStreamType stream,
int32_t* _aidl_return) override;
- binder::Status getDevicesForStream(
- AudioStreamType stream,
- std::vector<AudioDeviceDescription>* _aidl_return) override;
binder::Status getDevicesForAttributes(const media::AudioAttributesEx& attr,
+ bool forVolume,
std::vector<AudioDevice>* _aidl_return) override;
binder::Status getOutputForEffect(const media::EffectDescriptor& desc,
int32_t* _aidl_return) override;
@@ -352,9 +350,13 @@
* by audio policy manager and attach/detach the spatializer effect accordingly.
*/
void onCheckSpatializer() override;
- void onCheckSpatializer_l();
+ void onCheckSpatializer_l() REQUIRES(mLock);
void doOnCheckSpatializer();
+ void onUpdateActiveSpatializerTracks_l() REQUIRES(mLock);
+ void doOnUpdateActiveSpatializerTracks();
+
+
void setEffectSuspended(int effectId,
audio_session_t sessionId,
bool suspended);
@@ -526,7 +528,8 @@
AUDIO_MODULES_UPDATE,
ROUTING_UPDATED,
UPDATE_UID_STATES,
- CHECK_SPATIALIZER
+ CHECK_SPATIALIZER_OUTPUT, // verify if spatializer effect should be created or moved
+ UPDATE_ACTIVE_SPATIALIZER_TRACKS // Update active track counts on spalializer output
};
AudioCommandThread (String8 name, const wp<AudioPolicyService>& service);
@@ -576,6 +579,8 @@
void routingChangedCommand();
void updateUidStatesCommand();
void checkSpatializerCommand();
+ void updateActiveSpatializerTracksCommand();
+
void insertCommand_l(AudioCommand *command, int delayMs = 0);
private:
class AudioCommandData;
@@ -1000,6 +1005,8 @@
void loadAudioPolicyManager();
void unloadAudioPolicyManager();
+ size_t countActiveClientsOnOutput_l(audio_io_handle_t output) REQUIRES(mLock);
+
mutable Mutex mLock; // prevents concurrent access to AudioPolicy manager functions changing
// device connection state or routing
// Note: lock acquisition order is always mLock > mEffectsLock:
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 54d9094..d9e89aa 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -300,6 +300,7 @@
if (levelChanged && mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_LEVEL, std::vector<SpatializationLevel>{level});
}
+ checkHeadSensor_l();
}
if (levelChanged) {
@@ -374,6 +375,7 @@
if (mPoseController != nullptr) {
mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
+ checkHeadSensor_l();
}
return Status::ok();
@@ -448,7 +450,7 @@
std::lock_guard lock(mLock);
mHeadSensor = sensorHandle;
if (mPoseController != nullptr) {
- mPoseController->setHeadSensor(mHeadSensor);
+ checkHeadSensor_l();
}
return Status::ok();
}
@@ -557,7 +559,6 @@
auto vec = headToStage.toVector();
LOG_ALWAYS_FATAL_IF(vec.size() != sHeadPoseKeys.size(),
"%s invalid head to stage vector size %zu", __func__, vec.size());
-
sp<AMessage> msg =
new AMessage(EngineCallbackHandler::kWhatOnHeadToStagePose, mHandler);
for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) {
@@ -571,6 +572,9 @@
sp<media::ISpatializerHeadTrackingCallback> callback;
{
std::lock_guard lock(mLock);
+ if (mActualHeadTrackingMode == SpatializerHeadTrackingMode::DISABLED) {
+ return;
+ }
callback = mHeadTrackingCallback;
if (mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
@@ -621,7 +625,7 @@
}
}
-status_t Spatializer::attachOutput(audio_io_handle_t output) {
+status_t Spatializer::attachOutput(audio_io_handle_t output, size_t numActiveTracks) {
std::shared_ptr<SpatializerPoseController> poseController;
bool outputChanged = false;
sp<media::INativeSpatializerCallback> callback;
@@ -634,6 +638,7 @@
// remove FX instance
mEngine->setEnabled(false);
mEngine.clear();
+ mPoseController.reset();
}
// create FX instance on output
AttributionSourceState attributionSource = AttributionSourceState();
@@ -663,7 +668,8 @@
"%s could not allocate pose controller", __func__);
mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
- mPoseController->setHeadSensor(mHeadSensor);
+ mNumActiveTracks = numActiveTracks;
+ checkHeadSensor_l();
mPoseController->setScreenSensor(mScreenSensor);
mPoseController->setDisplayOrientation(mDisplayOrientation);
poseController = mPoseController;
@@ -697,7 +703,6 @@
output = mOutput;
mOutput = AUDIO_IO_HANDLE_NONE;
mPoseController.reset();
-
callback = mSpatializerCallback;
}
@@ -707,6 +712,24 @@
return output;
}
+void Spatializer::updateActiveTracks(size_t numActiveTracks) {
+ std::lock_guard lock(mLock);
+ mNumActiveTracks = numActiveTracks;
+ checkHeadSensor_l();
+}
+
+void Spatializer::checkHeadSensor_l() {
+ if (mSupportsHeadTracking && mPoseController != nullptr) {
+ if(mNumActiveTracks > 0 && mLevel != SpatializationLevel::NONE
+ && mDesiredHeadTrackingMode != HeadTrackingMode::STATIC
+ && mHeadSensor != SpatializerPoseController::INVALID_SENSOR) {
+ mPoseController->setHeadSensor(mHeadSensor);
+ } else {
+ mPoseController->setHeadSensor(SpatializerPoseController::INVALID_SENSOR);
+ }
+ }
+}
+
void Spatializer::calculateHeadPose() {
ALOGV("%s", __func__);
std::lock_guard lock(mLock);
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index 4d77b78..4ce99d8 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -135,7 +135,7 @@
/** Called by audio policy service when the special output mixer dedicated to spatialization
* is opened and the spatializer engine must be created.
*/
- status_t attachOutput(audio_io_handle_t output);
+ status_t attachOutput(audio_io_handle_t output, size_t numActiveTracks);
/** Called by audio policy service when the special output mixer dedicated to spatialization
* is closed and the spatializer engine must be release.
*/
@@ -143,6 +143,8 @@
/** Returns the output stream the spatializer is attached to. */
audio_io_handle_t getOutput() const { std::lock_guard lock(mLock); return mOutput; }
+ void updateActiveTracks(size_t numActiveTracks);
+
/** Gets the channel mask, sampling rate and format set for the spatializer input. */
audio_config_base_t getAudioInConfig() const;
@@ -274,6 +276,8 @@
void postFramesProcessedMsg(int frames);
+ void checkHeadSensor_l() REQUIRES(mLock);
+
/** Effect engine descriptor */
const effect_descriptor_t mEngineDescriptor;
/** Callback interface to parent audio policy service */
@@ -328,6 +332,8 @@
sp<ALooper> mLooper;
sp<EngineCallbackHandler> mHandler;
+ size_t mNumActiveTracks GUARDED_BY(mLock) = 0;
+
static const std::vector<const char *> sHeadPoseKeys;
};
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index b61bc09..69300be 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -105,6 +105,8 @@
],
header_libs: [
+ "libdynamic_depth-internal_headers",
+ "libdynamic_depth-public_headers",
"libmediadrm_headers",
"libmediametrics_headers",
],
@@ -185,8 +187,6 @@
include_dirs: [
"system/media/private/camera/include",
"frameworks/native/include/media/openmax",
- "external/dynamic_depth/includes",
- "external/dynamic_depth/internal",
],
export_include_dirs: ["."],
@@ -216,6 +216,11 @@
"utils/SessionConfigurationUtilsHost.cpp",
],
+ header_libs: [
+ "libdynamic_depth-internal_headers",
+ "libdynamic_depth-public_headers",
+ ],
+
shared_libs: [
"libbase",
"libbinder",
@@ -229,8 +234,6 @@
],
include_dirs: [
- "external/dynamic_depth/includes",
- "external/dynamic_depth/internal",
"frameworks/av/camera/include",
"frameworks/av/camera/include/camera",
],
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 0ba1b28..c576162 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2139,10 +2139,14 @@
id.string());
errorCode = ERROR_CAMERA_IN_USE;
break;
+ case -EINVAL:
+ msg = String8::format("Torch strength level %d is not within the "
+ "valid range.", torchStrength);
+ errorCode = ERROR_ILLEGAL_ARGUMENT;
+ break;
default:
msg = String8::format("Changing torch strength level failed.");
errorCode = ERROR_INVALID_OPERATION;
-
}
ALOGE("%s: %s", __FUNCTION__, msg.string());
return STATUS_ERROR(errorCode, msg.string());
diff --git a/services/mediametrics/AudioAnalytics.cpp b/services/mediametrics/AudioAnalytics.cpp
index ade54d0..aacc2be 100644
--- a/services/mediametrics/AudioAnalytics.cpp
+++ b/services/mediametrics/AudioAnalytics.cpp
@@ -1246,10 +1246,10 @@
if (channelMask != 0) {
switch (direction) {
case 1: // Output, keep sync with AudioTypes#getAAudioDirection()
- channelCount = audio_channel_count_from_out_mask(channelMask);
+ channelCount = (int32_t)audio_channel_count_from_out_mask(channelMask);
break;
case 2: // Input, keep sync with AudioTypes#getAAudioDirection()
- channelCount = audio_channel_count_from_in_mask(channelMask);
+ channelCount = (int32_t)audio_channel_count_from_in_mask(channelMask);
break;
default:
ALOGW("Invalid direction %d", direction);
diff --git a/services/mediametrics/statsd_drm.cpp b/services/mediametrics/statsd_drm.cpp
index 287fb8d..e06a605 100644
--- a/services/mediametrics/statsd_drm.cpp
+++ b/services/mediametrics/statsd_drm.cpp
@@ -171,7 +171,7 @@
std::vector<uint8_t> buf(str.length() / 4 * 3, 0);
size_t size = buf.size();
if (decodeBase64(buf.data(), &size, str.c_str()) && size <= buf.size()) {
- buf.erase(buf.begin() + size, buf.end());
+ buf.erase(buf.begin() + (ptrdiff_t)size, buf.end());
return buf;
}
return {};