@ -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 ( ) ;