summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-03-17 15:29:32 -0700
committerEric Laurent <elaurent@google.com>2015-04-08 18:08:11 -0700
commitc75307b73d324d590d0dbc05b44bce9aa89b7145 (patch)
tree824a23a9ffbebb3ace63146c171e938df6630fdd /services
parent303db9de6506db0c2b300863c39ece81721dd4e9 (diff)
downloadframeworks_av-c75307b73d324d590d0dbc05b44bce9aa89b7145.zip
frameworks_av-c75307b73d324d590d0dbc05b44bce9aa89b7145.tar.gz
frameworks_av-c75307b73d324d590d0dbc05b44bce9aa89b7145.tar.bz2
audio policy: volume control reorganization
Output volume and routing control by AudioOutputDescriptor is reorganized to prepare hardware source volume and routing control. AudioOutputDescriptor contains all volume, device and activity state common to software (audio flinger mixers) and hardware sources (tuners, A2DP, HDMI). A new class SwAudioOutputDescriptor is derived from AudioOutputDescriptor and is specific to software sources. Low level routing and volume control methods receive an AudioOutputDescriptor parameter instead of an IO handle. mPrimaryOutput is now an AudioOutputDescriptor. Change-Id: Ie90943ee3102cdb8adf89fdd2addd2c279b1e5bf
Diffstat (limited to 'services')
-rw-r--r--services/audiopolicy/common/managerdefinitions/Android.mk1
-rw-r--r--services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h92
-rw-r--r--services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h14
-rw-r--r--services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp290
-rw-r--r--services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp8
-rwxr-xr-xservices/audiopolicy/engine/interface/AudioPolicyManagerObserver.h2
-rwxr-xr-xservices/audiopolicy/enginedefault/src/Engine.cpp6
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp473
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.h61
9 files changed, 571 insertions, 376 deletions
diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk
index 71ba1cb..7c265aa 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.mk
+++ b/services/audiopolicy/common/managerdefinitions/Android.mk
@@ -25,6 +25,7 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/include \
$(TOPDIR)frameworks/av/services/audiopolicy/common/include \
+ $(TOPDIR)frameworks/av/services/audiopolicy
LOCAL_EXPORT_C_INCLUDE_DIRS := \
$(LOCAL_PATH)/include
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index cc2a3bd..c6bb975 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -27,25 +27,36 @@ namespace android {
class IOProfile;
class AudioMix;
+class AudioPolicyClientInterface;
// descriptor for audio outputs. Used to maintain current configuration of each opened audio output
// and keep track of the usage of this output by each audio stream type.
class AudioOutputDescriptor: public AudioPortConfig
{
public:
- AudioOutputDescriptor(const sp<IOProfile>& profile);
+ AudioOutputDescriptor(const sp<AudioPort>& port,
+ AudioPolicyClientInterface *clientInterface);
+ virtual ~AudioOutputDescriptor() {}
status_t dump(int fd);
void log(const char* indent);
- audio_devices_t device() const;
- void changeRefCount(audio_stream_type_t stream, int delta);
audio_port_handle_t getId() const;
- void setIoHandle(audio_io_handle_t ioHandle);
- bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
- audio_devices_t supportedDevices();
- uint32_t latency();
- bool sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc);
+ virtual audio_devices_t device() const;
+ virtual bool sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc);
+ virtual audio_devices_t supportedDevices();
+ virtual bool isDuplicated() const { return false; }
+ virtual uint32_t latency() { return 0; }
+ virtual bool isFixedVolume(audio_devices_t device);
+ virtual sp<AudioOutputDescriptor> subOutput1() { return 0; }
+ virtual sp<AudioOutputDescriptor> subOutput2() { return 0; }
+ virtual bool setVolume(float volume,
+ audio_stream_type_t stream,
+ audio_devices_t device,
+ uint32_t delayMs,
+ bool force);
+ virtual void changeRefCount(audio_stream_type_t stream, int delta);
+
bool isActive(uint32_t inPastMs = 0) const;
bool isStreamActive(audio_stream_type_t stream,
uint32_t inPastMs = 0,
@@ -53,34 +64,69 @@ public:
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
- virtual sp<AudioPort> getAudioPort() const { return mProfile; }
- void toAudioPort(struct audio_port *port) const;
+ virtual sp<AudioPort> getAudioPort() const { return mPort; }
+ virtual void toAudioPort(struct audio_port *port) const;
audio_module_handle_t getModuleHandle() const;
- audio_io_handle_t mIoHandle; // output handle
- uint32_t mLatency; //
- audio_output_flags_t mFlags; //
+ sp<AudioPort> mPort;
audio_devices_t mDevice; // current device this output is routed to
- AudioMix *mPolicyMix; // non NULL when used by a dynamic policy
audio_patch_handle_t mPatchHandle;
uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
nsecs_t mStopTime[AUDIO_STREAM_CNT];
- sp<AudioOutputDescriptor> mOutput1; // used by duplicated outputs: first output
- sp<AudioOutputDescriptor> mOutput2; // used by duplicated outputs: second output
float mCurVolume[AUDIO_STREAM_CNT]; // current stream volume
int mMuteCount[AUDIO_STREAM_CNT]; // mute request counter
- const sp<IOProfile> mProfile; // I/O profile this output derives from
bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
// device selection. See checkDeviceMuteStrategies()
- uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
+ AudioPolicyClientInterface *mClientInterface;
-private:
+protected:
audio_port_handle_t mId;
};
-class AudioOutputCollection :
- public DefaultKeyedVector< audio_io_handle_t, sp<AudioOutputDescriptor> >
+// Audio output driven by a software mixer in audio flinger.
+class SwAudioOutputDescriptor: public AudioOutputDescriptor
+{
+public:
+ SwAudioOutputDescriptor(const sp<IOProfile>& profile,
+ AudioPolicyClientInterface *clientInterface);
+ virtual ~SwAudioOutputDescriptor() {}
+
+ status_t dump(int fd);
+
+ void setIoHandle(audio_io_handle_t ioHandle);
+
+ virtual audio_devices_t device() const;
+ virtual bool sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc);
+ virtual audio_devices_t supportedDevices();
+ virtual uint32_t latency();
+ virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
+ virtual bool isFixedVolume(audio_devices_t device);
+ virtual sp<AudioOutputDescriptor> subOutput1() { return mOutput1; }
+ virtual sp<AudioOutputDescriptor> subOutput2() { return mOutput2; }
+ virtual void changeRefCount(audio_stream_type_t stream, int delta);
+ virtual bool setVolume(float volume,
+ audio_stream_type_t stream,
+ audio_devices_t device,
+ uint32_t delayMs,
+ bool force);
+
+ virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
+ const struct audio_port_config *srcConfig = NULL) const;
+ virtual void toAudioPort(struct audio_port *port) const;
+
+ const sp<IOProfile> mProfile; // I/O profile this output derives from
+ audio_io_handle_t mIoHandle; // output handle
+ uint32_t mLatency; //
+ audio_output_flags_t mFlags; //
+ AudioMix *mPolicyMix; // non NULL when used by a dynamic policy
+ 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)
+};
+
+class SwAudioOutputCollection :
+ public DefaultKeyedVector< audio_io_handle_t, sp<SwAudioOutputDescriptor> >
{
public:
bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
@@ -99,9 +145,9 @@ public:
*/
audio_io_handle_t getA2dpOutput() const;
- sp<AudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;
+ sp<SwAudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;
- sp<AudioOutputDescriptor> getPrimaryOutput() const;
+ sp<SwAudioOutputDescriptor> getPrimaryOutput() const;
/**
* return true if any output is playing anything besides the stream to ignore
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 988aed6..67285f3 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -24,7 +24,7 @@
namespace android {
-class AudioOutputDescriptor;
+class SwAudioOutputDescriptor;
/**
* custom mix entry in mPolicyMixes
@@ -33,9 +33,9 @@ class AudioPolicyMix : public RefBase {
public:
AudioPolicyMix() {}
- const sp<AudioOutputDescriptor> &getOutput() const;
+ const sp<SwAudioOutputDescriptor> &getOutput() const;
- void setOutput(sp<AudioOutputDescriptor> &output);
+ void setOutput(sp<SwAudioOutputDescriptor> &output);
void clearOutput();
@@ -45,7 +45,7 @@ public:
private:
AudioMix mMix; // Audio policy mix descriptor
- sp<AudioOutputDescriptor> mOutput; // Corresponding output stream
+ sp<SwAudioOutputDescriptor> mOutput; // Corresponding output stream
};
@@ -58,18 +58,18 @@ public:
status_t unregisterMix(String8 address);
- void closeOutput(sp<AudioOutputDescriptor> &desc);
+ void closeOutput(sp<SwAudioOutputDescriptor> &desc);
/**
* Try to find an output descriptor for the given attributes.
*
- * @param[in] attributes to consider for the research of output descriptor.
+ * @param[in] attributes to consider fowr the research of output descriptor.
* @param[out] desc to return if an output could be found.
*
* @return NO_ERROR if an output was found for the given attribute (in this case, the
* descriptor output param is initialized), error code otherwise.
*/
- status_t getOutputForAttr(audio_attributes_t attributes, sp<AudioOutputDescriptor> &desc);
+ status_t getOutputForAttr(audio_attributes_t attributes, sp<SwAudioOutputDescriptor> &desc);
audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
audio_devices_t availableDeviceTypes,
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 8de8cd8..0837a54 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "APM::AudioOutputDescriptor"
//#define LOG_NDEBUG 0
+#include <AudioPolicyInterface.h>
#include "AudioOutputDescriptor.h"
#include "IOProfile.h"
#include "AudioGain.h"
@@ -29,12 +30,10 @@
namespace android {
-AudioOutputDescriptor::AudioOutputDescriptor(const sp<IOProfile>& profile)
- : mIoHandle(0), mLatency(0),
- mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
- mPatchHandle(0),
- mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0),
- mId(0)
+AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
+ AudioPolicyClientInterface *clientInterface)
+ : mPort(port), mDevice(AUDIO_DEVICE_NONE),
+ mPatchHandle(0), mClientInterface(clientInterface), mId(0)
{
// clear usage count for all stream types
for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
@@ -46,23 +45,19 @@ AudioOutputDescriptor::AudioOutputDescriptor(const sp<IOProfile>& profile)
for (int i = 0; i < NUM_STRATEGIES; i++) {
mStrategyMutedByDevice[i] = false;
}
- if (profile != NULL) {
- mFlags = (audio_output_flags_t)profile->mFlags;
- mSamplingRate = profile->pickSamplingRate();
- mFormat = profile->pickFormat();
- mChannelMask = profile->pickChannelMask();
- if (profile->mGains.size() > 0) {
- profile->mGains[0]->getDefaultConfig(&mGain);
+ if (port != NULL) {
+ mSamplingRate = port->pickSamplingRate();
+ mFormat = port->pickFormat();
+ mChannelMask = port->pickChannelMask();
+ if (port->mGains.size() > 0) {
+ port->mGains[0]->getDefaultConfig(&mGain);
}
}
}
audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
{
- if (mProfile == 0) {
- return 0;
- }
- return mProfile->getModuleHandle();
+ return mPort->getModuleHandle();
}
audio_port_handle_t AudioOutputDescriptor::getId() const
@@ -72,35 +67,20 @@ audio_port_handle_t AudioOutputDescriptor::getId() const
audio_devices_t AudioOutputDescriptor::device() const
{
- if (isDuplicated()) {
- return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
- } else {
- return mDevice;
- }
+ return mDevice;
}
-void AudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
-{
- mId = AudioPort::getNextUniqueId();
- mIoHandle = ioHandle;
-}
-
-uint32_t AudioOutputDescriptor::latency()
+audio_devices_t AudioOutputDescriptor::supportedDevices()
{
- if (isDuplicated()) {
- return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
- } else {
- return mLatency;
- }
+ return mDevice;
}
bool AudioOutputDescriptor::sharesHwModuleWith(
const sp<AudioOutputDescriptor> outputDesc)
{
- if (isDuplicated()) {
- return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
- } else if (outputDesc->isDuplicated()){
- return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
+ if (outputDesc->isDuplicated()) {
+ return sharesHwModuleWith(outputDesc->subOutput1()) ||
+ sharesHwModuleWith(outputDesc->subOutput2());
} else {
return (getModuleHandle() == outputDesc->getModuleHandle());
}
@@ -109,11 +89,6 @@ bool AudioOutputDescriptor::sharesHwModuleWith(
void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
int delta)
{
- // forward usage count change to attached outputs
- if (isDuplicated()) {
- mOutput1->changeRefCount(stream, delta);
- mOutput2->changeRefCount(stream, delta);
- }
if ((delta + (int)mRefCount[stream]) < 0) {
ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
delta, stream, mRefCount[stream]);
@@ -124,15 +99,6 @@ void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
}
-audio_devices_t AudioOutputDescriptor::supportedDevices()
-{
- if (isDuplicated()) {
- return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
- } else {
- return mProfile->mSupportedDevices.types() ;
- }
-}
-
bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
{
nsecs_t sysTime = 0;
@@ -169,12 +135,33 @@ bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
return false;
}
+
+bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
+{
+ return false;
+}
+
+bool AudioOutputDescriptor::setVolume(float volume,
+ audio_stream_type_t stream,
+ audio_devices_t device __unused,
+ uint32_t delayMs,
+ bool force)
+{
+ // We actually change the volume if:
+ // - the float value returned by computeVolume() changed
+ // - the force flag is set
+ if (volume != mCurVolume[stream] || force) {
+ ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs);
+ mCurVolume[stream] = volume;
+ return true;
+ }
+ return false;
+}
+
void AudioOutputDescriptor::toAudioPortConfig(
struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
- ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
-
dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
if (srcConfig != NULL) {
@@ -186,21 +173,15 @@ void AudioOutputDescriptor::toAudioPortConfig(
dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
dstConfig->type = AUDIO_PORT_TYPE_MIX;
dstConfig->ext.mix.hw_module = getModuleHandle();
- dstConfig->ext.mix.handle = mIoHandle;
dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
}
void AudioOutputDescriptor::toAudioPort(
struct audio_port *port) const
{
- ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
- mProfile->toAudioPort(port);
+ mPort->toAudioPort(port);
port->id = mId;
- toAudioPortConfig(&port->active_config);
port->ext.mix.hw_module = getModuleHandle();
- port->ext.mix.handle = mIoHandle;
- port->ext.mix.latency_class =
- mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
}
status_t AudioOutputDescriptor::dump(int fd)
@@ -209,7 +190,7 @@ status_t AudioOutputDescriptor::dump(int fd)
char buffer[SIZE];
String8 result;
- snprintf(buffer, SIZE, " ID: %d\n", getId());
+ snprintf(buffer, SIZE, " ID: %d\n", mId);
result.append(buffer);
snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
result.append(buffer);
@@ -217,10 +198,6 @@ status_t AudioOutputDescriptor::dump(int fd)
result.append(buffer);
snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
result.append(buffer);
- snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
- result.append(buffer);
- snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
- result.append(buffer);
snprintf(buffer, SIZE, " Devices %08x\n", device());
result.append(buffer);
snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
@@ -237,15 +214,162 @@ status_t AudioOutputDescriptor::dump(int fd)
void AudioOutputDescriptor::log(const char* indent)
{
- ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X] hndl:%d",
- indent, mId, mId, mSamplingRate, mFormat, mChannelMask, mIoHandle);
+ ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
+ indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
+}
+
+// SwAudioOutputDescriptor implementation
+SwAudioOutputDescriptor::SwAudioOutputDescriptor(
+ const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface)
+ : AudioOutputDescriptor(profile, clientInterface),
+ mProfile(profile), mIoHandle(0), mLatency(0),
+ mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
+ mOutput1(0), mOutput2(0), mDirectOpenCount(0)
+{
+ if (profile != NULL) {
+ mFlags = (audio_output_flags_t)profile->mFlags;
+ }
+}
+
+void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
+{
+ mId = AudioPort::getNextUniqueId();
+ mIoHandle = ioHandle;
+}
+
+
+status_t SwAudioOutputDescriptor::dump(int fd)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
+ result.append(buffer);
+ write(fd, result.string(), result.size());
+
+ AudioOutputDescriptor::dump(fd);
+
+ return NO_ERROR;
+}
+
+audio_devices_t SwAudioOutputDescriptor::device() const
+{
+ if (isDuplicated()) {
+ return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
+ } else {
+ return mDevice;
+ }
}
-bool AudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
+bool SwAudioOutputDescriptor::sharesHwModuleWith(
+ const sp<AudioOutputDescriptor> outputDesc)
+{
+ if (isDuplicated()) {
+ return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
+ } else if (outputDesc->isDuplicated()){
+ return sharesHwModuleWith(outputDesc->subOutput1()) ||
+ sharesHwModuleWith(outputDesc->subOutput2());
+ } else {
+ return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
+ }
+}
+
+audio_devices_t SwAudioOutputDescriptor::supportedDevices()
+{
+ if (isDuplicated()) {
+ return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
+ } else {
+ return mProfile->mSupportedDevices.types() ;
+ }
+}
+
+uint32_t SwAudioOutputDescriptor::latency()
+{
+ if (isDuplicated()) {
+ return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
+ } else {
+ return mLatency;
+ }
+}
+
+void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
+ int delta)
+{
+ // forward usage count change to attached outputs
+ if (isDuplicated()) {
+ mOutput1->changeRefCount(stream, delta);
+ mOutput2->changeRefCount(stream, delta);
+ }
+ AudioOutputDescriptor::changeRefCount(stream, delta);
+}
+
+
+bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
+{
+ // unit gain if rerouting to external policy
+ if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
+ if (mPolicyMix != NULL) {
+ ALOGV("max gain when rerouting for output=%d", mIoHandle);
+ return true;
+ }
+ }
+ return false;
+}
+
+void SwAudioOutputDescriptor::toAudioPortConfig(
+ struct audio_port_config *dstConfig,
+ const struct audio_port_config *srcConfig) const
+{
+
+ ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
+ AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
+
+ dstConfig->ext.mix.handle = mIoHandle;
+}
+
+void SwAudioOutputDescriptor::toAudioPort(
+ struct audio_port *port) const
+{
+ ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
+
+ AudioOutputDescriptor::toAudioPort(port);
+
+ toAudioPortConfig(&port->active_config);
+ port->ext.mix.handle = mIoHandle;
+ port->ext.mix.latency_class =
+ mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
+}
+
+bool SwAudioOutputDescriptor::setVolume(float volume,
+ audio_stream_type_t stream,
+ audio_devices_t device,
+ uint32_t delayMs,
+ bool force)
+{
+ bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
+
+ if (changed) {
+ // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
+ // enabled
+ if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
+ mClientInterface->setStreamVolume(
+ AUDIO_STREAM_VOICE_CALL, mCurVolume[stream], mIoHandle, delayMs);
+ }
+ mClientInterface->setStreamVolume(stream, mCurVolume[stream], mIoHandle, delayMs);
+ }
+ return changed;
+}
+
+// SwAudioOutputCollection implementation
+
+bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
{
nsecs_t sysTime = systemTime();
for (size_t i = 0; i < this->size(); i++) {
- const sp<AudioOutputDescriptor> outputDesc = this->valueAt(i);
+ const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
return true;
}
@@ -253,12 +377,12 @@ bool AudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t
return false;
}
-bool AudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
+bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
uint32_t inPastMs) const
{
nsecs_t sysTime = systemTime();
for (size_t i = 0; i < size(); i++) {
- const sp<AudioOutputDescriptor> outputDesc = valueAt(i);
+ const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
// do not consider re routing (when the output is going to a dynamic policy)
@@ -271,10 +395,10 @@ bool AudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
return false;
}
-audio_io_handle_t AudioOutputCollection::getA2dpOutput() const
+audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
{
for (size_t i = 0; i < size(); i++) {
- sp<AudioOutputDescriptor> outputDesc = valueAt(i);
+ sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
return this->keyAt(i);
}
@@ -282,10 +406,10 @@ audio_io_handle_t AudioOutputCollection::getA2dpOutput() const
return 0;
}
-sp<AudioOutputDescriptor> AudioOutputCollection::getPrimaryOutput() const
+sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
{
for (size_t i = 0; i < size(); i++) {
- const sp<AudioOutputDescriptor> outputDesc = valueAt(i);
+ const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
return outputDesc;
}
@@ -293,9 +417,9 @@ sp<AudioOutputDescriptor> AudioOutputCollection::getPrimaryOutput() const
return NULL;
}
-sp<AudioOutputDescriptor> AudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
+sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
{
- sp<AudioOutputDescriptor> outputDesc = NULL;
+ sp<SwAudioOutputDescriptor> outputDesc = NULL;
for (size_t i = 0; i < size(); i++) {
outputDesc = valueAt(i);
if (outputDesc->getId() == id) {
@@ -305,14 +429,14 @@ sp<AudioOutputDescriptor> AudioOutputCollection::getOutputFromId(audio_port_hand
return outputDesc;
}
-bool AudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
+bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
{
for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
if (s == (size_t) streamToIgnore) {
continue;
}
for (size_t i = 0; i < size(); i++) {
- const sp<AudioOutputDescriptor> outputDesc = valueAt(i);
+ const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
if (outputDesc->mRefCount[s] != 0) {
return true;
}
@@ -321,15 +445,15 @@ bool AudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore
return false;
}
-audio_devices_t AudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
+audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
{
- sp<AudioOutputDescriptor> outputDesc = valueFor(handle);
+ sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types();
return devices;
}
-status_t AudioOutputCollection::dump(int fd) const
+status_t SwAudioOutputCollection::dump(int fd) const
{
const size_t SIZE = 256;
char buffer[SIZE];
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 84a53eb..c43bb6a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -26,12 +26,12 @@
namespace android {
-void AudioPolicyMix::setOutput(sp<AudioOutputDescriptor> &output)
+void AudioPolicyMix::setOutput(sp<SwAudioOutputDescriptor> &output)
{
mOutput = output;
}
-const sp<AudioOutputDescriptor> &AudioPolicyMix::getOutput() const
+const sp<SwAudioOutputDescriptor> &AudioPolicyMix::getOutput() const
{
return mOutput;
}
@@ -88,7 +88,7 @@ status_t AudioPolicyMixCollection::getAudioPolicyMix(String8 address,
return NO_ERROR;
}
-void AudioPolicyMixCollection::closeOutput(sp<AudioOutputDescriptor> &desc)
+void AudioPolicyMixCollection::closeOutput(sp<SwAudioOutputDescriptor> &desc)
{
for (size_t i = 0; i < size(); i++) {
sp<AudioPolicyMix> policyMix = valueAt(i);
@@ -99,7 +99,7 @@ void AudioPolicyMixCollection::closeOutput(sp<AudioOutputDescriptor> &desc)
}
status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attributes,
- sp<AudioOutputDescriptor> &desc)
+ sp<SwAudioOutputDescriptor> &desc)
{
for (size_t i = 0; i < size(); i++) {
sp<AudioPolicyMix> policyMix = valueAt(i);
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h b/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
index 4f5427e..6d43df2 100755
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
@@ -43,7 +43,7 @@ public:
virtual const AudioPolicyMixCollection &getAudioPolicyMixCollection() const = 0;
- virtual const AudioOutputCollection &getOutputs() const = 0;
+ virtual const SwAudioOutputCollection &getOutputs() const = 0;
virtual const AudioInputCollection &getInputs() const = 0;
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 417eebc..26a0d09 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -243,7 +243,7 @@ routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
{
- const AudioOutputCollection &outputs = mApmObserver->getOutputs();
+ const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
// usage to strategy mapping
switch (usage) {
@@ -291,7 +291,7 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
- const AudioOutputCollection &outputs = mApmObserver->getOutputs();
+ const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
uint32_t device = AUDIO_DEVICE_NONE;
uint32_t availableOutputDevicesType = availableOutputDevices.types();
@@ -582,7 +582,7 @@ audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) cons
{
const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
- const AudioOutputCollection &outputs = mApmObserver->getOutputs();
+ const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
uint32_t device = AUDIO_DEVICE_NONE;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index ffa689a..b5ff9a9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -157,7 +157,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
// outputs must be closed after checkOutputForAllStrategies() is executed
if (!outputs.isEmpty()) {
for (size_t i = 0; i < outputs.size(); i++) {
- sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
// close unused outputs after device disconnection or direct outputs that have been
// opened by checkOutputsForDevice() to query dynamic parameters
if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
@@ -176,18 +176,17 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
updateCallRouting(newDevice);
}
for (size_t i = 0; i < mOutputs.size(); i++) {
- audio_io_handle_t output = mOutputs.keyAt(i);
- if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) {
- audio_devices_t newDevice = getNewOutputDevice(mOutputs.keyAt(i),
- true /*fromCache*/);
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
+ audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
// do not force device change on duplicated output because if device is 0, it will
// also force a device 0 for the two outputs it is duplicated to which may override
// a valid device selection on those outputs.
- bool force = !mOutputs.valueAt(i)->isDuplicated()
+ bool force = !desc->isDuplicated()
&& (!device_distinguishes_on_address(device)
// always force when disconnecting (a non-duplicated device)
|| (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
- setOutputDevice(output, newDevice, force, 0);
+ setOutputDevice(desc, newDevice, force, 0);
}
}
@@ -349,7 +348,7 @@ void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs
AUDIO_OUTPUT_FLAG_NONE,
AUDIO_FORMAT_INVALID);
if (output != AUDIO_IO_HANDLE_NONE) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
ALOG_ASSERT(!outputDesc->isDuplicated(),
"updateCallRouting() RX device output is duplicated");
outputDesc->toAudioPortConfig(&patch.sources[1]);
@@ -450,13 +449,13 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)
checkOutputForAllStrategies();
updateDevicesAndOutputs();
- sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
+ sp<SwAudioOutputDescriptor> hwOutputDesc = mPrimaryOutput;
int delayMs = 0;
if (isStateInCall(state)) {
nsecs_t sysTime = systemTime();
for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
// mute media and sonification strategies and delay device switch by the largest
// latency of any output where either strategy is active.
// This avoid sending the ring tone or music tail into the earpiece or headset.
@@ -466,14 +465,14 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)
isStrategyActive(desc, STRATEGY_SONIFICATION,
SONIFICATION_HEADSET_MUSIC_DELAY,
sysTime)) &&
- (delayMs < (int)desc->mLatency*2)) {
- delayMs = desc->mLatency*2;
+ (delayMs < (int)desc->latency()*2)) {
+ delayMs = desc->latency()*2;
}
- setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
- setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
+ setStrategyMute(STRATEGY_MEDIA, true, desc);
+ setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
- setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i));
- setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS,
+ setStrategyMute(STRATEGY_SONIFICATION, true, desc);
+ setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
}
}
@@ -549,13 +548,13 @@ void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
updateCallRouting(newDevice);
}
for (size_t i = 0; i < mOutputs.size(); i++) {
- audio_io_handle_t output = mOutputs.keyAt(i);
- audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/);
- if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) {
- setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
+ audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
+ if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
+ setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE));
}
if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
- applyStreamVolumes(output, newDevice, 0, true);
+ applyStreamVolumes(outputDesc, newDevice, 0, true);
}
}
@@ -642,7 +641,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
}
stream_type_to_audio_attributes(*stream, &attributes);
}
- sp<AudioOutputDescriptor> desc;
+ sp<SwAudioOutputDescriptor> desc;
if (mPolicyMixes.getOutputForAttr(attributes, desc) == NO_ERROR) {
ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
if (!audio_is_linear_pcm(format)) {
@@ -713,7 +712,8 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
if (mTestOutputs[mCurOutput] == 0) {
ALOGV("getOutput() opening test output");
- sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
+ sp<AudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(NULL,
+ mpClientInterface);
outputDesc->mDevice = mTestDevice;
outputDesc->mLatency = mTestLatencyMs;
outputDesc->mFlags =
@@ -789,10 +789,10 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
}
if (profile != 0) {
- sp<AudioOutputDescriptor> outputDesc = NULL;
+ sp<SwAudioOutputDescriptor> outputDesc = NULL;
for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ 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
@@ -809,7 +809,7 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
if (outputDesc != NULL) {
closeOutput(outputDesc->mIoHandle);
}
- outputDesc = new AudioOutputDescriptor(profile);
+ outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
outputDesc->mDevice = device;
outputDesc->mLatency = 0;
outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
@@ -915,7 +915,7 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h
audio_io_handle_t outputPrimary = 0;
for (size_t i = 0; i < outputs.size(); i++) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
if (!outputDesc->isDuplicated()) {
// if a valid format is specified, skip output if not compatible
if (format != AUDIO_FORMAT_INVALID) {
@@ -962,8 +962,51 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
return BAD_VALUE;
}
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
+
+ audio_devices_t newDevice;
+ if (outputDesc->mPolicyMix != NULL) {
+ newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+ } else {
+ newDevice = AUDIO_DEVICE_NONE;
+ }
+
+ uint32_t delayMs = 0;
+
+ // Routing?
+ mOutputRoutes.incRouteActivity(session);
+
+ status_t status = startSource(outputDesc, stream, newDevice, &delayMs);
+
+ if (status != NO_ERROR) {
+ mOutputRoutes.decRouteActivity(session);
+ }
+ // Automatically enable the remote submix input when output is started on a re routing mix
+ // of type MIX_TYPE_RECORDERS
+ if (audio_is_remote_submix_device(newDevice) && outputDesc->mPolicyMix != NULL &&
+ outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
+ setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ outputDesc->mPolicyMix->mRegistrationId,
+ "remote-submix");
+ }
+
+ if (delayMs != 0) {
+ usleep(delayMs * 1000);
+ }
+
+ return status;
+}
+
+status_t AudioPolicyManager::startSource(sp<AudioOutputDescriptor> outputDesc,
+ audio_stream_type_t stream,
+ audio_devices_t device,
+ uint32_t *delayMs)
+{
// cannot start playback of STREAM_TTS if any other output is being used
uint32_t beaconMuteLatency = 0;
+
+ *delayMs = 0;
if (stream == AUDIO_STREAM_TTS) {
ALOGV("\t found BEACON stream");
if (mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
@@ -976,22 +1019,15 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT);
}
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
// increment usage count for this stream on the requested output:
// NOTE that the usage count is the same for duplicated output and hardware output which is
// necessary for a correct control of hardware output routing by startOutput() and stopOutput()
outputDesc->changeRefCount(stream, 1);
- // Routing?
- mOutputRoutes.incRouteActivity(session);
-
if (outputDesc->mRefCount[stream] == 1) {
// starting an output being rerouted?
- audio_devices_t newDevice;
- if (outputDesc->mPolicyMix != NULL) {
- newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
- } else {
- newDevice = getNewOutputDevice(output, false /*fromCache*/);
+ if (device == AUDIO_DEVICE_NONE) {
+ device = getNewOutputDevice(outputDesc, false /*fromCache*/);
}
routing_strategy strategy = getStrategy(stream);
bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
@@ -1007,7 +1043,7 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
// In this case, the audio HAL must receive the new device selection so that it can
// change the device currently selected by the other active output.
if (outputDesc->sharesHwModuleWith(desc) &&
- desc->device() != newDevice) {
+ desc->device() != device) {
force = true;
}
// wait for audio on other active outputs to be presented when starting
@@ -1019,7 +1055,7 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
}
}
}
- uint32_t muteWaitMs = setOutputDevice(output, newDevice, force);
+ uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force);
// handle special case for sonification while in call
if (isInCall()) {
@@ -1028,32 +1064,18 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
// apply volume rules for current stream and device if necessary
checkAndSetVolume(stream,
- mStreams[stream].getVolumeIndex(newDevice),
- output,
- newDevice);
+ mStreams.valueFor(stream).getVolumeIndex(device),
+ outputDesc,
+ device);
// update the outputs if starting an output with a stream that can affect notification
// routing
handleNotificationRoutingForStream(stream);
- // Automatically enable the remote submix input when output is started on a re routing mix
- // of type MIX_TYPE_RECORDERS
- if (audio_is_remote_submix_device(newDevice) && outputDesc->mPolicyMix != NULL &&
- outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
- setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
- AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- outputDesc->mPolicyMix->mRegistrationId,
- "remote-submix");
- }
-
// force reevaluating accessibility routing when ringtone or alarm starts
if (strategy == STRATEGY_SONIFICATION) {
mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
}
-
- if (waitMs > muteWaitMs) {
- usleep((waitMs - muteWaitMs) * 2 * 1000);
- }
}
return NO_ERROR;
}
@@ -1070,8 +1092,32 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
return BAD_VALUE;
}
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
+
+ if (outputDesc->mRefCount[stream] == 1) {
+ // Automatically disable the remote submix input when output is stopped on a
+ // re routing mix of type MIX_TYPE_RECORDERS
+ if (audio_is_remote_submix_device(outputDesc->mDevice) &&
+ outputDesc->mPolicyMix != NULL &&
+ outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
+ setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
+ AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ outputDesc->mPolicyMix->mRegistrationId,
+ "remote-submix");
+ }
+ }
+
+ // Routing?
+ if (outputDesc->mRefCount[stream] > 0) {
+ mOutputRoutes.decRouteActivity(session);
+ }
+ return stopSource(outputDesc, stream);
+}
+
+status_t AudioPolicyManager::stopSource(sp<AudioOutputDescriptor> outputDesc,
+ audio_stream_type_t stream)
+{
// always handle stream stop, check which stream type is stopping
handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
@@ -1084,44 +1130,30 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
// decrement usage count of this stream on the output
outputDesc->changeRefCount(stream, -1);
- // Routing?
- mOutputRoutes.decRouteActivity(session);
-
// store time at which the stream was stopped - see isStreamActive()
if (outputDesc->mRefCount[stream] == 0) {
- // Automatically disable the remote submix input when output is stopped on a
- // re routing mix of type MIX_TYPE_RECORDERS
- if (audio_is_remote_submix_device(outputDesc->mDevice) &&
- outputDesc->mPolicyMix != NULL &&
- outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
- setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
- AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- outputDesc->mPolicyMix->mRegistrationId,
- "remote-submix");
- }
-
outputDesc->mStopTime[stream] = systemTime();
- audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);
+ audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
// delay the device switch by twice the latency because stopOutput() is executed when
// the track stop() command is received and at that time the audio track buffer can
// still contain data that needs to be drained. The latency only covers the audio HAL
// and kernel buffers. Also the latency does not always include additional delay in the
// audio path (audio DSP, CODEC ...)
- setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
+ setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
// force restoring the device selection on other active outputs if it differs from the
// one being selected for this output
for (size_t i = 0; i < mOutputs.size(); i++) {
audio_io_handle_t curOutput = mOutputs.keyAt(i);
sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
- if (curOutput != output &&
+ if (desc != outputDesc &&
desc->isActive() &&
outputDesc->sharesHwModuleWith(desc) &&
(newDevice != desc->device())) {
- setOutputDevice(curOutput,
- getNewOutputDevice(curOutput, false /*fromCache*/),
+ setOutputDevice(desc,
+ getNewOutputDevice(desc, false /*fromCache*/),
true,
- outputDesc->mLatency*2);
+ outputDesc->latency()*2);
}
}
// update the outputs if stopping one with a stream that can affect notification routing
@@ -1129,7 +1161,7 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
}
return NO_ERROR;
} else {
- ALOGW("stopOutput() refcount is already 0 for output %d", output);
+ ALOGW("stopOutput() refcount is already 0");
return INVALID_OPERATION;
}
}
@@ -1161,7 +1193,7 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
// Routing
mOutputRoutes.removeRoute(session);
- sp<AudioOutputDescriptor> desc = mOutputs.valueAt(index);
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(index);
if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
if (desc->mDirectOpenCount <= 0) {
ALOGW("releaseOutput() invalid open count %d for output %d",
@@ -1173,8 +1205,9 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
// If effects where present on the output, audioflinger moved them to the primary
// output by default: move them back to the appropriate output.
audio_io_handle_t dstOutput = getOutputForEffect();
- if (dstOutput != mPrimaryOutput) {
- mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput);
+ if (dstOutput != mPrimaryOutput->mIoHandle) {
+ mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX,
+ mPrimaryOutput->mIoHandle, dstOutput);
}
mpClientInterface->onAudioPortListUpdate();
}
@@ -1528,8 +1561,8 @@ status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
audio_devices_t device)
{
- if ((index < mStreams[stream].getVolumeIndexMin()) ||
- (index > mStreams[stream].getVolumeIndexMax())) {
+ if ((index < mStreams.valueFor(stream).getVolumeIndexMin()) ||
+ (index > mStreams.valueFor(stream).getVolumeIndexMax())) {
return BAD_VALUE;
}
if (!audio_is_output_device(device)) {
@@ -1537,7 +1570,7 @@ status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
}
// Force max volume if stream cannot be muted
- if (!mStreams.canBeMuted(stream)) index = mStreams[stream].getVolumeIndexMax();
+ if (!mStreams.canBeMuted(stream)) index = mStreams.valueFor(stream).getVolumeIndexMax();
ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
stream, device, index);
@@ -1566,16 +1599,17 @@ status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
}
status_t status = NO_ERROR;
for (size_t i = 0; i < mOutputs.size(); i++) {
- audio_devices_t curDevice = Volume::getDeviceForVolume(mOutputs.valueAt(i)->device());
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device());
if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & strategyDevice) != 0)) {
- status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
+ status_t volStatus = checkAndSetVolume(stream, index, desc, curDevice);
if (volStatus != NO_ERROR) {
status = volStatus;
}
}
if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & accessibilityDevice) != 0)) {
status_t volStatus = checkAndSetVolume(AUDIO_STREAM_ACCESSIBILITY,
- index, mOutputs.keyAt(i), curDevice);
+ index, desc, curDevice);
}
}
return status;
@@ -1598,7 +1632,7 @@ status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
}
device = Volume::getDeviceForVolume(device);
- *index = mStreams[stream].getVolumeIndex(device);
+ *index = mStreams.valueFor(stream).getVolumeIndex(device);
ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
return NO_ERROR;
}
@@ -1622,7 +1656,7 @@ audio_io_handle_t AudioPolicyManager::selectOutputForEffects(
audio_io_handle_t outputDeepBuffer = 0;
for (size_t i = 0; i < outputs.size(); i++) {
- sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
outputOffloaded = outputs[i];
@@ -1676,6 +1710,16 @@ status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
return mEffects.registerEffect(desc, io, strategy, session, id);
}
+bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
+{
+ return mOutputs.isStreamActive(stream, inPastMs);
+}
+
+bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
+{
+ return mOutputs.isStreamActiveRemotely(stream, inPastMs);
+}
+
bool AudioPolicyManager::isSourceActive(audio_source_t source) const
{
for (size_t i = 0; i < mInputs.size(); i++) {
@@ -1826,7 +1870,7 @@ status_t AudioPolicyManager::dump(int fd)
snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
result.append(buffer);
- snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput);
+ snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput->mIoHandle);
result.append(buffer);
snprintf(buffer, SIZE, " Phone state: %d\n", mEngine->getPhoneState());
result.append(buffer);
@@ -2044,7 +2088,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
}
if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
if (outputDesc == NULL) {
ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
return BAD_VALUE;
@@ -2092,7 +2136,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
// TODO: reconfigure output format and channels here
ALOGV("createAudioPatch() setting device %08x on output %d",
devices.types(), outputDesc->mIoHandle);
- setOutputDevice(outputDesc->mIoHandle, devices.types(), true, 0, handle);
+ setOutputDevice(outputDesc, devices.types(), true, 0, handle);
index = mAudioPatches.indexOfKey(*handle);
if (index >= 0) {
if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
@@ -2270,14 +2314,14 @@ status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle,
struct audio_patch *patch = &patchDesc->mPatch;
patchDesc->mUid = mUidCached;
if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
if (outputDesc == NULL) {
ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
return BAD_VALUE;
}
- setOutputDevice(outputDesc->mIoHandle,
- getNewOutputDevice(outputDesc->mIoHandle, true /*fromCache*/),
+ setOutputDevice(outputDesc,
+ getNewOutputDevice(outputDesc, true /*fromCache*/),
true,
0,
NULL);
@@ -2336,7 +2380,7 @@ status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *
sp<AudioPortConfig> audioPortConfig;
if (config->type == AUDIO_PORT_TYPE_MIX) {
if (config->role == AUDIO_PORT_ROLE_SOURCE) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(config->id);
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(config->id);
if (outputDesc == NULL) {
return BAD_VALUE;
}
@@ -2418,7 +2462,6 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
#ifdef AUDIO_POLICY_TEST
Thread(false),
#endif //AUDIO_POLICY_TEST
- mPrimaryOutput((audio_io_handle_t)0),
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false),
mSpeakerDrcEnabled(false),
@@ -2502,7 +2545,8 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
if ((profileType & outputDeviceTypes) == 0) {
continue;
}
- sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile);
+ sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
+ mpClientInterface);
outputDesc->mDevice = profileType;
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
@@ -2538,10 +2582,10 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
}
if (mPrimaryOutput == 0 &&
outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
- mPrimaryOutput = output;
+ mPrimaryOutput = outputDesc;
}
addOutput(output, outputDesc);
- setOutputDevice(output,
+ setOutputDevice(outputDesc,
outputDesc->mDevice,
true);
}
@@ -2648,7 +2692,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
if (mPrimaryOutput != 0) {
AudioParameter outputCmd = AudioParameter();
outputCmd.addInt(String8("set_id"), 0);
- mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
+ mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, outputCmd.toString());
mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
mTestSamplingRate = 44100;
@@ -2788,20 +2832,21 @@ bool AudioPolicyManager::threadLoop()
if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
param.remove(String8("test_cmd_policy_reopen"));
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
- mpClientInterface->closeOutput(mPrimaryOutput);
+ mpClientInterface->closeOutput(mpClientInterface->closeOutput(mPrimaryOutput););
- audio_module_handle_t moduleHandle = outputDesc->getModuleHandle();
+ audio_module_handle_t moduleHandle = mPrimaryOutput->getModuleHandle();
- removeOutput(mPrimaryOutput);
- sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
+ removeOutput(mPrimaryOutput->mIoHandle);
+ sp<SwAudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL,
+ mpClientInterface);
outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = outputDesc->mSamplingRate;
config.channel_mask = outputDesc->mChannelMask;
config.format = outputDesc->mFormat;
+ audio_io_handle_t handle;
status_t status = mpClientInterface->openOutput(moduleHandle,
- &mPrimaryOutput,
+ &handle,
&config,
&outputDesc->mDevice,
String8(""),
@@ -2815,10 +2860,11 @@ bool AudioPolicyManager::threadLoop()
outputDesc->mSamplingRate = config.sample_rate;
outputDesc->mChannelMask = config.channel_mask;
outputDesc->mFormat = config.format;
+ mPrimaryOutput = outputDesc;
AudioParameter outputCmd = AudioParameter();
outputCmd.addInt(String8("set_id"), 0);
- mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
- addOutput(mPrimaryOutput, outputDesc);
+ mpClientInterface->setParameters(handle, outputCmd.toString());
+ addOutput(handle, outputDesc);
}
}
@@ -2850,7 +2896,7 @@ int AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
// ---
-void AudioPolicyManager::addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc)
+void AudioPolicyManager::addOutput(audio_io_handle_t output, sp<SwAudioOutputDescriptor> outputDesc)
{
outputDesc->setIoHandle(output);
mOutputs.add(output, outputDesc);
@@ -2869,7 +2915,7 @@ void AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescript
nextAudioPortGeneration();
}
-void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
+void AudioPolicyManager::findIoHandlesByAddress(sp<SwAudioOutputDescriptor> desc /*in*/,
const audio_devices_t device /*in*/,
const String8 address /*in*/,
SortedVector<audio_io_handle_t>& outputs /*out*/) {
@@ -2888,7 +2934,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de
const String8 address)
{
audio_devices_t device = devDesc->type();
- sp<AudioOutputDescriptor> desc;
+ sp<SwAudioOutputDescriptor> desc;
// erase all current sample rates, formats and channel masks
devDesc->clearCapabilities();
@@ -2896,7 +2942,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de
// first list already open outputs that can be routed to this device
for (size_t i = 0; i < mOutputs.size(); i++) {
desc = mOutputs.valueAt(i);
- if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) {
+ if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
if (!device_distinguishes_on_address(device)) {
ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
outputs.add(mOutputs.keyAt(i));
@@ -2955,7 +3001,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de
ALOGV("opening output for device %08x with params %s profile %p",
device, address.string(), profile.get());
- desc = new AudioOutputDescriptor(profile);
+ desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
desc->mDevice = device;
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = desc->mSamplingRate;
@@ -3068,28 +3114,29 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de
audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
// set initial stream volume for device
- applyStreamVolumes(output, device, 0, true);
+ applyStreamVolumes(desc, device, 0, true);
//TODO: configure audio effect output stage here
// open a duplicating output thread for the new output and the primary output
- duplicatedOutput = mpClientInterface->openDuplicateOutput(output,
- mPrimaryOutput);
+ duplicatedOutput =
+ mpClientInterface->openDuplicateOutput(output,
+ mPrimaryOutput->mIoHandle);
if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
// add duplicated output descriptor
- sp<AudioOutputDescriptor> dupOutputDesc =
- new AudioOutputDescriptor(NULL);
- dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
- dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
+ sp<SwAudioOutputDescriptor> dupOutputDesc =
+ new SwAudioOutputDescriptor(NULL, mpClientInterface);
+ dupOutputDesc->mOutput1 = mPrimaryOutput;
+ dupOutputDesc->mOutput2 = desc;
dupOutputDesc->mSamplingRate = desc->mSamplingRate;
dupOutputDesc->mFormat = desc->mFormat;
dupOutputDesc->mChannelMask = desc->mChannelMask;
dupOutputDesc->mLatency = desc->mLatency;
addOutput(duplicatedOutput, dupOutputDesc);
- applyStreamVolumes(duplicatedOutput, device, 0, true);
+ applyStreamVolumes(dupOutputDesc, device, 0, true);
} else {
ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
- mPrimaryOutput, output);
+ mPrimaryOutput->mIoHandle, output);
mpClientInterface->closeOutput(output);
removeOutput(output);
nextAudioPortGeneration();
@@ -3111,7 +3158,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de
if (device_distinguishes_on_address(device)) {
ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)",
device, address.string());
- setOutputDevice(output, device, true/*force*/, 0/*delay*/,
+ setOutputDevice(desc, device, true/*force*/, 0/*delay*/,
NULL/*patch handle*/, address.string());
}
ALOGV("checkOutputsForDevice(): adding output %d", output);
@@ -3129,10 +3176,9 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de
if (!desc->isDuplicated()) {
// exact match on device
if (device_distinguishes_on_address(device) &&
- (desc->mProfile->mSupportedDevices.types() == device)) {
+ (desc->supportedDevices() == device)) {
findIoHandlesByAddress(desc, device, address, outputs);
- } else if (!(desc->mProfile->mSupportedDevices.types()
- & mAvailableOutputDevices.types())) {
+ } else if (!(desc->supportedDevices() & mAvailableOutputDevices.types())) {
ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
mOutputs.keyAt(i));
outputs.add(mOutputs.keyAt(i));
@@ -3367,7 +3413,7 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output)
{
ALOGV("closeOutput(%d)", output);
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
if (outputDesc == NULL) {
ALOGW("closeOutput() unknown output %d", output);
return;
@@ -3376,7 +3422,7 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output)
// look for duplicated outputs connected to the output being removed.
for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<AudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
+ sp<SwAudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
if (dupOutputDesc->isDuplicated() &&
(dupOutputDesc->mOutput1 == outputDesc ||
dupOutputDesc->mOutput2 == outputDesc)) {
@@ -3445,8 +3491,9 @@ void AudioPolicyManager::closeInput(audio_io_handle_t input)
mInputs.removeItem(input);
}
-SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device,
- AudioOutputCollection openOutputs)
+SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(
+ audio_devices_t device,
+ SwAudioOutputCollection openOutputs)
{
SortedVector<audio_io_handle_t> outputs;
@@ -3487,14 +3534,14 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
// associated with policies in the "before" and "after" output vectors
ALOGVV("checkOutputForStrategy(): policy related outputs");
for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
- const sp<AudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
+ const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
if (desc != 0 && desc->mPolicyMix != NULL) {
srcOutputs.add(desc->mIoHandle);
ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
}
}
for (size_t i = 0 ; i < mOutputs.size() ; i++) {
- const sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if (desc != 0 && desc->mPolicyMix != NULL) {
dstOutputs.add(desc->mIoHandle);
ALOGVV(" new outputs: adding %d", desc->mIoHandle);
@@ -3506,10 +3553,10 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
strategy, srcOutputs[0], dstOutputs[0]);
// mute strategy while moving tracks from one output to another
for (size_t i = 0; i < srcOutputs.size(); i++) {
- sp<AudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
if (isStrategyActive(desc, strategy)) {
- setStrategyMute(strategy, true, srcOutputs[i]);
- setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice);
+ setStrategyMute(strategy, true, desc);
+ setStrategyMute(strategy, false, desc, MUTE_TIME_MS, newDevice);
}
}
@@ -3606,12 +3653,11 @@ void AudioPolicyManager::checkA2dpSuspend()
}
}
-audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache)
+audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
+ bool fromCache)
{
audio_devices_t device = AUDIO_DEVICE_NONE;
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
-
ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
if (index >= 0) {
sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
@@ -3789,9 +3835,9 @@ uint32_t AudioPolicyManager::setBeaconMute(bool mute) {
ALOGV("\t muting %d", mute);
uint32_t maxLatency = 0;
for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
setStreamMute(AUDIO_STREAM_TTS, mute/*on*/,
- desc->mIoHandle,
+ desc,
0 /*delay*/, AUDIO_DEVICE_NONE);
const uint32_t latency = desc->latency() * 2;
if (latency > maxLatency) {
@@ -3855,7 +3901,7 @@ uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor>
for (size_t i = 0; i < NUM_STRATEGIES; i++) {
audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
- curDevice = curDevice & outputDesc->mProfile->mSupportedDevices.types();
+ curDevice = curDevice & outputDesc->supportedDevices();
bool mute = shouldMute && (curDevice & device) && (curDevice != device);
bool doMute = false;
@@ -3874,10 +3920,9 @@ uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor>
== AUDIO_DEVICE_NONE) {
continue;
}
- audio_io_handle_t curOutput = mOutputs.keyAt(j);
- ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d",
- mute ? "muting" : "unmuting", i, curDevice, curOutput);
- setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs);
+ ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x)",
+ mute ? "muting" : "unmuting", i, curDevice);
+ setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
if (isStrategyActive(desc, (routing_strategy)i)) {
if (mute) {
// FIXME: should not need to double latency if volume could be applied
@@ -3902,9 +3947,9 @@ uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor>
}
for (size_t i = 0; i < NUM_STRATEGIES; i++) {
if (isStrategyActive(outputDesc, (routing_strategy)i)) {
- setStrategyMute((routing_strategy)i, true, outputDesc->mIoHandle);
+ setStrategyMute((routing_strategy)i, true, outputDesc);
// do tempMute unmute after twice the mute wait time
- setStrategyMute((routing_strategy)i, false, outputDesc->mIoHandle,
+ setStrategyMute((routing_strategy)i, false, outputDesc,
muteWaitMs *2, device);
}
}
@@ -3919,32 +3964,31 @@ uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor>
return 0;
}
-uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
+uint32_t AudioPolicyManager::setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
audio_devices_t device,
bool force,
int delayMs,
audio_patch_handle_t *patchHandle,
const char* address)
{
- ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs);
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
+ ALOGV("setOutputDevice() device %04x delayMs %d", device, delayMs);
AudioParameter param;
uint32_t muteWaitMs;
if (outputDesc->isDuplicated()) {
- muteWaitMs = setOutputDevice(outputDesc->mOutput1->mIoHandle, device, force, delayMs);
- muteWaitMs += setOutputDevice(outputDesc->mOutput2->mIoHandle, device, force, delayMs);
+ muteWaitMs = setOutputDevice(outputDesc->subOutput1(), device, force, delayMs);
+ muteWaitMs += setOutputDevice(outputDesc->subOutput2(), device, force, delayMs);
return muteWaitMs;
}
// no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
// output profile
- if (device != AUDIO_DEVICE_NONE &&
- (device & outputDesc->mProfile->mSupportedDevices.types()) == 0) {
+ if ((device != AUDIO_DEVICE_NONE) &&
+ ((device & outputDesc->supportedDevices()) == 0)) {
return 0;
}
// filter devices according to output selected
- device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types());
+ device = (audio_devices_t)(device & outputDesc->supportedDevices());
audio_devices_t prevDevice = outputDesc->mDevice;
@@ -3964,8 +4008,7 @@ uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
if ((device == AUDIO_DEVICE_NONE || device == prevDevice) &&
!force &&
outputDesc->mPatchHandle != 0) {
- ALOGV("setOutputDevice() setting same device 0x%04x or null device for output %d",
- device, output);
+ ALOGV("setOutputDevice() setting same device 0x%04x or null device", device);
return muteWaitMs;
}
@@ -3973,7 +4016,7 @@ uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
// do the routing
if (device == AUDIO_DEVICE_NONE) {
- resetOutputDevice(output, delayMs, NULL);
+ resetOutputDevice(outputDesc, delayMs, NULL);
} else {
DeviceVector deviceList = (address == NULL) ?
mAvailableOutputDevices.getDevicesFromType(device)
@@ -4040,16 +4083,15 @@ uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
}
// update stream volumes according to new device
- applyStreamVolumes(output, device, delayMs);
+ applyStreamVolumes(outputDesc, device, delayMs);
return muteWaitMs;
}
-status_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output,
+status_t AudioPolicyManager::resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
int delayMs,
audio_patch_handle_t *patchHandle)
{
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
ssize_t index;
if (patchHandle) {
index = mAudioPatches.indexOfKey(*patchHandle);
@@ -4206,16 +4248,11 @@ audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t input
}
float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
- int index,
- audio_io_handle_t output,
- audio_devices_t device)
+ int index,
+ audio_devices_t device)
{
float volume = 1.0;
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
- if (device == AUDIO_DEVICE_NONE) {
- device = outputDesc->device();
- }
volume = mEngine->volIndexToAmpl(Volume::getDeviceCategory(device), stream, index);
// if a headset is connected, apply the following rules to ring tones and notifications
@@ -4242,8 +4279,7 @@ float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
mLimitRingtoneVolume) {
audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
float musicVol = computeVolume(AUDIO_STREAM_MUSIC,
- mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice),
- output,
+ mStreams.valueFor(AUDIO_STREAM_MUSIC).getVolumeIndex(musicDevice),
musicDevice);
float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ?
musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
@@ -4258,17 +4294,16 @@ float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
}
status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
- int index,
- audio_io_handle_t output,
- audio_devices_t device,
- int delayMs,
- bool force)
+ int index,
+ const sp<AudioOutputDescriptor>& outputDesc,
+ audio_devices_t device,
+ int delayMs,
+ bool force)
{
-
// do not change actual stream volume if the stream is muted
- if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
+ if (outputDesc->mMuteCount[stream] != 0) {
ALOGVV("checkAndSetVolume() stream %d muted count %d",
- stream, mOutputs.valueFor(output)->mMuteCount[stream]);
+ stream, outputDesc->mMuteCount[stream]);
return NO_ERROR;
}
audio_policy_forced_cfg_t forceUseForComm =
@@ -4281,45 +4316,28 @@ status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
return INVALID_OPERATION;
}
- float volume = computeVolume(stream, index, output, device);
- // unit gain if rerouting to external policy
- if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
- ssize_t index = mOutputs.indexOfKey(output);
- if (index >= 0) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
- if (outputDesc->mPolicyMix != NULL) {
- ALOGV("max gain when rerouting for output=%d", output);
- volume = 1.0f;
- }
- }
-
+ if (device == AUDIO_DEVICE_NONE) {
+ device = outputDesc->device();
}
- // We actually change the volume if:
- // - the float value returned by computeVolume() changed
- // - the force flag is set
- if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
- force) {
- mOutputs.valueFor(output)->mCurVolume[stream] = volume;
- ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
- // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
- // enabled
- if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
- mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs);
- }
- mpClientInterface->setStreamVolume(stream, volume, output, delayMs);
+
+ float volume = computeVolume(stream, index, device);
+ if (outputDesc->isFixedVolume(device)) {
+ volume = 1.0f;
}
+ outputDesc->setVolume(volume, stream, device, delayMs, force);
+
if (stream == AUDIO_STREAM_VOICE_CALL ||
stream == AUDIO_STREAM_BLUETOOTH_SCO) {
float voiceVolume;
// Force voice volume to max for bluetooth SCO as volume is managed by the headset
if (stream == AUDIO_STREAM_VOICE_CALL) {
- voiceVolume = (float)index/(float)mStreams[stream].getVolumeIndexMax();
+ voiceVolume = (float)index/(float)mStreams.valueFor(stream).getVolumeIndexMax();
} else {
voiceVolume = 1.0;
}
- if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
+ if (voiceVolume != mLastVoiceVolume && outputDesc == mPrimaryOutput) {
mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
mLastVoiceVolume = voiceVolume;
}
@@ -4328,20 +4346,20 @@ status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
return NO_ERROR;
}
-void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,
- audio_devices_t device,
- int delayMs,
- bool force)
+void AudioPolicyManager::applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
+ audio_devices_t device,
+ int delayMs,
+ bool force)
{
- ALOGVV("applyStreamVolumes() for output %d and device %x", output, device);
+ ALOGVV("applyStreamVolumes() for device %08x", device);
for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
if (stream == AUDIO_STREAM_PATCH) {
continue;
}
checkAndSetVolume((audio_stream_type_t)stream,
- mStreams[stream].getVolumeIndex(device),
- output,
+ mStreams.valueFor((audio_stream_type_t)stream).getVolumeIndex(device),
+ outputDesc,
device,
delayMs,
force);
@@ -4349,10 +4367,10 @@ void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,
}
void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
- bool on,
- audio_io_handle_t output,
- int delayMs,
- audio_devices_t device)
+ bool on,
+ const sp<AudioOutputDescriptor>& outputDesc,
+ int delayMs,
+ audio_devices_t device)
{
ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
@@ -4360,32 +4378,31 @@ void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
continue;
}
if (getStrategy((audio_stream_type_t)stream) == strategy) {
- setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device);
+ setStreamMute((audio_stream_type_t)stream, on, outputDesc, delayMs, device);
}
}
}
void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
- bool on,
- audio_io_handle_t output,
- int delayMs,
- audio_devices_t device)
+ bool on,
+ const sp<AudioOutputDescriptor>& outputDesc,
+ int delayMs,
+ audio_devices_t device)
{
- const StreamDescriptor &streamDesc = mStreams[stream];
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
+ const StreamDescriptor& streamDesc = mStreams.valueFor(stream);
if (device == AUDIO_DEVICE_NONE) {
device = outputDesc->device();
}
- ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x",
- stream, on, output, outputDesc->mMuteCount[stream], device);
+ ALOGVV("setStreamMute() stream %d, mute %d, mMuteCount %d device %04x",
+ stream, on, outputDesc->mMuteCount[stream], device);
if (on) {
if (outputDesc->mMuteCount[stream] == 0) {
if (streamDesc.canBeMuted() &&
((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
(mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
- checkAndSetVolume(stream, 0, output, device, delayMs);
+ checkAndSetVolume(stream, 0, outputDesc, device, delayMs);
}
}
// increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
@@ -4398,7 +4415,7 @@ void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
if (--outputDesc->mMuteCount[stream] == 0) {
checkAndSetVolume(stream,
streamDesc.getVolumeIndex(device),
- output,
+ outputDesc,
device,
delayMs);
}
@@ -4417,7 +4434,7 @@ void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
const routing_strategy stream_strategy = getStrategy(stream);
if ((stream_strategy == STRATEGY_SONIFICATION) ||
((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
+ sp<SwAudioOutputDescriptor> outputDesc = mPrimaryOutput;
ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
stream, starting, outputDesc->mDevice, stateChange);
if (outputDesc->mRefCount[stream]) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 9fab9ef..9baeeb6 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -173,19 +173,15 @@ public:
return mEffects.setEffectEnabled(id, enabled);
}
- virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const
- {
- return mOutputs.isStreamActive(stream, inPastMs);
- }
+ virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
// return whether a stream is playing remotely, override to change the definition of
// local/remote playback, used for instance by notification manager to not make
// media players lose audio focus when not playing locally
// For the base implementation, "remotely" means playing during screen mirroring which
// uses an output for playback with a non-empty, non "0" address.
- virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const
- {
- return mOutputs.isStreamActiveRemotely(stream, inPastMs);
- }
+ virtual bool isStreamActiveRemotely(audio_stream_type_t stream,
+ uint32_t inPastMs = 0) const;
+
virtual bool isSourceActive(audio_source_t source) const;
virtual status_t dump(int fd);
@@ -281,7 +277,7 @@ protected:
{
return mPolicyMixes;
}
- virtual const AudioOutputCollection &getOutputs() const
+ virtual const SwAudioOutputCollection &getOutputs() const
{
return mOutputs;
}
@@ -306,7 +302,7 @@ protected:
return mDefaultOutputDevice;
}
protected:
- void addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc);
+ void addOutput(audio_io_handle_t output, sp<SwAudioOutputDescriptor> outputDesc);
void removeOutput(audio_io_handle_t output);
void addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc);
@@ -329,13 +325,13 @@ protected:
// change the route of the specified output. Returns the number of ms we have slept to
// allow new routing to take effect in certain cases.
- virtual uint32_t setOutputDevice(audio_io_handle_t output,
+ virtual uint32_t setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
audio_devices_t device,
bool force = false,
int delayMs = 0,
audio_patch_handle_t *patchHandle = NULL,
const char* address = NULL);
- status_t resetOutputDevice(audio_io_handle_t output,
+ status_t resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
int delayMs = 0,
audio_patch_handle_t *patchHandle = NULL);
status_t setInputDevice(audio_io_handle_t input,
@@ -350,29 +346,31 @@ protected:
// compute the actual volume for a given stream according to the requested index and a particular
// device
- virtual float computeVolume(audio_stream_type_t stream, int index,
- audio_io_handle_t output, audio_devices_t device);
+ virtual float computeVolume(audio_stream_type_t stream,
+ int index,
+ audio_devices_t device);
// check that volume change is permitted, compute and send new volume to audio hardware
virtual status_t checkAndSetVolume(audio_stream_type_t stream, int index,
- audio_io_handle_t output,
+ const sp<AudioOutputDescriptor>& outputDesc,
audio_devices_t device,
int delayMs = 0, bool force = false);
// apply all stream volumes to the specified output and device
- void applyStreamVolumes(audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false);
+ void applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
+ audio_devices_t device, int delayMs = 0, bool force = false);
// Mute or unmute all streams handled by the specified strategy on the specified output
void setStrategyMute(routing_strategy strategy,
bool on,
- audio_io_handle_t output,
+ const sp<AudioOutputDescriptor>& outputDesc,
int delayMs = 0,
audio_devices_t device = (audio_devices_t)0);
// Mute or unmute the stream on the specified output
void setStreamMute(audio_stream_type_t stream,
bool on,
- audio_io_handle_t output,
+ const sp<AudioOutputDescriptor>& outputDesc,
int delayMs = 0,
audio_devices_t device = (audio_devices_t)0);
@@ -425,7 +423,8 @@ protected:
// must be called every time a condition that affects the device choice for a given output is
// changed: connected device, phone state, force use, output start, output stop..
// see getDeviceForStrategy() for the use of fromCache parameter
- audio_devices_t getNewOutputDevice(audio_io_handle_t output, bool fromCache);
+ audio_devices_t getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
+ bool fromCache);
// updates cache of device used by all strategies (mDeviceForStrategy[])
// must be called every time a condition that affects the device choice for a given strategy is
@@ -453,7 +452,7 @@ protected:
#endif //AUDIO_POLICY_TEST
SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device,
- AudioOutputCollection openOutputs);
+ SwAudioOutputCollection openOutputs);
bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
SortedVector<audio_io_handle_t>& outputs2);
@@ -494,25 +493,33 @@ protected:
audio_devices_t availablePrimaryOutputDevices() const
{
- return mOutputs.getSupportedDevices(mPrimaryOutput) & mAvailableOutputDevices.types();
+ return mPrimaryOutput->supportedDevices() & mAvailableOutputDevices.types();
}
audio_devices_t availablePrimaryInputDevices() const
{
- return mAvailableInputDevices.getDevicesFromHwModule(
- mOutputs.valueFor(mPrimaryOutput)->getModuleHandle());
+ return mAvailableInputDevices.getDevicesFromHwModule(mPrimaryOutput->getModuleHandle());
}
void updateCallRouting(audio_devices_t rxDevice, int delayMs = 0);
+ status_t startSource(sp<AudioOutputDescriptor> outputDesc,
+ audio_stream_type_t stream,
+ audio_devices_t device,
+ uint32_t *delayMs);
+ status_t stopSource(sp<AudioOutputDescriptor> outputDesc,
+ audio_stream_type_t stream);
+
uid_t mUidCached;
AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
- audio_io_handle_t mPrimaryOutput; // primary output handle
+ sp<SwAudioOutputDescriptor> mPrimaryOutput; // primary output descriptor
// list of descriptors for outputs currently opened
- AudioOutputCollection mOutputs;
+
+ SwAudioOutputCollection mOutputs;
// copy of mOutputs before setDeviceConnectionState() opens new outputs
// reset to mOutputs when updateDevicesAndOutputs() is called.
- AudioOutputCollection mPreviousOutputs;
+ SwAudioOutputCollection mPreviousOutputs;
AudioInputCollection mInputs; // list of input descriptors
+
DeviceVector mAvailableOutputDevices; // all available output devices
DeviceVector mAvailableInputDevices; // all available input devices
@@ -583,7 +590,7 @@ private:
// in mProfile->mSupportedDevices) matches the device whose address is to be matched.
// see deviceDistinguishesOnAddress(audio_devices_t) for whether the device type is one
// where addresses are used to distinguish between one connected device and another.
- void findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
+ void findIoHandlesByAddress(sp<SwAudioOutputDescriptor> desc /*in*/,
const audio_devices_t device /*in*/,
const String8 address /*in*/,
SortedVector<audio_io_handle_t>& outputs /*out*/);