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

Commit 0479d7c7 authored by Steve Kondik's avatar Steve Kondik Committed by Steve Kondik
Browse files

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
parent 51aee1e5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ namespace android {
//   AudioSystem's implementation of the AudioPolicyClient interface
// keep in sync with AudioSystem.java
#define DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE 0
#define AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE 10

#define MIX_STATE_DISABLED -1
#define MIX_STATE_IDLE 0
+7 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ namespace android {

typedef void (*audio_error_callback)(status_t err);
typedef void (*dynamic_policy_callback)(int event, String8 regId, int val);
typedef void (*effect_session_callback)(int event,
        audio_stream_type_t stream, audio_unique_id_t sessionId, bool added);

class IAudioFlinger;
class IAudioPolicyService;
@@ -92,6 +94,7 @@ public:

    static void setErrorCallback(audio_error_callback cb);
    static void setDynPolicyCallback(dynamic_policy_callback cb);
    static status_t setEffectSessionCallback(effect_session_callback cb);

    // helper function to obtain AudioFlinger service handle
    static const sp<IAudioFlinger> get_audio_flinger();
@@ -419,6 +422,9 @@ private:
        virtual void onAudioPortListUpdate();
        virtual void onAudioPatchListUpdate();
        virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
        virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
                                                  audio_unique_id_t sessionId,
                                                  bool added);

    private:
        Mutex                               mLock;
@@ -438,6 +444,7 @@ private:
    static sp<IAudioFlinger> gAudioFlinger;
    static audio_error_callback gAudioErrorCallback;
    static dynamic_policy_callback gDynPolicyCallback;
    static effect_session_callback gEffectSessionCallback;

    static size_t gInBuffSize;
    // previous parameters for recording buffer size queries
+2 −0
Original line number Diff line number Diff line
@@ -165,6 +165,8 @@ public:
                                      const audio_attributes_t *attributes,
                                      audio_io_handle_t *handle) = 0;
    virtual status_t stopAudioSource(audio_io_handle_t handle) = 0;

    virtual status_t setEffectSessionCallbacksEnabled(bool enabled) = 0;
};


+4 −0
Original line number Diff line number Diff line
@@ -37,6 +37,10 @@ public:
    virtual void onAudioPatchListUpdate() = 0;
    // Notifies a change in the mixing state of a specific mix in a dynamic audio policy
    virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;
    // Notifies when a default effect set is attached to a session/stream
    virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
                                              audio_unique_id_t sessionId,
                                              bool added) = 0;
};


+31 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ sp<IAudioFlinger> AudioSystem::gAudioFlinger;
sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;

effect_session_callback AudioSystem::gEffectSessionCallback = NULL;

// establish binder interface to AudioFlinger service
const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
@@ -652,6 +652,21 @@ status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
    gDynPolicyCallback = cb;
}

/*static*/ status_t AudioSystem::setEffectSessionCallback(effect_session_callback cb)
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;

    Mutex::Autolock _l(gLock);
    gEffectSessionCallback = cb;

    status_t status = aps->setEffectSessionCallbacksEnabled(cb != NULL);
    if (status != OK) {
        gEffectSessionCallback = NULL;
    }
    return status;
}

// client singleton for AudioPolicyService binder interface
// protected by gLockAPS
sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
@@ -1223,6 +1238,21 @@ void AudioSystem::AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate(
    }
}

void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate(
        audio_stream_type_t stream, audio_unique_id_t sessionId, bool added)
{
    ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)", stream, sessionId, added);
    effect_session_callback cb = NULL;
    {
        Mutex::Autolock _l(AudioSystem::gLock);
        cb = gEffectSessionCallback;
    }

    if (cb != NULL) {
        cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, stream, sessionId, added);
    }
}

void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
{
    {
Loading