audiopolicy: exclusive Preferred Device
It allows to force the routing of music during call without
affecting clients that does not explicitely requested to use
another device than the one decided by the policy during call
(which is TELEPHONY TX).
It fixes differently Bug 111467967.
Test: make
Change-Id: I6034f0d2568e1b2a1e600d9ae1453fd0c60ed02e
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index 2fb1277..4c069e4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -41,10 +41,12 @@
{
public:
ClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
- audio_attributes_t attributes, audio_config_base_t config,
- audio_port_handle_t preferredDeviceId) :
+ audio_attributes_t attributes, audio_config_base_t config,
+ audio_port_handle_t preferredDeviceId,
+ bool isPreferredDeviceForExclusiveUse = false) :
mPortId(portId), mUid(uid), mSessionId(sessionId), mAttributes(attributes),
- mConfig(config), mPreferredDeviceId(preferredDeviceId), mActive(false) {}
+ mConfig(config), mPreferredDeviceId(preferredDeviceId), mActive(false),
+ mPreferredDeviceForExclusiveUse(isPreferredDeviceForExclusiveUse){}
~ClientDescriptor() override = default;
virtual void dump(String8 *dst, int spaces, int index) const;
@@ -58,7 +60,8 @@
audio_port_handle_t preferredDeviceId() const { return mPreferredDeviceId; };
void setPreferredDeviceId(audio_port_handle_t preferredDeviceId) {
mPreferredDeviceId = preferredDeviceId;
- };
+ }
+ bool isPreferredDeviceForExclusiveUse() const { return mPreferredDeviceForExclusiveUse; }
void setActive(bool active) { mActive = active; }
bool active() const { return mActive; }
bool hasPreferredDevice(bool activeOnly = false) const {
@@ -73,16 +76,19 @@
const audio_config_base_t mConfig;
audio_port_handle_t mPreferredDeviceId; // selected input device port ID
bool mActive;
+ bool mPreferredDeviceForExclusiveUse = false;
};
class TrackClientDescriptor: public ClientDescriptor
{
public:
TrackClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
- audio_attributes_t attributes, audio_config_base_t config,
- audio_port_handle_t preferredDeviceId, audio_stream_type_t stream,
- product_strategy_t strategy, audio_output_flags_t flags) :
- ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId),
+ audio_attributes_t attributes, audio_config_base_t config,
+ audio_port_handle_t preferredDeviceId, audio_stream_type_t stream,
+ product_strategy_t strategy, audio_output_flags_t flags,
+ bool isPreferredDeviceForExclusiveUse) :
+ ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId,
+ isPreferredDeviceForExclusiveUse),
mStream(stream), mStrategy(strategy), mFlags(flags) {}
~TrackClientDescriptor() override = default;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index d997bf7..1dfd88a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -258,7 +258,8 @@
for (const auto &client : getClientIterable()) {
if ((!activeOnly || client->active())
&& (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
- && (!preferredDeviceOnly || client->hasPreferredDevice())) {
+ && (!preferredDeviceOnly ||
+ (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
clients.push_back(client);
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
index 1525285..a6f6c3b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -85,7 +85,7 @@
product_strategy_t strategy) :
TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
AUDIO_CONFIG_BASE_INITIALIZER, AUDIO_PORT_HANDLE_NONE,
- stream, strategy, AUDIO_OUTPUT_FLAG_NONE),
+ stream, strategy, AUDIO_OUTPUT_FLAG_NONE, false),
mPatchDesc(patchDesc), mSrcDevice(srcDevice)
{
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 771f62a..126a5f7 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -916,7 +916,8 @@
uid_t uid,
const audio_config_t *config,
audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId)
+ audio_port_handle_t *selectedDeviceId,
+ bool *isRequestedDeviceForExclusiveUse)
{
DeviceVector outputDevices;
const audio_port_handle_t requestedPortId = *selectedDeviceId;
@@ -980,7 +981,7 @@
isInCall()) {
if (requestedPortId != AUDIO_PORT_HANDLE_NONE) {
*flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
- // @todo: provide another solution (separated CL)
+ *isRequestedDeviceForExclusiveUse = true;
}
}
@@ -1030,8 +1031,9 @@
}
const audio_port_handle_t requestedPortId = *selectedDeviceId;
audio_attributes_t resultAttr;
+ bool isRequestedDeviceForExclusiveUse = false;
status_t status = getOutputForAttrInt(&resultAttr, output, session, attr, stream, uid,
- config, flags, selectedDeviceId);
+ config, flags, selectedDeviceId, &isRequestedDeviceForExclusiveUse);
if (status != NO_ERROR) {
return status;
}
@@ -1045,7 +1047,7 @@
new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
requestedPortId, *stream,
mEngine->getProductStrategyForAttributes(resultAttr),
- *flags);
+ *flags, isRequestedDeviceForExclusiveUse);
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(*output);
outputDesc->addClient(clientDesc);
@@ -3633,8 +3635,10 @@
config.format = sourceDesc->config().format;
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ bool isRequestedDeviceForExclusiveUse = false;
getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE,
- &attributes, &stream, sourceDesc->uid(), &config, &flags, &selectedDeviceId);
+ &attributes, &stream, sourceDesc->uid(), &config, &flags,
+ &selectedDeviceId, &isRequestedDeviceForExclusiveUse);
if (output == AUDIO_IO_HANDLE_NONE) {
ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevices.types());
return INVALID_OPERATION;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 0bf40f4..73c3b56 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -710,7 +710,8 @@
uid_t uid,
const audio_config_t *config,
audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId);
+ audio_port_handle_t *selectedDeviceId,
+ bool *isRequestedDeviceForExclusiveUse);
// internal method to return the output handle for the given device and format
audio_io_handle_t getOutputForDevices(
const DeviceVector &devices,