OSDN Git Service

audiopolicy: Two clients can not offload concurrently
authorKevin Rocard <krocard@google.com>
Mon, 6 Feb 2017 23:59:29 +0000 (15:59 -0800)
committerKevin Rocard <krocard@google.com>
Thu, 9 Feb 2017 18:29:05 +0000 (10:29 -0800)
If two application are playing a compatible offload stream at the same
time.
Eg: two games playing MP3. At least one not taking the audio
focus.

The audio policy was offloading both stream resulting in audio glitches
and one stream being dropped.

Concurrent offload streams is intended to be a transitioning state when
an application wants back to back playbacks.

It should not be allowed for two different applications to stream at the
same time.

Test: Play mp3 while mp3 is already offloaded.
Bug: 34012147

Change-Id: I98a8913d6faf5092a1e43a0bdd0f1ce1482221a9
Signed-off-by: Kevin Rocard <krocard@google.com>
include/media/AudioSystem.h
services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
services/audiopolicy/managerdefault/AudioPolicyManager.cpp
services/audiopolicy/managerdefault/AudioPolicyManager.h

index 4c64242..853d318 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef ANDROID_AUDIOSYSTEM_H_
 #define ANDROID_AUDIOSYSTEM_H_
 
+#include <sys/types.h>
+
 #include <media/AudioPolicy.h>
 #include <media/AudioIoDescriptor.h>
 #include <media/IAudioFlingerClient.h>
index 35bb021..16fed70 100644 (file)
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <sys/types.h>
+
 #include "AudioPort.h"
 #include <RoutingStrategy.h>
 #include <utils/Errors.h>
@@ -128,6 +130,7 @@ public:
     sp<SwAudioOutputDescriptor> mOutput1;    // used by duplicated outputs: first output
     sp<SwAudioOutputDescriptor> mOutput2;    // used by duplicated outputs: second output
     uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
+    uid_t mDirectClientUid; // uid of the direct output client
     uint32_t mGlobalRefCount;  // non-stream-specific ref count
 };
 
index 93b7f47..5643335 100644 (file)
@@ -223,7 +223,7 @@ SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
     : AudioOutputDescriptor(profile, clientInterface),
     mProfile(profile), mIoHandle(0), mLatency(0),
     mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
-    mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0)
+    mOutput1(0), mOutput2(0), mDirectOpenCount(0), mDirectClientUid(0), mGlobalRefCount(0)
 {
     if (profile != NULL) {
         mFlags = (audio_output_flags_t)profile->getFlags();
index 54c406c..564ed56 100644 (file)
@@ -752,7 +752,7 @@ audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
     ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
           device, stream, samplingRate, format, channelMask, flags);
 
-    return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE,
+    return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE, uid_t{0} /*Invalid uid*/,
                               stream, samplingRate,format, channelMask,
                               flags, offloadInfo);
 }
@@ -832,7 +832,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
     ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x",
           device, config->sample_rate, config->format, config->channel_mask, flags);
 
-    *output = getOutputForDevice(device, session, *stream,
+    *output = getOutputForDevice(device, session, uid, *stream,
                                  config->sample_rate, config->format, config->channel_mask,
                                  flags, &config->offload_info);
     if (*output == AUDIO_IO_HANDLE_NONE) {
@@ -846,6 +846,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
 audio_io_handle_t AudioPolicyManager::getOutputForDevice(
         audio_devices_t device,
         audio_session_t session __unused,
+        uid_t clientUid,
         audio_stream_type_t stream,
         uint32_t samplingRate,
         audio_format_t format,
@@ -954,13 +955,21 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
             if (!desc->isDuplicated() && (profile == desc->mProfile)) {
                 outputDesc = desc;
-                // reuse direct output if currently open and configured with same parameters
+                // reuse direct output if currently open by the same client
+                // and configured with same parameters
                 if ((samplingRate == outputDesc->mSamplingRate) &&
-                        audio_formats_match(format, outputDesc->mFormat) &&
-                        (channelMask == outputDesc->mChannelMask)) {
-                    outputDesc->mDirectOpenCount++;
-                    ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
-                    return mOutputs.keyAt(i);
+                    audio_formats_match(format, outputDesc->mFormat) &&
+                    (channelMask == outputDesc->mChannelMask)) {
+                  if (clientUid == outputDesc->mDirectClientUid) {
+                      outputDesc->mDirectOpenCount++;
+                      ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
+                      return mOutputs.keyAt(i);
+                  } else {
+                      ALOGV("getOutput() do not reuse direct output because current client (%ld) "
+                            "is not the same as requesting client (%ld)",
+                            (long)outputDesc->mDirectClientUid, (long)clientUid);
+                      goto non_direct_output;
+                  }
                 }
             }
         }
@@ -1028,6 +1037,7 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
         outputDesc->mRefCount[stream] = 0;
         outputDesc->mStopTime[stream] = 0;
         outputDesc->mDirectOpenCount = 1;
+        outputDesc->mDirectClientUid = clientUid;
 
         audio_io_handle_t srcOutput = getOutputForEffect();
         addOutput(output, outputDesc);
index cea3f54..3dfcde6 100644 (file)
@@ -625,6 +625,7 @@ private:
         audio_io_handle_t getOutputForDevice(
                 audio_devices_t device,
                 audio_session_t session,
+                uid_t client,
                 audio_stream_type_t stream,
                 uint32_t samplingRate,
                 audio_format_t format,