Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 551061ab authored by Kevin Rocard's avatar Kevin Rocard
Browse files

audiopolicy: Two clients can not offload concurrently



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: default avatarKevin Rocard <krocard@google.com>
parent e2ce9366
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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>
+3 −0
Original line number Diff line number Diff line
@@ -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
};

+1 −1
Original line number Diff line number Diff line
@@ -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();
+18 −8
Original line number Diff line number Diff line
@@ -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)) {
                  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);
+1 −0
Original line number Diff line number Diff line
@@ -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,