[BUG] AudioPolicyManager: prevent patch leak on SwOutput used for bridges
When using either SwBridge or HwBridge, a SwOutput is always involved.
SwBridge: for playback, HwBridge: for volume control (it hosts the
Source Client).
When the bridge ends, the SwOutput shall be rerouted (Sw) or
unrouted (Hw bridge to prevent patch leak).
This CL generalizes the ClientDescriptor usage for all audio patches.
For patches created from APM::createAudioPatch API or call patches witch
are not associated to an active client, it creates an internal client descriptor.
Sink device is expressed as a preferredDevices. Then APM forbids to change
it using UID enforcement in getNewOutputDevices.
It alos allows to track client hence volume sources active on a SwOutput,
even for HwBridge. Waiting for cleaner HwAudioOutputDescriptor, we will use
the mandatory SwOutput declared in configuration file for a given sink device
for HwBridge to attach the Audio Source and control activity, thus volume.
This SwOutput will be routed (aka setOutputDevices to be called) and unrouted
if not needed anymore.
Bug: 187173302
Test: build & audio UC involving bridges
(functional on emulator):
adb shell ./data/AudioPolicyEmulatorTests --gtest_filter=*AudioPatchTest*
adb shell ./data/AudioPolicyEmulatorTests --gtest_filter=*AudioSourceTest*
Signed-off-by: Francois Gaffie <francois.gaffie@renault.com>
Change-Id: Ib4dc2ae32a89464bd8ac3b96833f324760012799
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index ac8b625..3accb7f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -266,10 +266,7 @@
virtual status_t getAudioPort(struct audio_port_v7 *port);
virtual status_t createAudioPatch(const struct audio_patch *patch,
audio_patch_handle_t *handle,
- uid_t uid) {
- return createAudioPatchInternal(patch, handle, uid);
- }
-
+ uid_t uid);
virtual status_t releaseAudioPatch(audio_patch_handle_t handle,
uid_t uid);
virtual status_t listAudioPatches(unsigned int *num_patches,
@@ -647,7 +644,12 @@
void connectTelephonyRxAudioSource();
- void disconnectTelephonyRxAudioSource();
+ void disconnectTelephonyAudioSource(audio_port_handle_t &portHandle);
+
+ void connectTelephonyTxAudioSource(const sp<DeviceDescriptor> &srcdevice,
+ const sp<DeviceDescriptor> &sinkDevice,
+ uint32_t delayMs);
+
/**
* @brief updates routing for all inputs.
@@ -854,6 +856,12 @@
status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
status_t disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
+ status_t connectAudioSourceToSink(const sp<SourceClientDescriptor>& sourceDesc,
+ const sp<DeviceDescriptor> &sinkDevice,
+ const struct audio_patch *patch,
+ audio_patch_handle_t &handle,
+ uid_t uid, uint32_t delayMs);
+
sp<SourceClientDescriptor> getSourceForAttributesOnOutput(audio_io_handle_t output,
const audio_attributes_t &attr);
void clearAudioSourcesForOutput(audio_io_handle_t output);
@@ -904,8 +912,6 @@
SoundTriggerSessionCollection mSoundTriggerSessions;
- sp<AudioPatch> mCallTxPatch;
-
HwAudioOutputCollection mHwOutputs;
SourceClientCollection mAudioSources;
@@ -947,6 +953,7 @@
// The port handle of the hardware audio source created internally for the Call RX audio
// end point.
audio_port_handle_t mCallRxSourceClientPort = AUDIO_PORT_HANDLE_NONE;
+ audio_port_handle_t mCallTxSourceClientPort = AUDIO_PORT_HANDLE_NONE;
// Support for Multi-Stream Decoder (MSD) module
sp<DeviceDescriptor> getMsdAudioInDevice() const;
@@ -978,6 +985,8 @@
// Called by setDeviceConnectionState()
status_t deviceToAudioPort(audio_devices_t deviceType, const char* device_address,
const char* device_name, media::AudioPort* aidPort);
+ bool isMsdPatch(const audio_patch_handle_t &handle) const;
+
private:
void onNewAudioModulesAvailableInt(DeviceVector *newDevices);
@@ -1123,21 +1132,25 @@
* @param[out] handle patch handle to be provided if patch installed correctly
* @param[in] uid of the client
* @param[in] delayMs if required
- * @param[in] sourceDesc [optional] in case of external source, source client to be
- * configured by the patch, i.e. assigning an Output (HW or SW)
+ * @param[in] sourceDesc source client to be configured when creating the patch, i.e.
+ * assigning an Output (HW or SW) used for volume control.
* @return NO_ERROR if patch installed correctly, error code otherwise.
*/
status_t createAudioPatchInternal(const struct audio_patch *patch,
audio_patch_handle_t *handle,
- uid_t uid, uint32_t delayMs = 0,
- const sp<SourceClientDescriptor>& sourceDesc = nullptr);
+ uid_t uid, uint32_t delayMs,
+ const sp<SourceClientDescriptor>& sourceDesc);
/**
* @brief releaseAudioPatchInternal internal function to remove an audio patch
* @param[in] handle of the patch to be removed
* @param[in] delayMs if required
+ * @param[in] sourceDesc [optional] in case of external source, source client to be
+ * unrouted from the patch, i.e. assigning an Output (HW or SW)
* @return NO_ERROR if patch removed correctly, error code otherwise.
*/
- status_t releaseAudioPatchInternal(audio_patch_handle_t handle, uint32_t delayMs = 0);
+ status_t releaseAudioPatchInternal(audio_patch_handle_t handle,
+ uint32_t delayMs = 0,
+ const sp<SourceClientDescriptor>& sourceDesc = nullptr);
status_t installPatch(const char *caller,
audio_patch_handle_t *patchHandle,