diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-05-25 18:43:08 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-05-25 18:43:08 +0000 |
commit | e5aa8da0e3746dd4dcd19058bf9a062b4067a8ee (patch) | |
tree | d313059107b10318777a58e074cea6f28bc6e62e | |
parent | 5be288e24aeb2ff800912b0d2636754d007e23b4 (diff) | |
parent | fa12c0fcdc6607b746177ccad4f7099098b4849a (diff) | |
download | av-oreo-m6-s2-release.tar.gz |
Merge cherrypicks of [4195294, 4195296, 4195440, 4195441, 4186165, 4186166, 4186580, 4195442, 4195443, 4186193, 4186194, 4186195, 4186196, 4186607, 4195444, 4195297, 4186608, 4186609, 4186610, 4186611, 4186612, 4186613, 4186614, 4186649, 4186650, 4186651, 4186652, 4186653, 4186654, 4186655, 4186656, 4186657, 4195518, 4195519, 4195520, 4195521, 4195522, 4186406, 4186407, 4186408, 4195523, 4195558, 4195559, 4186197, 4195524, 4186615, 4195445, 4195446, 4186829, 4186830, 4186831, 4186832, 4186833, 4186834, 4186835, 4186836, 4186837, 4195578, 4195579, 4195580, 4195581, 4195447, 4186581, 4195448, 4195560] into sparse-4749909-L06000000176800346android-8.1.0_r41oreo-m6-s2-release
Change-Id: I8fd2e5330a81cee2c04924c1e775adb07068a021
-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 | 21 | ||||
-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 |
13 files changed, 218 insertions, 69 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..e897b67aac 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) { 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 |