summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-07-20 00:32:02 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-07-20 00:32:02 +0000
commitb511459ef16a74f35c534ee5f7767f59adb49742 (patch)
treeb34bdf7674975e2b8897b732dc59a469c4ce8569
parent5be288e24aeb2ff800912b0d2636754d007e23b4 (diff)
parent402ffe42673186ad25705120919928f2bd27f9b8 (diff)
downloadav-oreo-m6-s3-release.tar.gz
Merge cherrypicks of [4586293, 4586294, 4586295, 4584365, 4584366, 4584367, 4584368, 4584369, 4584370, 4587544, 4584705, 4586296, 4587545, 4587546, 4586297, 4586298, 4586299, 4586300, 4584371, 4586301, 4584706, 4586302, 4586303, 4587584, 4587585, 4587586, 4587587, 4587588, 4587589, 4587590, 4587591, 4587644, 4587645, 4587646, 4587647, 4587648, 4587649, 4587650, 4587651, 4587652, 4587653, 4587654, 4587655, 4587656, 4587657, 4587658, 4587659, 4587660, 4587661, 4587662, 4584536, 4587547, 4587548, 4587549, 4584707, 4584708, 4587550, 4587551, 4587593, 4586516, 4584372, 4584373, 4584374, 4587595, 4584375, 4584376, 4587552, 4587596, 4587597, 4587598, 4587599, 4584414, 4584415, 4584416, 4584417, 4584418, 4584419, 4584420, 4584421, 4584422, 4584423, 4587804, 4587805, 4587806, 4587807, 4587808, 4587809, 4587810, 4587811, 4587812, 4587813, 4587814, 4587815, 4587816, 4587817, 4587818, 4587884, 4587885, 4587600, 4587601, 4587819, 4584709] into sparse-4749909-L91900000192339903android-8.1.0_r43oreo-m6-s3-release
Change-Id: Ia953910fe5f01eeb7081984e035a15b3f2e0fd92
-rw-r--r--drm/libmediadrm/CryptoHal.cpp25
-rw-r--r--media/libaudioclient/IAudioPolicyService.cpp65
-rw-r--r--media/libaudioclient/include/media/IAudioPolicyService.h2
-rw-r--r--media/libmedia/include/media/CryptoHal.h15
-rw-r--r--media/libstagefright/ItemTable.cpp3
-rw-r--r--media/libstagefright/VideoFrameScheduler.cpp5
-rw-r--r--media/libstagefright/id3/ID3.cpp24
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp79
-rw-r--r--services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp1
-rw-r--r--services/oboeservice/AAudioServiceEndpoint.h4
-rw-r--r--services/oboeservice/AAudioServiceStreamBase.cpp57
-rw-r--r--services/oboeservice/AAudioServiceStreamBase.h5
-rw-r--r--services/oboeservice/AAudioServiceStreamMMAP.cpp55
-rw-r--r--services/oboeservice/AAudioServiceStreamShared.cpp29
14 files changed, 280 insertions, 89 deletions
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 1fdc6e1954..5dd25639ca 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -240,11 +240,12 @@ int32_t CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) {
Mutex::Autolock autoLock(mLock);
int32_t seqNum = mHeapSeqNum++;
+
int fd = heap->getHeapID();
nativeHandle->data[0] = fd;
auto hidlHandle = hidl_handle(nativeHandle);
auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize());
- mHeapBases.add(seqNum, mNextBufferId);
+ mHeapBases.add(seqNum, HeapBase(mNextBufferId, heap->getSize()));
Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++);
ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
return seqNum;
@@ -269,10 +270,26 @@ status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::
return UNEXPECTED_NULL;
}
- // memory must be in the declared heap
- CHECK(mHeapBases.indexOfKey(seqNum) >= 0);
+ // memory must be in one of the heaps that have been set
+ if (mHeapBases.indexOfKey(seqNum) < 0) {
+ return UNKNOWN_ERROR;
+ }
+
+ // heap must be the same size as the one that was set in setHeapBase
+ if (mHeapBases.valueFor(seqNum).getSize() != heap->getSize()) {
+ android_errorWriteLog(0x534e4554, "76221123");
+ return UNKNOWN_ERROR;
+ }
+
+ // memory must be within the address space of the heap
+ if (memory->pointer() != static_cast<uint8_t *>(heap->getBase()) + memory->offset() ||
+ heap->getSize() < memory->offset() + memory->size() ||
+ SIZE_MAX - memory->offset() < memory->size()) {
+ android_errorWriteLog(0x534e4554, "76221123");
+ return UNKNOWN_ERROR;
+ }
- buffer->bufferId = mHeapBases.valueFor(seqNum);
+ buffer->bufferId = mHeapBases.valueFor(seqNum).getBufferId();
buffer->offset = offset >= 0 ? offset : 0;
buffer->size = size;
return OK;
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index d838975fba..f071a020b1 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -940,7 +940,7 @@ status_t BnAudioPolicyService::onTransact(
audio_output_flags_t flags =
static_cast <audio_output_flags_t>(data.readInt32());
bool hasOffloadInfo = data.readInt32() != 0;
- audio_offload_info_t offloadInfo;
+ audio_offload_info_t offloadInfo = {};
if (hasOffloadInfo) {
data.read(&offloadInfo, sizeof(audio_offload_info_t));
}
@@ -956,7 +956,7 @@ status_t BnAudioPolicyService::onTransact(
case GET_OUTPUT_FOR_ATTR: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_attributes_t attr;
+ audio_attributes_t attr = {};
bool hasAttributes = data.readInt32() != 0;
if (hasAttributes) {
data.read(&attr, sizeof(audio_attributes_t));
@@ -1024,7 +1024,7 @@ status_t BnAudioPolicyService::onTransact(
case GET_INPUT_FOR_ATTR: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_attributes_t attr;
+ audio_attributes_t attr = {};
data.read(&attr, sizeof(audio_attributes_t));
sanetizeAudioAttributes(&attr);
audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
@@ -1125,8 +1125,11 @@ status_t BnAudioPolicyService::onTransact(
case GET_OUTPUT_FOR_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- effect_descriptor_t desc;
- data.read(&desc, sizeof(effect_descriptor_t));
+ effect_descriptor_t desc = {};
+ if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
+ android_errorWriteLog(0x534e4554, "73126106");
+ }
+ (void)sanitizeEffectDescriptor(&desc);
audio_io_handle_t output = getOutputForEffect(&desc);
reply->writeInt32(static_cast <int>(output));
return NO_ERROR;
@@ -1134,8 +1137,11 @@ status_t BnAudioPolicyService::onTransact(
case REGISTER_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- effect_descriptor_t desc;
- data.read(&desc, sizeof(effect_descriptor_t));
+ effect_descriptor_t desc = {};
+ if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
+ android_errorWriteLog(0x534e4554, "73126106");
+ }
+ (void)sanitizeEffectDescriptor(&desc);
audio_io_handle_t io = data.readInt32();
uint32_t strategy = data.readInt32();
audio_session_t session = (audio_session_t) data.readInt32();
@@ -1194,7 +1200,7 @@ status_t BnAudioPolicyService::onTransact(
count = AudioEffect::kMaxPreProcessing;
}
uint32_t retCount = count;
- effect_descriptor_t *descriptors = new effect_descriptor_t[count];
+ effect_descriptor_t *descriptors = new effect_descriptor_t[count]{};
status_t status = queryDefaultPreProcessing(audioSession, descriptors, &retCount);
reply->writeInt32(status);
if (status != NO_ERROR && status != NO_MEMORY) {
@@ -1213,7 +1219,7 @@ status_t BnAudioPolicyService::onTransact(
case IS_OFFLOAD_SUPPORTED: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_offload_info_t info;
+ audio_offload_info_t info = {};
data.read(&info, sizeof(audio_offload_info_t));
bool isSupported = isOffloadSupported(info);
reply->writeInt32(isSupported);
@@ -1268,7 +1274,7 @@ status_t BnAudioPolicyService::onTransact(
case CREATE_AUDIO_PATCH: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_patch patch;
+ struct audio_patch patch = {};
data.read(&patch, sizeof(struct audio_patch));
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
@@ -1284,7 +1290,7 @@ status_t BnAudioPolicyService::onTransact(
case RELEASE_AUDIO_PATCH: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_patch_handle_t handle;
+ audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
data.read(&handle, sizeof(audio_patch_handle_t));
status_t status = releaseAudioPatch(handle);
reply->writeInt32(status);
@@ -1323,8 +1329,9 @@ status_t BnAudioPolicyService::onTransact(
case SET_AUDIO_PORT_CONFIG: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_port_config config;
+ struct audio_port_config config = {};
data.read(&config, sizeof(struct audio_port_config));
+ (void)sanitizeAudioPortConfig(&config);
status_t status = setAudioPortConfig(&config);
reply->writeInt32(status);
return NO_ERROR;
@@ -1398,9 +1405,10 @@ status_t BnAudioPolicyService::onTransact(
case START_AUDIO_SOURCE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_port_config source;
+ struct audio_port_config source = {};
data.read(&source, sizeof(struct audio_port_config));
- audio_attributes_t attributes;
+ (void)sanitizeAudioPortConfig(&source);
+ audio_attributes_t attributes = {};
data.read(&attributes, sizeof(audio_attributes_t));
sanetizeAudioAttributes(&attributes);
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
@@ -1453,6 +1461,14 @@ status_t BnAudioPolicyService::onTransact(
}
}
+/** returns true if string overflow was prevented by zero termination */
+template <size_t size>
+static bool preventStringOverflow(char (&s)[size]) {
+ if (strnlen(s, size) < size) return false;
+ s[size - 1] = '\0';
+ return true;
+}
+
void BnAudioPolicyService::sanetizeAudioAttributes(audio_attributes_t* attr)
{
const size_t tagsMaxSize = AUDIO_ATTRIBUTES_TAGS_MAX_SIZE;
@@ -1462,6 +1478,27 @@ void BnAudioPolicyService::sanetizeAudioAttributes(audio_attributes_t* attr)
attr->tags[tagsMaxSize - 1] = '\0';
}
+/** returns BAD_VALUE if sanitization was required. */
+status_t BnAudioPolicyService::sanitizeEffectDescriptor(effect_descriptor_t* desc)
+{
+ if (preventStringOverflow(desc->name)
+ | /* always */ preventStringOverflow(desc->implementor)) {
+ android_errorWriteLog(0x534e4554, "73126106"); // SafetyNet logging
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+/** returns BAD_VALUE if sanitization was required. */
+status_t BnAudioPolicyService::sanitizeAudioPortConfig(struct audio_port_config* config)
+{
+ if (config->type == AUDIO_PORT_TYPE_DEVICE &&
+ preventStringOverflow(config->ext.device.address)) {
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
} // namespace android
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 60ba4ba28b..eec3e881da 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -185,6 +185,8 @@ public:
uint32_t flags = 0);
private:
void sanetizeAudioAttributes(audio_attributes_t* attr);
+ status_t sanitizeEffectDescriptor(effect_descriptor_t* desc);
+ status_t sanitizeAudioPortConfig(struct audio_port_config* config);
};
// ----------------------------------------------------------------------------
diff --git a/media/libmedia/include/media/CryptoHal.h b/media/libmedia/include/media/CryptoHal.h
index a5d8b43aec..80e181e57b 100644
--- a/media/libmedia/include/media/CryptoHal.h
+++ b/media/libmedia/include/media/CryptoHal.h
@@ -79,7 +79,20 @@ private:
*/
status_t mInitCheck;
- KeyedVector<int32_t, uint32_t> mHeapBases;
+ struct HeapBase {
+ HeapBase() : mBufferId(0), mSize(0) {}
+ HeapBase(uint32_t bufferId, size_t size) :
+ mBufferId(bufferId), mSize(size) {}
+
+ uint32_t getBufferId() const {return mBufferId;}
+ size_t getSize() const {return mSize;}
+
+ private:
+ uint32_t mBufferId;
+ size_t mSize;
+ };
+
+ KeyedVector<int32_t, HeapBase> mHeapBases;
uint32_t mNextBufferId;
int32_t mHeapSeqNum;
diff --git a/media/libstagefright/ItemTable.cpp b/media/libstagefright/ItemTable.cpp
index f9ee1c497a..f589f4f263 100644
--- a/media/libstagefright/ItemTable.cpp
+++ b/media/libstagefright/ItemTable.cpp
@@ -1335,7 +1335,8 @@ status_t ItemTable::buildImageItemsIfPossible(uint32_t type) {
ALOGV("adding %s: itemId %d", image.isGrid() ? "grid" : "image", info.itemId);
if (image.isGrid()) {
- if (size > 12) {
+ // ImageGrid struct is at least 8-byte, at most 12-byte (if flags&1)
+ if (size < 8 || size > 12) {
return ERROR_MALFORMED;
}
uint8_t buf[12];
diff --git a/media/libstagefright/VideoFrameScheduler.cpp b/media/libstagefright/VideoFrameScheduler.cpp
index 03226c753e..6819bba40c 100644
--- a/media/libstagefright/VideoFrameScheduler.cpp
+++ b/media/libstagefright/VideoFrameScheduler.cpp
@@ -129,6 +129,11 @@ bool VideoFrameScheduler::PLL::fit(
numSamplesToUse = mNumSamples;
}
+ if ((period >> kPrecision) == 0 ) {
+ ALOGW("Period is 0, or after including precision is 0 - would cause div0, returning");
+ return false;
+ }
+
int64_t sumX = 0;
int64_t sumXX = 0;
int64_t sumXY = 0;
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 58d8b13796..a0bfd06bf6 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -328,12 +328,25 @@ struct id3_header {
}
void ID3::removeUnsynchronization() {
- for (size_t i = 0; i + 1 < mSize; ++i) {
- if (mData[i] == 0xff && mData[i + 1] == 0x00) {
- memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2);
- --mSize;
+
+ // This file has "unsynchronization", so we have to replace occurrences
+ // of 0xff 0x00 with just 0xff in order to get the real data.
+
+ size_t writeOffset = 1;
+ for (size_t readOffset = 1; readOffset < mSize; ++readOffset) {
+ if (mData[readOffset - 1] == 0xff && mData[readOffset] == 0x00) {
+ continue;
}
+ // Only move data if there's actually something to move.
+ // This handles the special case of the data being only [0xff, 0x00]
+ // which should be converted to just 0xff if unsynchronization is on.
+ mData[writeOffset++] = mData[readOffset];
+ }
+
+ if (writeOffset < mSize) {
+ mSize = writeOffset;
}
+
}
static void WriteSyncsafeInteger(uint8_t *dst, size_t x) {
@@ -593,6 +606,9 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
// UCS-2
// API wants number of characters, not number of bytes...
int len = n / 2;
+ if (len == 0) {
+ return;
+ }
const char16_t *framedata = (const char16_t *) (frameData + 1);
char16_t *framedatacopy = NULL;
if (*framedata == 0xfffe) {
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 015a14878a..a9fbd71b3c 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -686,6 +686,7 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
CLOG_CONFIG(setPortMode, "%s(%d), port %d", asString(mode), mode, portIndex);
+ status_t err = OK;
switch (mode) {
case IOMX::kPortModeDynamicANWBuffer:
{
@@ -694,17 +695,19 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
"not setting port mode to %s(%d) on output",
asString(mode), mode);
- return StatusFromOMXError(OMX_ErrorUnsupportedIndex);
+ err = StatusFromOMXError(OMX_ErrorUnsupportedIndex);
+ break;
}
- status_t err = enableNativeBuffers_l(
+ err = enableNativeBuffers_l(
portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
if (err != OK) {
- return err;
+ break;
}
}
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
- return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
+ err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
+ break;
}
case IOMX::kPortModeDynamicNativeHandle:
@@ -712,13 +715,15 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
if (portIndex != kPortIndexInput) {
CLOG_ERROR(setPortMode, BAD_VALUE,
"%s(%d) mode is only supported on input port", asString(mode), mode);
- return BAD_VALUE;
+ err = BAD_VALUE;
+ break;
}
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
MetadataBufferType metaType = kMetadataBufferTypeNativeHandleSource;
- return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
+ err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
+ break;
}
case IOMX::kPortModePresetSecureBuffer:
@@ -726,7 +731,8 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
// Allow on both input and output.
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
- return enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
+ err = enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
+ break;
}
case IOMX::kPortModePresetANWBuffer:
@@ -734,7 +740,8 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
if (portIndex != kPortIndexOutput) {
CLOG_ERROR(setPortMode, BAD_VALUE,
"%s(%d) mode is only supported on output port", asString(mode), mode);
- return BAD_VALUE;
+ err = BAD_VALUE;
+ break;
}
// Check if we're simulating legacy mode with metadata mode,
@@ -743,7 +750,7 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
if (storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL) == OK) {
CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
"metdata mode enabled successfully");
- return OK;
+ break;
}
CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
@@ -754,15 +761,15 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
// Disable secure buffer and enable graphic buffer
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
- status_t err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
+ err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
if (err != OK) {
- return err;
+ break;
}
// Not running experiment, or metadata is not supported.
// Disable metadata mode and use legacy mode.
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
- return OK;
+ break;
}
case IOMX::kPortModePresetByteBuffer:
@@ -771,15 +778,19 @@ status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
- return OK;
+ break;
}
default:
+ CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
+ err = BAD_VALUE;
break;
}
- CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
- return BAD_VALUE;
+ if (err == OK) {
+ mPortMode[portIndex] = mode;
+ }
+ return err;
}
status_t OMXNodeInstance::enableNativeBuffers_l(
@@ -1057,28 +1068,51 @@ status_t OMXNodeInstance::useBuffer(
}
switch (omxBuffer.mBufferType) {
- case OMXBuffer::kBufferTypePreset:
+ case OMXBuffer::kBufferTypePreset: {
+ if (mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicNativeHandle) {
+ break;
+ }
return useBuffer_l(portIndex, NULL, NULL, buffer);
+ }
- case OMXBuffer::kBufferTypeSharedMem:
+ case OMXBuffer::kBufferTypeSharedMem: {
+ if (mPortMode[portIndex] != IOMX::kPortModePresetByteBuffer
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer) {
+ break;
+ }
return useBuffer_l(portIndex, omxBuffer.mMem, NULL, buffer);
+ }
- case OMXBuffer::kBufferTypeANWBuffer:
+ case OMXBuffer::kBufferTypeANWBuffer: {
+ if (mPortMode[portIndex] != IOMX::kPortModePresetANWBuffer) {
+ break;
+ }
return useGraphicBuffer_l(portIndex, omxBuffer.mGraphicBuffer, buffer);
+ }
case OMXBuffer::kBufferTypeHidlMemory: {
+ if (mPortMode[portIndex] != IOMX::kPortModePresetByteBuffer
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicNativeHandle) {
+ break;
+ }
sp<IHidlMemory> hidlMemory = mapMemory(omxBuffer.mHidlMemory);
if (hidlMemory == nullptr) {
ALOGE("OMXNodeInstance useBuffer() failed to map memory");
return NO_MEMORY;
}
return useBuffer_l(portIndex, NULL, hidlMemory, buffer);
- }
+ }
default:
+ return BAD_VALUE;
break;
}
- return BAD_VALUE;
+ ALOGE("b/77486542 : bufferType = %d vs. portMode = %d",
+ omxBuffer.mBufferType, mPortMode[portIndex]);
+ android_errorWriteLog(0x534e4554, "77486542");
+ return INVALID_OPERATION;
}
status_t OMXNodeInstance::useBuffer_l(
@@ -1514,6 +1548,11 @@ status_t OMXNodeInstance::allocateSecureBuffer(
android_errorWriteLog(0x534e4554, "35467458");
return BAD_VALUE;
}
+ if (mPortMode[portIndex] != IOMX::kPortModePresetSecureBuffer) {
+ ALOGE("b/77486542");
+ android_errorWriteLog(0x534e4554, "77486542");
+ return INVALID_OPERATION;
+ }
BufferMeta *buffer_meta = new BufferMeta(portIndex);
OMX_BUFFERHEADERTYPE *header;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index fcf9070394..cdaffe79fc 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -385,6 +385,7 @@ AudioPortConfig::AudioPortConfig()
mSamplingRate = 0;
mChannelMask = AUDIO_CHANNEL_NONE;
mFormat = AUDIO_FORMAT_INVALID;
+ memset(&mGain, 0, sizeof(struct audio_gain_config));
mGain.index = -1;
}
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 2ef623464d..c19cc3547f 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -49,9 +49,9 @@ public:
virtual aaudio_result_t close() = 0;
- virtual aaudio_result_t registerStream(android::sp<AAudioServiceStreamBase> stream);
+ aaudio_result_t registerStream(android::sp<AAudioServiceStreamBase> stream);
- virtual aaudio_result_t unregisterStream(android::sp<AAudioServiceStreamBase> stream);
+ aaudio_result_t unregisterStream(android::sp<AAudioServiceStreamBase> stream);
virtual aaudio_result_t startStream(android::sp<AAudioServiceStreamBase> stream,
audio_port_handle_t *clientHandle) = 0;
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index ff0b037e52..d9b87666d4 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -104,6 +104,9 @@ aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest
goto error;
}
+ // This is not protected by a lock because the stream cannot be
+ // referenced until the service returns a handle to the client.
+ // So only one thread can open a stream.
mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService,
request,
sharingMode);
@@ -112,6 +115,9 @@ aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest
result = AAUDIO_ERROR_UNAVAILABLE;
goto error;
}
+ // Save a weak pointer that we will use to access the endpoint.
+ mServiceEndpointWeak = mServiceEndpoint;
+
mFramesPerBurst = mServiceEndpoint->getFramesPerBurst();
copyFrom(*mServiceEndpoint);
}
@@ -130,15 +136,19 @@ aaudio_result_t AAudioServiceStreamBase::close() {
stop();
- if (mServiceEndpoint == nullptr) {
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
result = AAUDIO_ERROR_INVALID_STATE;
} else {
- mServiceEndpoint->unregisterStream(this);
- AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
- mEndpointManager.closeEndpoint(mServiceEndpoint);
- mServiceEndpoint.clear();
+ endpoint->unregisterStream(this);
+ AAudioEndpointManager &endpointManager = AAudioEndpointManager::getInstance();
+ endpointManager.closeEndpoint(endpoint);
+
+ // AAudioService::closeStream() prevents two threads from closing at the same time.
+ mServiceEndpoint.clear(); // endpoint will hold the pointer until this method returns.
}
+
{
std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
stopTimestampThread();
@@ -152,7 +162,12 @@ aaudio_result_t AAudioServiceStreamBase::close() {
aaudio_result_t AAudioServiceStreamBase::startDevice() {
mClientHandle = AUDIO_PORT_HANDLE_NONE;
- return mServiceEndpoint->startStream(this, &mClientHandle);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ return endpoint->startStream(this, &mClientHandle);
}
/**
@@ -162,16 +177,11 @@ aaudio_result_t AAudioServiceStreamBase::startDevice() {
*/
aaudio_result_t AAudioServiceStreamBase::start() {
aaudio_result_t result = AAUDIO_OK;
+
if (isRunning()) {
return AAUDIO_OK;
}
- if (mServiceEndpoint == nullptr) {
- ALOGE("AAudioServiceStreamBase::start() missing endpoint");
- result = AAUDIO_ERROR_INVALID_STATE;
- goto error;
- }
-
// Start with fresh presentation timestamps.
mAtomicTimestamp.clear();
@@ -198,10 +208,6 @@ aaudio_result_t AAudioServiceStreamBase::pause() {
if (!isRunning()) {
return result;
}
- if (mServiceEndpoint == nullptr) {
- ALOGE("AAudioServiceStreamShared::pause() missing endpoint");
- return AAUDIO_ERROR_INVALID_STATE;
- }
// Send it now because the timestamp gets rounded up when stopStream() is called below.
// Also we don't need the timestamps while we are shutting down.
@@ -213,7 +219,12 @@ aaudio_result_t AAudioServiceStreamBase::pause() {
return result;
}
- result = mServiceEndpoint->stopStream(this, mClientHandle);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ result = endpoint->stopStream(this, mClientHandle);
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::pause() mServiceEndpoint returned %d", result);
disconnect(); // TODO should we return or pause Base first?
@@ -230,11 +241,6 @@ aaudio_result_t AAudioServiceStreamBase::stop() {
return result;
}
- if (mServiceEndpoint == nullptr) {
- ALOGE("AAudioServiceStreamShared::stop() missing endpoint");
- return AAUDIO_ERROR_INVALID_STATE;
- }
-
// Send it now because the timestamp gets rounded up when stopStream() is called below.
// Also we don't need the timestamps while we are shutting down.
sendCurrentTimestamp(); // warning - this calls a virtual function
@@ -244,8 +250,13 @@ aaudio_result_t AAudioServiceStreamBase::stop() {
return result;
}
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
// TODO wait for data to be played out
- result = mServiceEndpoint->stopStream(this, mClientHandle);
+ result = endpoint->stopStream(this, mClientHandle);
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::stop() mServiceEndpoint returned %d", result);
disconnect();
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index af435b4b8f..815b1ccf7b 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -233,7 +233,12 @@ protected:
SimpleDoubleBuffer<Timestamp> mAtomicTimestamp;
android::AAudioService &mAudioService;
+
+ // The mServiceEndpoint variable can be accessed by multiple threads.
+ // So we access it by locally promoting a weak pointer to a smart pointer,
+ // which is thread-safe.
android::sp<AAudioServiceEndpoint> mServiceEndpoint;
+ android::wp<AAudioServiceEndpoint> mServiceEndpointWeak;
private:
aaudio_handle_t mHandle = -1;
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index 44ba1ca8d8..2e7ff8b262 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -70,14 +70,19 @@ aaudio_result_t AAudioServiceStreamMMAP::open(const aaudio::AAudioStreamRequest
return result;
}
- result = mServiceEndpoint->registerStream(keep);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+
+ result = endpoint->registerStream(keep);
if (result != AAUDIO_OK) {
- goto error;
+ return result;
}
setState(AAUDIO_STREAM_STATE_OPEN);
-error:
return AAUDIO_OK;
}
@@ -122,21 +127,37 @@ aaudio_result_t AAudioServiceStreamMMAP::stop() {
aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client,
audio_port_handle_t *clientHandle) {
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
// Start the client on behalf of the application. Generate a new porthandle.
- aaudio_result_t result = mServiceEndpoint->startClient(client, clientHandle);
+ aaudio_result_t result = endpoint->startClient(client, clientHandle);
return result;
}
aaudio_result_t AAudioServiceStreamMMAP::stopClient(audio_port_handle_t clientHandle) {
- aaudio_result_t result = mServiceEndpoint->stopClient(clientHandle);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ aaudio_result_t result = endpoint->stopClient(clientHandle);
return result;
}
// Get free-running DSP or DMA hardware position from the HAL.
aaudio_result_t AAudioServiceStreamMMAP::getFreeRunningPosition(int64_t *positionFrames,
int64_t *timeNanos) {
- sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
- static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
+ static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
+
aaudio_result_t result = serviceEndpointMMAP->getFreeRunningPosition(positionFrames, timeNanos);
if (result == AAUDIO_OK) {
Timestamp timestamp(*positionFrames, *timeNanos);
@@ -152,8 +173,15 @@ aaudio_result_t AAudioServiceStreamMMAP::getFreeRunningPosition(int64_t *positio
// Get timestamp that was written by getFreeRunningPosition()
aaudio_result_t AAudioServiceStreamMMAP::getHardwareTimestamp(int64_t *positionFrames,
int64_t *timeNanos) {
- sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
- static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
+
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
+ static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
+
// TODO Get presentation timestamp from the HAL
if (mAtomicTimestamp.isValid()) {
Timestamp timestamp = mAtomicTimestamp.read();
@@ -171,7 +199,12 @@ aaudio_result_t AAudioServiceStreamMMAP::getHardwareTimestamp(int64_t *positionF
aaudio_result_t AAudioServiceStreamMMAP::getAudioDataDescription(
AudioEndpointParcelable &parcelable)
{
- sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
- static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
+ static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
return serviceEndpointMMAP->getDownDataDescription(parcelable);
}
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 084f996cd6..f55c40d0ee 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -128,6 +128,11 @@ aaudio_result_t AAudioServiceStreamShared::open(const aaudio::AAudioStreamReques
const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ result = AAUDIO_ERROR_INVALID_STATE;
+ goto error;
+ }
// Is the request compatible with the shared endpoint?
setFormat(configurationInput.getFormat());
@@ -141,20 +146,20 @@ aaudio_result_t AAudioServiceStreamShared::open(const aaudio::AAudioStreamReques
setSampleRate(configurationInput.getSampleRate());
if (getSampleRate() == AAUDIO_UNSPECIFIED) {
- setSampleRate(mServiceEndpoint->getSampleRate());
- } else if (getSampleRate() != mServiceEndpoint->getSampleRate()) {
+ setSampleRate(endpoint->getSampleRate());
+ } else if (getSampleRate() != endpoint->getSampleRate()) {
ALOGE("AAudioServiceStreamShared::open() mSampleRate = %d, need %d",
- getSampleRate(), mServiceEndpoint->getSampleRate());
+ getSampleRate(), endpoint->getSampleRate());
result = AAUDIO_ERROR_INVALID_RATE;
goto error;
}
setSamplesPerFrame(configurationInput.getSamplesPerFrame());
if (getSamplesPerFrame() == AAUDIO_UNSPECIFIED) {
- setSamplesPerFrame(mServiceEndpoint->getSamplesPerFrame());
- } else if (getSamplesPerFrame() != mServiceEndpoint->getSamplesPerFrame()) {
+ setSamplesPerFrame(endpoint->getSamplesPerFrame());
+ } else if (getSamplesPerFrame() != endpoint->getSamplesPerFrame()) {
ALOGE("AAudioServiceStreamShared::open() mSamplesPerFrame = %d, need %d",
- getSamplesPerFrame(), mServiceEndpoint->getSamplesPerFrame());
+ getSamplesPerFrame(), endpoint->getSamplesPerFrame());
result = AAUDIO_ERROR_OUT_OF_RANGE;
goto error;
}
@@ -181,9 +186,9 @@ aaudio_result_t AAudioServiceStreamShared::open(const aaudio::AAudioStreamReques
}
ALOGD("AAudioServiceStreamShared::open() actual rate = %d, channels = %d, deviceId = %d",
- getSampleRate(), getSamplesPerFrame(), mServiceEndpoint->getDeviceId());
+ getSampleRate(), getSamplesPerFrame(), endpoint->getDeviceId());
- result = mServiceEndpoint->registerStream(keep);
+ result = endpoint->registerStream(keep);
if (result != AAUDIO_OK) {
goto error;
}
@@ -250,7 +255,13 @@ aaudio_result_t AAudioServiceStreamShared::getHardwareTimestamp(int64_t *positio
int64_t *timeNanos) {
int64_t position = 0;
- aaudio_result_t result = mServiceEndpoint->getTimestamp(&position, timeNanos);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+
+ aaudio_result_t result = endpoint->getTimestamp(&position, timeNanos);
if (result == AAUDIO_OK) {
int64_t offset = mTimestampPositionOffset.load();
// TODO, do not go below starting value