aaudio: indicate client UID and PID to audio flinger
Implement correct indication of client UID and PID to audio flinger
for AAudio MMAP streams in both exclusive mode and shared mode.
- Add start/stop client methods on MMAP streams used only when the MMAP
stream is in AAudio service and carries a mix of shared streams.
- Add "In Service'" indication from "client" side to AAudioServiceStreamMMAP
so that the behavior can be adapted accordingly.
- Modify logic on audio flinger side with regard to mmap tracks and
audio HAL stream activity:
- use same audio session for all clients on a same stream to match
audio policy logic to share same direct output stream for clients on same
session. This is also more consistent with current volume and effect
handling as all MMAP clients sharing the same output stream have the
same volume and use case.
- start/stop the HAL when the stream is started/stopped with the initial client
handle (returned when the stream is opened) but do not create a track.
AAudioService implementation will always send an additional start command before
first client starts and a stop command after last client stops,
in both shared and exclusive mode.
- start/stop a track only if the start/stop stream command is received
with a handle different from the initial handle.
- Allow more than one active client from the same UID on a MMAP input in audio policy.
Bug: 62950008
Test: verify playback and capture in mmap mode
Merged-In: I86151bbb637ff172d2fd5f813056eab13a7bcd3c
Change-Id: I86151bbb637ff172d2fd5f813056eab13a7bcd3c
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index 1b80486..68be3c3 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "AAudioService"
+#define LOG_TAG "AAudioServiceStreamMMAP"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -41,19 +41,21 @@
* Service Stream that uses an MMAP buffer.
*/
-AAudioServiceStreamMMAP::AAudioServiceStreamMMAP(uid_t serviceUid)
+AAudioServiceStreamMMAP::AAudioServiceStreamMMAP(const android::AudioClient& serviceClient,
+ bool inService)
: AAudioServiceStreamBase()
, mMmapStreamCallback(new MyMmapStreamCallback(*this))
, mPreviousFrameCounter(0)
, mMmapStream(nullptr)
- , mCachedUserId(serviceUid) {
+ , mServiceClient(serviceClient)
+ , mInService(inService) {
}
aaudio_result_t AAudioServiceStreamMMAP::close() {
if (mState == AAUDIO_STREAM_STATE_CLOSED) {
return AAUDIO_OK;
}
-
+ stop();
if (mMmapStream != 0) {
mMmapStream.clear(); // TODO review. Is that all we have to do?
// Apparently the above close is asynchronous. An attempt to open a new device
@@ -90,9 +92,6 @@
const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
audio_port_handle_t deviceId = configurationInput.getDeviceId();
-
- mMmapClient.clientUid = request.getUserId();
- mMmapClient.clientPid = request.getProcessId();
aaudio_direction_t direction = request.getDirection();
// Fill in config
@@ -123,8 +122,6 @@
return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
}
- mMmapClient.packageName.setTo(String16("aaudio_service")); // FIXME what should we do here?
-
MmapStreamInterface::stream_direction_t streamDirection = (direction == AAUDIO_DIRECTION_OUTPUT)
? MmapStreamInterface::DIRECTION_OUTPUT : MmapStreamInterface::DIRECTION_INPUT;
@@ -135,7 +132,8 @@
mMmapClient,
&deviceId,
mMmapStreamCallback,
- mMmapStream);
+ mMmapStream,
+ &mPortHandle);
if (status != OK) {
ALOGE("openMmapStream returned status %d", status);
return AAUDIO_ERROR_UNAVAILABLE;
@@ -172,7 +170,7 @@
mCapacityInFrames = -mCapacityInFrames;
} else {
// exclusive mode is only possible if the final fd destination is inside audioserver
- if ((mMmapClient.clientUid != mCachedUserId) &&
+ if ((mMmapClient.clientUid != mServiceClient.clientUid) &&
configurationInput.getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
// Fallback is handled by caller but indicate what is possible in case
// this is used in the future
@@ -223,15 +221,21 @@
* Start the flow of data.
*/
aaudio_result_t AAudioServiceStreamMMAP::start() {
+ if (isRunning()) {
+ return AAUDIO_OK;
+ }
if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
aaudio_result_t result;
- status_t status = mMmapStream->start(mMmapClient, &mPortHandle);
+ status_t status = mMmapStream->start(mServiceClient, &mPortHandle);
if (status != OK) {
ALOGE("AAudioServiceStreamMMAP::start() mMmapStream->start() returned %d", status);
disconnect();
result = AAudioConvert_androidToAAudioResult(status);
} else {
result = AAudioServiceStreamBase::start();
+ if (!mInService && result == AAUDIO_OK) {
+ startClient(mMmapClient, &mClientHandle);
+ }
}
return result;
}
@@ -240,18 +244,28 @@
* Stop the flow of data such that start() can resume with loss of data.
*/
aaudio_result_t AAudioServiceStreamMMAP::pause() {
+ if (!isRunning()) {
+ return AAUDIO_OK;
+ }
if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
-
aaudio_result_t result1 = AAudioServiceStreamBase::pause();
+ if (!mInService) {
+ stopClient(mClientHandle);
+ }
status_t status = mMmapStream->stop(mPortHandle);
mFramesRead.reset32();
return (result1 != AAUDIO_OK) ? result1 : AAudioConvert_androidToAAudioResult(status);
}
aaudio_result_t AAudioServiceStreamMMAP::stop() {
+ if (!isRunning()) {
+ return AAUDIO_OK;
+ }
if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
-
aaudio_result_t result1 = AAudioServiceStreamBase::stop();
+ if (!mInService) {
+ stopClient(mClientHandle);
+ }
aaudio_result_t status = mMmapStream->stop(mPortHandle);
mFramesRead.reset32();
return (result1 != AAUDIO_OK) ? result1 : AAudioConvert_androidToAAudioResult(status);
@@ -266,6 +280,15 @@
return AAudioServiceStreamBase::flush();;
}
+aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client,
+ audio_port_handle_t *clientHandle) {
+ return AAudioConvert_androidToAAudioResult(mMmapStream->start(client, clientHandle));
+}
+
+aaudio_result_t AAudioServiceStreamMMAP::stopClient(audio_port_handle_t clientHandle) {
+ return AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle));
+}
+
aaudio_result_t AAudioServiceStreamMMAP::getFreeRunningPosition(int64_t *positionFrames,
int64_t *timeNanos) {
struct audio_mmap_position position;
@@ -301,11 +324,11 @@
void AAudioServiceStreamMMAP::onRoutingChanged(audio_port_handle_t deviceId) {
ALOGD("AAudioServiceStreamMMAP::onRoutingChanged() called with %d, old = %d",
- deviceId, mPortHandle);
- if (mPortHandle > 0 && mPortHandle != deviceId) {
+ deviceId, mDeviceId);
+ if (mDeviceId != AUDIO_PORT_HANDLE_NONE && mDeviceId != deviceId) {
disconnect();
}
- mPortHandle = deviceId;
+ mDeviceId = deviceId;
};
/**