aaudio: set to SHARED when EXCLUSIVE fails

SHARED streams and endpoints were being created with sharing mode
set to EXCLUSIVE. This was confusing the close() code and caused a hang.

Now we create a modified Request object with the sharing mode set
correctly.

Bug: 112709847
Test: Hack AAudioServiceEndpointMMAP so isBufferShareable is false.
Test: 'adb shell write_sine_callback -pl -x -s2' should not hang.
Change-Id: I7a5c8260beaffdd706f34d35ef00a61b072adb1d
gugelfrei
Phil Burk 6 years ago
parent 0d97cec053
commit 15f97c996f

@ -140,9 +140,8 @@ sp<AAudioServiceEndpointShared> AAudioEndpointManager::findSharedEndpoint_l(
}
sp<AAudioServiceEndpoint> AAudioEndpointManager::openEndpoint(AAudioService &audioService,
const aaudio::AAudioStreamRequest &request,
aaudio_sharing_mode_t sharingMode) {
if (sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) {
const aaudio::AAudioStreamRequest &request) {
if (request.getConstantConfiguration().getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
return openExclusiveEndpoint(audioService, request);
} else {
return openSharedEndpoint(audioService, request);

@ -56,8 +56,7 @@ public:
* @return endpoint or null
*/
android::sp<AAudioServiceEndpoint> openEndpoint(android::AAudioService &audioService,
const aaudio::AAudioStreamRequest &request,
aaudio_sharing_mode_t sharingMode);
const aaudio::AAudioStreamRequest &request);
void closeEndpoint(android::sp<AAudioServiceEndpoint> serviceEndpoint);

@ -118,11 +118,16 @@ aaudio_handle_t AAudioService::openStream(const aaudio::AAudioStreamRequest &req
}
}
// if SHARED requested or if EXCLUSIVE failed
if (sharingMode == AAUDIO_SHARING_MODE_SHARED
|| (serviceStream.get() == nullptr && !sharingModeMatchRequired)) {
// If SHARED requested or if EXCLUSIVE failed.
if (sharingMode == AAUDIO_SHARING_MODE_SHARED) {
serviceStream = new AAudioServiceStreamShared(*this);
result = serviceStream->open(request);
} else if (serviceStream.get() == nullptr && !sharingModeMatchRequired) {
aaudio::AAudioStreamRequest modifiedRequest = request;
// Overwrite the original EXCLUSIVE mode with SHARED.
modifiedRequest.getConfiguration().setSharingMode(AAUDIO_SHARING_MODE_SHARED);
serviceStream = new AAudioServiceStreamShared(*this);
result = serviceStream->open(modifiedRequest);
}
if (result != AAUDIO_OK) {

@ -210,9 +210,6 @@ aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamReques
uid_t audioServiceUid = getuid();
if ((mMmapClient.clientUid != audioServiceUid) &&
getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
// Fallback is handled by caller but indicate what is possible in case
// this is used in the future
setSharingMode(AAUDIO_SHARING_MODE_SHARED);
ALOGW("%s() - exclusive FD cannot be used by client", __func__);
result = AAUDIO_ERROR_UNAVAILABLE;
goto error;

@ -81,8 +81,7 @@ std::string AAudioServiceStreamBase::dump() const {
return result.str();
}
aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest &request,
aaudio_sharing_mode_t sharingMode) {
aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest &request) {
AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
aaudio_result_t result = AAUDIO_OK;
@ -109,8 +108,7 @@ aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest
// referenced until the service returns a handle to the client.
// So only one thread can open a stream.
mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService,
request,
sharingMode);
request);
if (mServiceEndpoint == nullptr) {
ALOGE("%s() openEndpoint() failed", __func__);
result = AAUDIO_ERROR_UNAVAILABLE;

@ -64,8 +64,13 @@ aaudio_result_t AAudioServiceStreamMMAP::open(const aaudio::AAudioStreamRequest
sp<AAudioServiceStreamMMAP> keep(this);
aaudio_result_t result = AAudioServiceStreamBase::open(request,
AAUDIO_SHARING_MODE_EXCLUSIVE);
if (request.getConstantConfiguration().getSharingMode() != AAUDIO_SHARING_MODE_EXCLUSIVE) {
ALOGE("%s() sharingMode mismatch %d", __func__,
request.getConstantConfiguration().getSharingMode());
return AAUDIO_ERROR_INTERNAL;
}
aaudio_result_t result = AAudioServiceStreamBase::open(request);
if (result != AAUDIO_OK) {
return result;
}

@ -120,7 +120,13 @@ aaudio_result_t AAudioServiceStreamShared::open(const aaudio::AAudioStreamReques
sp<AAudioServiceStreamShared> keep(this);
aaudio_result_t result = AAudioServiceStreamBase::open(request, AAUDIO_SHARING_MODE_SHARED);
if (request.getConstantConfiguration().getSharingMode() != AAUDIO_SHARING_MODE_SHARED) {
ALOGE("%s() sharingMode mismatch %d", __func__,
request.getConstantConfiguration().getSharingMode());
return AAUDIO_ERROR_INTERNAL;
}
aaudio_result_t result = AAudioServiceStreamBase::open(request);
if (result != AAUDIO_OK) {
ALOGE("%s() returned %d", __func__, result);
return result;

Loading…
Cancel
Save