aaudio: enable exclusive MMAP mode support
Allow exclusive MMAP mode only if the HAL indicates
that the FD returned for shared memory buffer can be shared
with any application.
NOTE: the way the HAL indicates this is temporary until the audio
HAL is modified in next HIDL release.
Bug: 37167970
Test: check playback and capture in mmap exclusive and shared mode
Change-Id: I09c1461b2f99532ded2ef9d36d483b82096fda68
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index cfcfb11..8f89051 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -107,7 +107,7 @@
}
if (sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) {
- serviceStream = new AAudioServiceStreamMMAP();
+ serviceStream = new AAudioServiceStreamMMAP(mCachedUserId);
result = serviceStream->open(request, configurationOutput);
if (result != AAUDIO_OK) {
// fall back to using a shared stream
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index 40093eb..da7cdf7 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -41,11 +41,12 @@
* Service Stream that uses an MMAP buffer.
*/
-AAudioServiceStreamMMAP::AAudioServiceStreamMMAP()
+AAudioServiceStreamMMAP::AAudioServiceStreamMMAP(uid_t serviceUid)
: AAudioServiceStreamBase()
, mMmapStreamCallback(new MyMmapStreamCallback(*this))
, mPreviousFrameCounter(0)
- , mMmapStream(nullptr) {
+ , mMmapStream(nullptr)
+ , mCachedUserId(serviceUid) {
}
AAudioServiceStreamMMAP::~AAudioServiceStreamMMAP() {
@@ -153,10 +154,29 @@
status);
return AAUDIO_ERROR_UNAVAILABLE;
} else {
- ALOGD("createMmapBuffer status %d shared_address = %p buffer_size %d burst_size %d",
+ ALOGD("createMmapBuffer status %d shared_address = %p buffer_size %d burst_size %d"
+ "Sharable FD: %s",
status, mMmapBufferinfo.shared_memory_address,
- mMmapBufferinfo.buffer_size_frames,
- mMmapBufferinfo.burst_size_frames);
+ abs(mMmapBufferinfo.buffer_size_frames),
+ mMmapBufferinfo.burst_size_frames,
+ mMmapBufferinfo.buffer_size_frames < 0 ? "Yes" : "No");
+ }
+
+ mCapacityInFrames = mMmapBufferinfo.buffer_size_frames;
+ // FIXME: the audio HAL indicates if the shared memory fd can be shared outside of audioserver
+ // by returning a negative buffer size
+ if (mCapacityInFrames < 0) {
+ // Exclusive mode is possible from any client
+ mCapacityInFrames = -mCapacityInFrames;
+ } else {
+ // exclusive mode is only possible if the final fd destination is inside audioserver
+ if ((mMmapClient.clientUid != mCachedUserId) &&
+ configurationInput.getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
+ // Fallback is handled by caller but indicate what is possible in case
+ // this is used in the future
+ configurationOutput.setSharingMode(AAUDIO_SHARING_MODE_SHARED);
+ return AAUDIO_ERROR_UNAVAILABLE;
+ }
}
// Get information about the stream and pass it back to the caller.
@@ -166,7 +186,6 @@
mAudioDataFileDescriptor = mMmapBufferinfo.shared_memory_fd;
mFramesPerBurst = mMmapBufferinfo.burst_size_frames;
- mCapacityInFrames = mMmapBufferinfo.buffer_size_frames;
mAudioFormat = AAudioConvert_androidToAAudioDataFormat(config.format);
mSampleRate = config.sample_rate;
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h
index fe75a10..337252d 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.h
+++ b/services/oboeservice/AAudioServiceStreamMMAP.h
@@ -43,7 +43,7 @@
, public android::MmapStreamCallback {
public:
- AAudioServiceStreamMMAP();
+ AAudioServiceStreamMMAP(uid_t serviceUid);
virtual ~AAudioServiceStreamMMAP();
@@ -134,6 +134,7 @@
struct audio_mmap_buffer_info mMmapBufferinfo;
android::MmapStreamInterface::Client mMmapClient;
audio_port_handle_t mPortHandle = -1; // TODO review best default
+ uid_t mCachedUserId = -1;
};
} // namespace aaudio