diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-07-20 00:32:02 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-07-20 00:32:02 +0000 |
commit | b511459ef16a74f35c534ee5f7767f59adb49742 (patch) | |
tree | b34bdf7674975e2b8897b732dc59a469c4ce8569 | |
parent | 5be288e24aeb2ff800912b0d2636754d007e23b4 (diff) | |
parent | 402ffe42673186ad25705120919928f2bd27f9b8 (diff) | |
download | av-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.cpp | 25 | ||||
-rw-r--r-- | media/libaudioclient/IAudioPolicyService.cpp | 65 | ||||
-rw-r--r-- | media/libaudioclient/include/media/IAudioPolicyService.h | 2 | ||||
-rw-r--r-- | media/libmedia/include/media/CryptoHal.h | 15 | ||||
-rw-r--r-- | media/libstagefright/ItemTable.cpp | 3 | ||||
-rw-r--r-- | media/libstagefright/VideoFrameScheduler.cpp | 5 | ||||
-rw-r--r-- | media/libstagefright/id3/ID3.cpp | 24 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 79 | ||||
-rw-r--r-- | services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp | 1 | ||||
-rw-r--r-- | services/oboeservice/AAudioServiceEndpoint.h | 4 | ||||
-rw-r--r-- | services/oboeservice/AAudioServiceStreamBase.cpp | 57 | ||||
-rw-r--r-- | services/oboeservice/AAudioServiceStreamBase.h | 5 | ||||
-rw-r--r-- | services/oboeservice/AAudioServiceStreamMMAP.cpp | 55 | ||||
-rw-r--r-- | services/oboeservice/AAudioServiceStreamShared.cpp | 29 |
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 |