Loading services/oboeservice/AAudioService.cpp +30 −83 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ #include <sstream> #include <aaudio/AAudio.h> #include <mediautils/SchedulingPolicyService.h> #include <mediautils/ServiceUtilities.h> #include <utils/String16.h> Loading Loading @@ -162,28 +161,6 @@ aaudio_handle_t AAudioService::openStream(const aaudio::AAudioStreamRequest &req } } // If a close request is pending then close the stream bool AAudioService::releaseStream(const sp<AAudioServiceStreamBase> &serviceStream) { bool closed = false; // decrementAndRemoveStreamByHandle() uses a lock so that if there are two simultaneous closes // then only one will get the pointer and do the close. sp<AAudioServiceStreamBase> foundStream = mStreamTracker.decrementAndRemoveStreamByHandle( serviceStream->getHandle()); if (foundStream.get() != nullptr) { foundStream->close(); pid_t pid = foundStream->getOwnerProcessId(); AAudioClientTracker::getInstance().unregisterClientStream(pid, foundStream); closed = true; } return closed; } aaudio_result_t AAudioService::checkForPendingClose( const sp<AAudioServiceStreamBase> &serviceStream, aaudio_result_t defaultResult) { return releaseStream(serviceStream) ? AAUDIO_ERROR_INVALID_STATE : defaultResult; } aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) { // Check permission and ownership first. sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); Loading @@ -195,17 +172,20 @@ aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) { } aaudio_result_t AAudioService::closeStream(sp<AAudioServiceStreamBase> serviceStream) { // This is protected by a lock in AAudioClientTracker. // It is safe to unregister the same stream twice. pid_t pid = serviceStream->getOwnerProcessId(); AAudioClientTracker::getInstance().unregisterClientStream(pid, serviceStream); // This is protected by a lock in mStreamTracker. // It is safe to remove the same stream twice. mStreamTracker.removeStreamByHandle(serviceStream->getHandle()); serviceStream->markCloseNeeded(); (void) releaseStream(serviceStream); return AAUDIO_OK; return serviceStream->close(); } sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandleAndIncrement( sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandle( streamHandle); if (serviceStream.get() != nullptr) { // Only allow owner or the aaudio service to access the stream. Loading @@ -218,8 +198,6 @@ sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( if (!allowed) { ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d", callingUserId, streamHandle, ownerUserId); // We incremented the reference count so we must check if it needs to be closed. checkForPendingClose(serviceStream, AAUDIO_OK); serviceStream.clear(); } } Loading @@ -234,96 +212,66 @@ aaudio_result_t AAudioService::getStreamDescription( ALOGE("getStreamDescription(), illegal stream handle = 0x%0x", streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->getDescription(parcelable); // parcelable.dump(); return checkForPendingClose(serviceStream, result); return serviceStream->getDescription(parcelable); } aaudio_result_t AAudioService::startStream(aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("startStream(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->start(); return checkForPendingClose(serviceStream, result); return serviceStream->start(); } aaudio_result_t AAudioService::pauseStream(aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("pauseStream(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->pause(); return checkForPendingClose(serviceStream, result); return serviceStream->pause(); } aaudio_result_t AAudioService::stopStream(aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("stopStream(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->stop(); return checkForPendingClose(serviceStream, result); return serviceStream->stop(); } aaudio_result_t AAudioService::flushStream(aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("flushStream(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->flush(); return checkForPendingClose(serviceStream, result); return serviceStream->flush(); } aaudio_result_t AAudioService::registerAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId, int64_t periodNanoseconds) { aaudio_result_t result = AAUDIO_OK; int64_t /* periodNanoseconds */) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("registerAudioThread(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } if (serviceStream->getRegisteredThread() != AAudioServiceStreamBase::ILLEGAL_THREAD_ID) { ALOGE("AAudioService::registerAudioThread(), thread already registered"); result = AAUDIO_ERROR_INVALID_STATE; } else { const pid_t ownerPid = IPCThreadState::self()->getCallingPid(); // TODO review int32_t priority = isCallerInService() ? kRealTimeAudioPriorityService : kRealTimeAudioPriorityClient; serviceStream->setRegisteredThread(clientThreadId); int err = android::requestPriority(ownerPid, clientThreadId, priority, true /* isForApp */); if (err != 0) { ALOGE("AAudioService::registerAudioThread(%d) failed, errno = %d, priority = %d", clientThreadId, errno, priority); result = AAUDIO_ERROR_INTERNAL; } } return checkForPendingClose(serviceStream, result); return serviceStream->registerAudioThread(clientThreadId, priority); } aaudio_result_t AAudioService::unregisterAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId) { aaudio_result_t result = AAUDIO_OK; sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } if (serviceStream->getRegisteredThread() != clientThreadId) { ALOGE("%s(), wrong thread", __func__); result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; } else { serviceStream->setRegisteredThread(0); } return checkForPendingClose(serviceStream, result); return serviceStream->unregisterAudioThread(clientThreadId); } aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle, Loading @@ -332,22 +280,20 @@ aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle, audio_port_handle_t *clientHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->startClient(client, attr, clientHandle); return checkForPendingClose(serviceStream, result); return serviceStream->startClient(client, attr, clientHandle); } aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle, audio_port_handle_t portHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->stopClient(portHandle); return checkForPendingClose(serviceStream, result); return serviceStream->stopClient(portHandle); } // This is only called internally when AudioFlinger wants to tear down a stream. Loading @@ -355,12 +301,13 @@ aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle, aaudio_result_t AAudioService::disconnectStreamByPortHandle(audio_port_handle_t portHandle) { ALOGD("%s(%d) called", __func__, portHandle); sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.findStreamByPortHandleAndIncrement(portHandle); mStreamTracker.findStreamByPortHandle(portHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), could not find stream with portHandle = %d", __func__, portHandle); return AAUDIO_ERROR_INVALID_HANDLE; } // This is protected by a lock and will just return if already stopped. aaudio_result_t result = serviceStream->stop(); serviceStream->disconnect(); return checkForPendingClose(serviceStream, result); return result; } services/oboeservice/AAudioService.h +0 −5 Original line number Diff line number Diff line Loading @@ -114,11 +114,6 @@ private: sp<aaudio::AAudioServiceStreamBase> convertHandleToServiceStream( aaudio::aaudio_handle_t streamHandle); bool releaseStream(const sp<aaudio::AAudioServiceStreamBase> &serviceStream); aaudio_result_t checkForPendingClose(const sp<aaudio::AAudioServiceStreamBase> &serviceStream, aaudio_result_t defaultResult); android::AudioClient mAudioClient; aaudio::AAudioStreamTracker mStreamTracker; Loading services/oboeservice/AAudioServiceEndpoint.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -90,14 +90,16 @@ bool AAudioServiceEndpoint::isStreamRegistered(audio_port_handle_t portHandle) { std::vector<android::sp<AAudioServiceStreamBase>> AAudioServiceEndpoint::disconnectRegisteredStreams() { std::vector<android::sp<AAudioServiceStreamBase>> streamsDisconnected; { std::lock_guard<std::mutex> lock(mLockStreams); mRegisteredStreams.swap(streamsDisconnected); } mConnected.store(false); for (const auto &stream : mRegisteredStreams) { for (const auto &stream : streamsDisconnected) { ALOGD("%s() - stop and disconnect port %d", __func__, stream->getPortHandle()); stream->stop(); stream->disconnect(); } mRegisteredStreams.swap(streamsDisconnected); return streamsDisconnected; } Loading services/oboeservice/AAudioServiceEndpointShared.cpp +1 −3 Original line number Diff line number Diff line Loading @@ -168,13 +168,11 @@ aaudio_result_t AAudioServiceEndpointShared::startStream(sp<AAudioServiceStreamB aaudio_result_t AAudioServiceEndpointShared::stopStream(sp<AAudioServiceStreamBase> sharedStream, audio_port_handle_t clientHandle) { // Don't lock here because the disconnectRegisteredStreams also uses the lock. // Ignore result. (void) getStreamInternal()->stopClient(clientHandle); if (--mRunningStreamCount == 0) { // atomic stopSharingThread(); stopSharingThread(); // the sharing thread locks mLockStreams getStreamInternal()->requestStop(); } return AAUDIO_OK; Loading services/oboeservice/AAudioServiceStreamBase.cpp +89 −12 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <media/MediaMetricsItem.h> #include <media/TypeConverter.h> #include <mediautils/SchedulingPolicyService.h> #include "binding/IAAudioService.h" #include "binding/AAudioServiceMessage.h" Loading Loading @@ -169,11 +170,16 @@ error: } aaudio_result_t AAudioServiceStreamBase::close() { std::lock_guard<std::mutex> lock(mLock); return close_l(); } aaudio_result_t AAudioServiceStreamBase::close_l() { if (getState() == AAUDIO_STREAM_STATE_CLOSED) { return AAUDIO_OK; } stop(); stop_l(); aaudio_result_t result = AAUDIO_OK; sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote(); Loading @@ -185,7 +191,7 @@ aaudio_result_t AAudioServiceStreamBase::close() { 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. mServiceEndpoint.clear(); // endpoint will hold the pointer after this method returns. } { Loading Loading @@ -219,9 +225,18 @@ aaudio_result_t AAudioServiceStreamBase::startDevice() { * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete. */ aaudio_result_t AAudioServiceStreamBase::start() { std::lock_guard<std::mutex> lock(mLock); const int64_t beginNs = AudioClock::getNanoseconds(); aaudio_result_t result = AAUDIO_OK; if (auto state = getState(); state == AAUDIO_STREAM_STATE_CLOSED || state == AAUDIO_STREAM_STATE_DISCONNECTED) { ALOGW("%s() already CLOSED, returns INVALID_STATE, handle = %d", __func__, getHandle()); return AAUDIO_ERROR_INVALID_STATE; } mediametrics::Defer defer([&] { mediametrics::LogItem(mMetricsId) .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_START) Loading @@ -231,7 +246,7 @@ aaudio_result_t AAudioServiceStreamBase::start() { .record(); }); if (isRunning()) { return AAUDIO_OK; return result; } setFlowing(false); Loading @@ -254,16 +269,21 @@ aaudio_result_t AAudioServiceStreamBase::start() { return result; error: disconnect(); disconnect_l(); return result; } aaudio_result_t AAudioServiceStreamBase::pause() { const int64_t beginNs = AudioClock::getNanoseconds(); std::lock_guard<std::mutex> lock(mLock); return pause_l(); } aaudio_result_t AAudioServiceStreamBase::pause_l() { aaudio_result_t result = AAUDIO_OK; if (!isRunning()) { return result; } const int64_t beginNs = AudioClock::getNanoseconds(); mediametrics::Defer defer([&] { mediametrics::LogItem(mMetricsId) Loading @@ -279,7 +299,7 @@ aaudio_result_t AAudioServiceStreamBase::pause() { result = stopTimestampThread(); if (result != AAUDIO_OK) { disconnect(); disconnect_l(); return result; } Loading @@ -292,7 +312,7 @@ aaudio_result_t AAudioServiceStreamBase::pause() { result = endpoint->stopStream(this, mClientHandle); if (result != AAUDIO_OK) { ALOGE("%s() mServiceEndpoint returned %d, %s", __func__, result, getTypeText()); disconnect(); // TODO should we return or pause Base first? disconnect_l(); // TODO should we return or pause Base first? } sendServiceEvent(AAUDIO_SERVICE_EVENT_PAUSED); Loading @@ -301,11 +321,16 @@ aaudio_result_t AAudioServiceStreamBase::pause() { } aaudio_result_t AAudioServiceStreamBase::stop() { const int64_t beginNs = AudioClock::getNanoseconds(); std::lock_guard<std::mutex> lock(mLock); return stop_l(); } aaudio_result_t AAudioServiceStreamBase::stop_l() { aaudio_result_t result = AAUDIO_OK; if (!isRunning()) { return result; } const int64_t beginNs = AudioClock::getNanoseconds(); mediametrics::Defer defer([&] { mediametrics::LogItem(mMetricsId) Loading @@ -322,7 +347,7 @@ aaudio_result_t AAudioServiceStreamBase::stop() { sendCurrentTimestamp(); // warning - this calls a virtual function result = stopTimestampThread(); if (result != AAUDIO_OK) { disconnect(); disconnect_l(); return result; } Loading @@ -336,7 +361,7 @@ aaudio_result_t AAudioServiceStreamBase::stop() { result = endpoint->stopStream(this, mClientHandle); if (result != AAUDIO_OK) { ALOGE("%s() stopStream returned %d, %s", __func__, result, getTypeText()); disconnect(); disconnect_l(); // TODO what to do with result here? } Loading @@ -355,11 +380,12 @@ aaudio_result_t AAudioServiceStreamBase::stopTimestampThread() { } aaudio_result_t AAudioServiceStreamBase::flush() { const int64_t beginNs = AudioClock::getNanoseconds(); std::lock_guard<std::mutex> lock(mLock); aaudio_result_t result = AAudio_isFlushAllowed(getState()); if (result != AAUDIO_OK) { return result; } const int64_t beginNs = AudioClock::getNanoseconds(); mediametrics::Defer defer([&] { mediametrics::LogItem(mMetricsId) Loading Loading @@ -404,16 +430,66 @@ void AAudioServiceStreamBase::run() { } void AAudioServiceStreamBase::disconnect() { if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { std::lock_guard<std::mutex> lock(mLock); disconnect_l(); } void AAudioServiceStreamBase::disconnect_l() { if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED && getState() != AAUDIO_STREAM_STATE_CLOSED) { mediametrics::LogItem(mMetricsId) .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_DISCONNECT) .set(AMEDIAMETRICS_PROP_STATE, AudioGlobal_convertStreamStateToText(getState())) .record(); sendServiceEvent(AAUDIO_SERVICE_EVENT_DISCONNECTED); setState(AAUDIO_STREAM_STATE_DISCONNECTED); } } aaudio_result_t AAudioServiceStreamBase::registerAudioThread(pid_t clientThreadId, int priority) { std::lock_guard<std::mutex> lock(mLock); aaudio_result_t result = AAUDIO_OK; if (getRegisteredThread() != AAudioServiceStreamBase::ILLEGAL_THREAD_ID) { ALOGE("AAudioService::registerAudioThread(), thread already registered"); result = AAUDIO_ERROR_INVALID_STATE; } else { const pid_t ownerPid = IPCThreadState::self()->getCallingPid(); // TODO review setRegisteredThread(clientThreadId); int err = android::requestPriority(ownerPid, clientThreadId, priority, true /* isForApp */); if (err != 0) { ALOGE("AAudioService::registerAudioThread(%d) failed, errno = %d, priority = %d", clientThreadId, errno, priority); result = AAUDIO_ERROR_INTERNAL; } } return result; } aaudio_result_t AAudioServiceStreamBase::unregisterAudioThread(pid_t clientThreadId) { std::lock_guard<std::mutex> lock(mLock); aaudio_result_t result = AAUDIO_OK; if (getRegisteredThread() != clientThreadId) { ALOGE("%s(), wrong thread", __func__); result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; } else { setRegisteredThread(0); } return result; } void AAudioServiceStreamBase::setState(aaudio_stream_state_t state) { // CLOSED is a final state. if (mState != AAUDIO_STREAM_STATE_CLOSED) { mState = state; } else { ALOGW_IF(mState != state, "%s(%d) when already CLOSED", __func__, state); } } aaudio_result_t AAudioServiceStreamBase::sendServiceEvent(aaudio_service_event_t event, double dataDouble) { AAudioServiceMessage command; Loading Loading @@ -511,6 +587,7 @@ aaudio_result_t AAudioServiceStreamBase::sendCurrentTimestamp() { * used to communicate with the underlying HAL or Service. */ aaudio_result_t AAudioServiceStreamBase::getDescription(AudioEndpointParcelable &parcelable) { std::lock_guard<std::mutex> lock(mLock); { std::lock_guard<std::mutex> lock(mUpMessageQueueLock); if (mUpMessageQueue == nullptr) { Loading Loading
services/oboeservice/AAudioService.cpp +30 −83 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ #include <sstream> #include <aaudio/AAudio.h> #include <mediautils/SchedulingPolicyService.h> #include <mediautils/ServiceUtilities.h> #include <utils/String16.h> Loading Loading @@ -162,28 +161,6 @@ aaudio_handle_t AAudioService::openStream(const aaudio::AAudioStreamRequest &req } } // If a close request is pending then close the stream bool AAudioService::releaseStream(const sp<AAudioServiceStreamBase> &serviceStream) { bool closed = false; // decrementAndRemoveStreamByHandle() uses a lock so that if there are two simultaneous closes // then only one will get the pointer and do the close. sp<AAudioServiceStreamBase> foundStream = mStreamTracker.decrementAndRemoveStreamByHandle( serviceStream->getHandle()); if (foundStream.get() != nullptr) { foundStream->close(); pid_t pid = foundStream->getOwnerProcessId(); AAudioClientTracker::getInstance().unregisterClientStream(pid, foundStream); closed = true; } return closed; } aaudio_result_t AAudioService::checkForPendingClose( const sp<AAudioServiceStreamBase> &serviceStream, aaudio_result_t defaultResult) { return releaseStream(serviceStream) ? AAUDIO_ERROR_INVALID_STATE : defaultResult; } aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) { // Check permission and ownership first. sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); Loading @@ -195,17 +172,20 @@ aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) { } aaudio_result_t AAudioService::closeStream(sp<AAudioServiceStreamBase> serviceStream) { // This is protected by a lock in AAudioClientTracker. // It is safe to unregister the same stream twice. pid_t pid = serviceStream->getOwnerProcessId(); AAudioClientTracker::getInstance().unregisterClientStream(pid, serviceStream); // This is protected by a lock in mStreamTracker. // It is safe to remove the same stream twice. mStreamTracker.removeStreamByHandle(serviceStream->getHandle()); serviceStream->markCloseNeeded(); (void) releaseStream(serviceStream); return AAUDIO_OK; return serviceStream->close(); } sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandleAndIncrement( sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.getStreamByHandle( streamHandle); if (serviceStream.get() != nullptr) { // Only allow owner or the aaudio service to access the stream. Loading @@ -218,8 +198,6 @@ sp<AAudioServiceStreamBase> AAudioService::convertHandleToServiceStream( if (!allowed) { ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d", callingUserId, streamHandle, ownerUserId); // We incremented the reference count so we must check if it needs to be closed. checkForPendingClose(serviceStream, AAUDIO_OK); serviceStream.clear(); } } Loading @@ -234,96 +212,66 @@ aaudio_result_t AAudioService::getStreamDescription( ALOGE("getStreamDescription(), illegal stream handle = 0x%0x", streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->getDescription(parcelable); // parcelable.dump(); return checkForPendingClose(serviceStream, result); return serviceStream->getDescription(parcelable); } aaudio_result_t AAudioService::startStream(aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("startStream(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->start(); return checkForPendingClose(serviceStream, result); return serviceStream->start(); } aaudio_result_t AAudioService::pauseStream(aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("pauseStream(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->pause(); return checkForPendingClose(serviceStream, result); return serviceStream->pause(); } aaudio_result_t AAudioService::stopStream(aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("stopStream(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->stop(); return checkForPendingClose(serviceStream, result); return serviceStream->stop(); } aaudio_result_t AAudioService::flushStream(aaudio_handle_t streamHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("flushStream(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->flush(); return checkForPendingClose(serviceStream, result); return serviceStream->flush(); } aaudio_result_t AAudioService::registerAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId, int64_t periodNanoseconds) { aaudio_result_t result = AAUDIO_OK; int64_t /* periodNanoseconds */) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("registerAudioThread(), illegal stream handle = 0x%0x", streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } if (serviceStream->getRegisteredThread() != AAudioServiceStreamBase::ILLEGAL_THREAD_ID) { ALOGE("AAudioService::registerAudioThread(), thread already registered"); result = AAUDIO_ERROR_INVALID_STATE; } else { const pid_t ownerPid = IPCThreadState::self()->getCallingPid(); // TODO review int32_t priority = isCallerInService() ? kRealTimeAudioPriorityService : kRealTimeAudioPriorityClient; serviceStream->setRegisteredThread(clientThreadId); int err = android::requestPriority(ownerPid, clientThreadId, priority, true /* isForApp */); if (err != 0) { ALOGE("AAudioService::registerAudioThread(%d) failed, errno = %d, priority = %d", clientThreadId, errno, priority); result = AAUDIO_ERROR_INTERNAL; } } return checkForPendingClose(serviceStream, result); return serviceStream->registerAudioThread(clientThreadId, priority); } aaudio_result_t AAudioService::unregisterAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId) { aaudio_result_t result = AAUDIO_OK; sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } if (serviceStream->getRegisteredThread() != clientThreadId) { ALOGE("%s(), wrong thread", __func__); result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; } else { serviceStream->setRegisteredThread(0); } return checkForPendingClose(serviceStream, result); return serviceStream->unregisterAudioThread(clientThreadId); } aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle, Loading @@ -332,22 +280,20 @@ aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle, audio_port_handle_t *clientHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->startClient(client, attr, clientHandle); return checkForPendingClose(serviceStream, result); return serviceStream->startClient(client, attr, clientHandle); } aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle, audio_port_handle_t portHandle) { sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } aaudio_result_t result = serviceStream->stopClient(portHandle); return checkForPendingClose(serviceStream, result); return serviceStream->stopClient(portHandle); } // This is only called internally when AudioFlinger wants to tear down a stream. Loading @@ -355,12 +301,13 @@ aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle, aaudio_result_t AAudioService::disconnectStreamByPortHandle(audio_port_handle_t portHandle) { ALOGD("%s(%d) called", __func__, portHandle); sp<AAudioServiceStreamBase> serviceStream = mStreamTracker.findStreamByPortHandleAndIncrement(portHandle); mStreamTracker.findStreamByPortHandle(portHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), could not find stream with portHandle = %d", __func__, portHandle); return AAUDIO_ERROR_INVALID_HANDLE; } // This is protected by a lock and will just return if already stopped. aaudio_result_t result = serviceStream->stop(); serviceStream->disconnect(); return checkForPendingClose(serviceStream, result); return result; }
services/oboeservice/AAudioService.h +0 −5 Original line number Diff line number Diff line Loading @@ -114,11 +114,6 @@ private: sp<aaudio::AAudioServiceStreamBase> convertHandleToServiceStream( aaudio::aaudio_handle_t streamHandle); bool releaseStream(const sp<aaudio::AAudioServiceStreamBase> &serviceStream); aaudio_result_t checkForPendingClose(const sp<aaudio::AAudioServiceStreamBase> &serviceStream, aaudio_result_t defaultResult); android::AudioClient mAudioClient; aaudio::AAudioStreamTracker mStreamTracker; Loading
services/oboeservice/AAudioServiceEndpoint.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -90,14 +90,16 @@ bool AAudioServiceEndpoint::isStreamRegistered(audio_port_handle_t portHandle) { std::vector<android::sp<AAudioServiceStreamBase>> AAudioServiceEndpoint::disconnectRegisteredStreams() { std::vector<android::sp<AAudioServiceStreamBase>> streamsDisconnected; { std::lock_guard<std::mutex> lock(mLockStreams); mRegisteredStreams.swap(streamsDisconnected); } mConnected.store(false); for (const auto &stream : mRegisteredStreams) { for (const auto &stream : streamsDisconnected) { ALOGD("%s() - stop and disconnect port %d", __func__, stream->getPortHandle()); stream->stop(); stream->disconnect(); } mRegisteredStreams.swap(streamsDisconnected); return streamsDisconnected; } Loading
services/oboeservice/AAudioServiceEndpointShared.cpp +1 −3 Original line number Diff line number Diff line Loading @@ -168,13 +168,11 @@ aaudio_result_t AAudioServiceEndpointShared::startStream(sp<AAudioServiceStreamB aaudio_result_t AAudioServiceEndpointShared::stopStream(sp<AAudioServiceStreamBase> sharedStream, audio_port_handle_t clientHandle) { // Don't lock here because the disconnectRegisteredStreams also uses the lock. // Ignore result. (void) getStreamInternal()->stopClient(clientHandle); if (--mRunningStreamCount == 0) { // atomic stopSharingThread(); stopSharingThread(); // the sharing thread locks mLockStreams getStreamInternal()->requestStop(); } return AAUDIO_OK; Loading
services/oboeservice/AAudioServiceStreamBase.cpp +89 −12 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <media/MediaMetricsItem.h> #include <media/TypeConverter.h> #include <mediautils/SchedulingPolicyService.h> #include "binding/IAAudioService.h" #include "binding/AAudioServiceMessage.h" Loading Loading @@ -169,11 +170,16 @@ error: } aaudio_result_t AAudioServiceStreamBase::close() { std::lock_guard<std::mutex> lock(mLock); return close_l(); } aaudio_result_t AAudioServiceStreamBase::close_l() { if (getState() == AAUDIO_STREAM_STATE_CLOSED) { return AAUDIO_OK; } stop(); stop_l(); aaudio_result_t result = AAUDIO_OK; sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote(); Loading @@ -185,7 +191,7 @@ aaudio_result_t AAudioServiceStreamBase::close() { 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. mServiceEndpoint.clear(); // endpoint will hold the pointer after this method returns. } { Loading Loading @@ -219,9 +225,18 @@ aaudio_result_t AAudioServiceStreamBase::startDevice() { * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete. */ aaudio_result_t AAudioServiceStreamBase::start() { std::lock_guard<std::mutex> lock(mLock); const int64_t beginNs = AudioClock::getNanoseconds(); aaudio_result_t result = AAUDIO_OK; if (auto state = getState(); state == AAUDIO_STREAM_STATE_CLOSED || state == AAUDIO_STREAM_STATE_DISCONNECTED) { ALOGW("%s() already CLOSED, returns INVALID_STATE, handle = %d", __func__, getHandle()); return AAUDIO_ERROR_INVALID_STATE; } mediametrics::Defer defer([&] { mediametrics::LogItem(mMetricsId) .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_START) Loading @@ -231,7 +246,7 @@ aaudio_result_t AAudioServiceStreamBase::start() { .record(); }); if (isRunning()) { return AAUDIO_OK; return result; } setFlowing(false); Loading @@ -254,16 +269,21 @@ aaudio_result_t AAudioServiceStreamBase::start() { return result; error: disconnect(); disconnect_l(); return result; } aaudio_result_t AAudioServiceStreamBase::pause() { const int64_t beginNs = AudioClock::getNanoseconds(); std::lock_guard<std::mutex> lock(mLock); return pause_l(); } aaudio_result_t AAudioServiceStreamBase::pause_l() { aaudio_result_t result = AAUDIO_OK; if (!isRunning()) { return result; } const int64_t beginNs = AudioClock::getNanoseconds(); mediametrics::Defer defer([&] { mediametrics::LogItem(mMetricsId) Loading @@ -279,7 +299,7 @@ aaudio_result_t AAudioServiceStreamBase::pause() { result = stopTimestampThread(); if (result != AAUDIO_OK) { disconnect(); disconnect_l(); return result; } Loading @@ -292,7 +312,7 @@ aaudio_result_t AAudioServiceStreamBase::pause() { result = endpoint->stopStream(this, mClientHandle); if (result != AAUDIO_OK) { ALOGE("%s() mServiceEndpoint returned %d, %s", __func__, result, getTypeText()); disconnect(); // TODO should we return or pause Base first? disconnect_l(); // TODO should we return or pause Base first? } sendServiceEvent(AAUDIO_SERVICE_EVENT_PAUSED); Loading @@ -301,11 +321,16 @@ aaudio_result_t AAudioServiceStreamBase::pause() { } aaudio_result_t AAudioServiceStreamBase::stop() { const int64_t beginNs = AudioClock::getNanoseconds(); std::lock_guard<std::mutex> lock(mLock); return stop_l(); } aaudio_result_t AAudioServiceStreamBase::stop_l() { aaudio_result_t result = AAUDIO_OK; if (!isRunning()) { return result; } const int64_t beginNs = AudioClock::getNanoseconds(); mediametrics::Defer defer([&] { mediametrics::LogItem(mMetricsId) Loading @@ -322,7 +347,7 @@ aaudio_result_t AAudioServiceStreamBase::stop() { sendCurrentTimestamp(); // warning - this calls a virtual function result = stopTimestampThread(); if (result != AAUDIO_OK) { disconnect(); disconnect_l(); return result; } Loading @@ -336,7 +361,7 @@ aaudio_result_t AAudioServiceStreamBase::stop() { result = endpoint->stopStream(this, mClientHandle); if (result != AAUDIO_OK) { ALOGE("%s() stopStream returned %d, %s", __func__, result, getTypeText()); disconnect(); disconnect_l(); // TODO what to do with result here? } Loading @@ -355,11 +380,12 @@ aaudio_result_t AAudioServiceStreamBase::stopTimestampThread() { } aaudio_result_t AAudioServiceStreamBase::flush() { const int64_t beginNs = AudioClock::getNanoseconds(); std::lock_guard<std::mutex> lock(mLock); aaudio_result_t result = AAudio_isFlushAllowed(getState()); if (result != AAUDIO_OK) { return result; } const int64_t beginNs = AudioClock::getNanoseconds(); mediametrics::Defer defer([&] { mediametrics::LogItem(mMetricsId) Loading Loading @@ -404,16 +430,66 @@ void AAudioServiceStreamBase::run() { } void AAudioServiceStreamBase::disconnect() { if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { std::lock_guard<std::mutex> lock(mLock); disconnect_l(); } void AAudioServiceStreamBase::disconnect_l() { if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED && getState() != AAUDIO_STREAM_STATE_CLOSED) { mediametrics::LogItem(mMetricsId) .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_DISCONNECT) .set(AMEDIAMETRICS_PROP_STATE, AudioGlobal_convertStreamStateToText(getState())) .record(); sendServiceEvent(AAUDIO_SERVICE_EVENT_DISCONNECTED); setState(AAUDIO_STREAM_STATE_DISCONNECTED); } } aaudio_result_t AAudioServiceStreamBase::registerAudioThread(pid_t clientThreadId, int priority) { std::lock_guard<std::mutex> lock(mLock); aaudio_result_t result = AAUDIO_OK; if (getRegisteredThread() != AAudioServiceStreamBase::ILLEGAL_THREAD_ID) { ALOGE("AAudioService::registerAudioThread(), thread already registered"); result = AAUDIO_ERROR_INVALID_STATE; } else { const pid_t ownerPid = IPCThreadState::self()->getCallingPid(); // TODO review setRegisteredThread(clientThreadId); int err = android::requestPriority(ownerPid, clientThreadId, priority, true /* isForApp */); if (err != 0) { ALOGE("AAudioService::registerAudioThread(%d) failed, errno = %d, priority = %d", clientThreadId, errno, priority); result = AAUDIO_ERROR_INTERNAL; } } return result; } aaudio_result_t AAudioServiceStreamBase::unregisterAudioThread(pid_t clientThreadId) { std::lock_guard<std::mutex> lock(mLock); aaudio_result_t result = AAUDIO_OK; if (getRegisteredThread() != clientThreadId) { ALOGE("%s(), wrong thread", __func__); result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; } else { setRegisteredThread(0); } return result; } void AAudioServiceStreamBase::setState(aaudio_stream_state_t state) { // CLOSED is a final state. if (mState != AAUDIO_STREAM_STATE_CLOSED) { mState = state; } else { ALOGW_IF(mState != state, "%s(%d) when already CLOSED", __func__, state); } } aaudio_result_t AAudioServiceStreamBase::sendServiceEvent(aaudio_service_event_t event, double dataDouble) { AAudioServiceMessage command; Loading Loading @@ -511,6 +587,7 @@ aaudio_result_t AAudioServiceStreamBase::sendCurrentTimestamp() { * used to communicate with the underlying HAL or Service. */ aaudio_result_t AAudioServiceStreamBase::getDescription(AudioEndpointParcelable &parcelable) { std::lock_guard<std::mutex> lock(mLock); { std::lock_guard<std::mutex> lock(mUpMessageQueueLock); if (mUpMessageQueue == nullptr) { Loading