From 0479d7c79a7fd6f112e8dc7e45c009cf6602dbaa Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Thu, 14 Jan 2016 02:46:40 -0800 Subject: audiopolicy: Add notification when default effects are updated * In M, we now have the ability to define a default set of audio effect on a per-stream basis. This allows us to get around the problem of apps not sending the control intents so we can implement smart global effects for specific media types. * We still need a session id in order to get a handle and configure them from an app like AudioFX, so we'll need to add some plumbing in order to send an event to interested applications. * This patch implements the native side of this. The Java layer will call down thru AudioSystem and register a callback which will be invoked by the audio policy when default effects are updated on a stream. This callback will receive both the stream type as well as the session id. * Attaching this listener requires that the caller hold the MODIFY_AUDIO_ROUTING permission. Change-Id: I142b15f2585ffca6a953c3e828e2a7c07b24f56c --- services/audiopolicy/service/AudioPolicyService.h | 27 +++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'services/audiopolicy/service/AudioPolicyService.h') diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index d11294b..27a62f4 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -202,6 +202,8 @@ public: audio_io_handle_t *handle); virtual status_t stopAudioSource(audio_io_handle_t handle); + virtual status_t setEffectSessionCallbacksEnabled(bool enabled); + status_t doStartOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session); @@ -229,6 +231,11 @@ public: void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); void doOnDynamicPolicyMixStateUpdate(String8 regId, int32_t state); + void onOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); + void doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); + private: AudioPolicyService() ANDROID_API; virtual ~AudioPolicyService(); @@ -260,7 +267,8 @@ private: UPDATE_AUDIOPORT_LIST, UPDATE_AUDIOPATCH_LIST, SET_AUDIOPORT_CONFIG, - DYN_POLICY_MIX_STATE_UPDATE + DYN_POLICY_MIX_STATE_UPDATE, + EFFECT_SESSION_UPDATE }; AudioCommandThread (String8 name, const wp& service); @@ -303,6 +311,8 @@ private: int delayMs); void dynamicPolicyMixStateUpdateCommand(String8 regId, int32_t state); void insertCommand_l(AudioCommand *command, int delayMs = 0); + void effectSessionUpdateCommand(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); private: class AudioCommandData; @@ -399,6 +409,13 @@ private: int32_t mState; }; + class EffectSessionUpdateData : public AudioCommandData { + public: + audio_stream_type_t mStream; + audio_unique_id_t mSessionId; + bool mAdded; + }; + Mutex mLock; Condition mWaitWorkCV; Vector < sp > mAudioCommands; // list of pending commands @@ -508,6 +525,9 @@ private: virtual audio_unique_id_t newAudioUniqueId(); + virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); + private: AudioPolicyService *mAudioPolicyService; }; @@ -524,7 +544,9 @@ private: void onAudioPatchListUpdate(); void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); void setAudioPortCallbacksEnabled(bool enabled); - + void setEffectSessionCallbacksEnabled(bool enabled); + void onOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, bool added); // IBinder::DeathRecipient virtual void binderDied(const wp& who); @@ -536,6 +558,7 @@ private: const uid_t mUid; const sp mAudioPolicyServiceClient; bool mAudioPortCallbacksEnabled; + bool mEffectSessionCallbacksEnabled; }; // Internal dump utilities. -- cgit v1.1 From 47f8c7303c9e2054f1492b02b6c7472385c52dc9 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 7 Mar 2016 03:43:14 -0800 Subject: audiopolicy: Defer release of output session effects * Some effects modules are racy and don't tolerate being destroyed and immediately resurrected on the same session. This is the common case when switching tracks, and the use of default output effects makes the problem even worse. Certain apps which handle gapless in a sloppy way are also to blame. * Instead of immediately nuking the entire descriptor with the stream, just decrease the refcount and defer it for 10 seconds. If it needs resurrected, the refcount will be increased and the delayed release command will not shoot it in the face. Change-Id: I068dd72c4180023a74eb9ccbe8a180f6f0683dbf --- services/audiopolicy/service/AudioPolicyService.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'services/audiopolicy/service/AudioPolicyService.h') diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index 27a62f4..9b17a26 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -235,6 +235,10 @@ public: audio_unique_id_t sessionId, bool added); void doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, audio_unique_id_t sessionId, bool added); + void releaseOutputSessionEffectsDelayed(audio_io_handle_t output, + audio_stream_type_t stream, + audio_unique_id_t sessionId, + int delayMs); private: AudioPolicyService() ANDROID_API; @@ -268,7 +272,8 @@ private: UPDATE_AUDIOPATCH_LIST, SET_AUDIOPORT_CONFIG, DYN_POLICY_MIX_STATE_UPDATE, - EFFECT_SESSION_UPDATE + EFFECT_SESSION_UPDATE, + RELEASE_OUTPUT_SESSION_EFFECTS, }; AudioCommandThread (String8 name, const wp& service); @@ -313,6 +318,10 @@ private: void insertCommand_l(AudioCommand *command, int delayMs = 0); void effectSessionUpdateCommand(audio_stream_type_t stream, audio_unique_id_t sessionId, bool added); + void releaseOutputSessionEffectsCommand(audio_io_handle_t output, + audio_stream_type_t stream, + audio_unique_id_t sessionId, + int delayMs = 0); private: class AudioCommandData; @@ -416,6 +425,13 @@ private: bool mAdded; }; + class ReleaseOutputSessionEffectsData : public AudioCommandData { + public: + audio_io_handle_t mOutput; + audio_stream_type_t mStream; + audio_unique_id_t mSessionId; + }; + Mutex mLock; Condition mWaitWorkCV; Vector < sp > mAudioCommands; // list of pending commands -- cgit v1.1