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

Commit 000c3e44 authored by Ytai Ben-Tsvi's avatar Ytai Ben-Tsvi
Browse files

Support multiple error callbacks

Move from a single callback model to allow multiple registrations.
Created a separate mutex to guard the callback in order to simplify
the process of invoking the callbacks safely without holding the
main lock.

Change-Id: Id09aedda785e99b31c70cba1681a2ee392e9b06c
parent ab2ff056
Loading
Loading
Loading
Loading
+21 −12
Original line number Diff line number Diff line
@@ -36,10 +36,11 @@ namespace android {

// client singleton for AudioFlinger binder interface
Mutex AudioSystem::gLock;
Mutex AudioSystem::gLockErrorCallbacks;
Mutex AudioSystem::gLockAPS;
sp<IAudioFlinger> AudioSystem::gAudioFlinger;
sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
std::set<audio_error_callback> AudioSystem::gAudioErrorCallbacks;
dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
record_config_callback AudioSystem::gRecordConfigCallback = NULL;

@@ -63,9 +64,7 @@ const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
            if (gAudioFlingerClient == NULL) {
                gAudioFlingerClient = new AudioFlingerClient();
            } else {
                if (gAudioErrorCallback) {
                    gAudioErrorCallback(NO_ERROR);
                }
                reportError(NO_ERROR);
            }
            binder->linkToDeath(gAudioFlingerClient);
            gAudioFlinger = interface_cast<IAudioFlinger>(binder);
@@ -500,19 +499,16 @@ void AudioSystem::AudioFlingerClient::clearIoCache()

void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused)
{
    audio_error_callback cb = NULL;
    {
        Mutex::Autolock _l(AudioSystem::gLock);
        AudioSystem::gAudioFlinger.clear();
        cb = gAudioErrorCallback;
    }

    // clear output handles and stream to output map caches
    clearIoCache();

    if (cb) {
        cb(DEAD_OBJECT);
    }
    reportError(DEAD_OBJECT);

    ALOGW("AudioFlinger server died!");
}

@@ -717,10 +713,23 @@ status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
    return NO_ERROR;
}

/* static */ void AudioSystem::setErrorCallback(audio_error_callback cb)
/* static */ uintptr_t AudioSystem::addErrorCallback(audio_error_callback cb)
{
    Mutex::Autolock _l(gLock);
    gAudioErrorCallback = cb;
    Mutex::Autolock _l(gLockErrorCallbacks);
    gAudioErrorCallbacks.insert(cb);
    return reinterpret_cast<uintptr_t>(cb);
}

/* static */ void AudioSystem::removeErrorCallback(uintptr_t cb) {
    Mutex::Autolock _l(gLockErrorCallbacks);
    gAudioErrorCallbacks.erase(reinterpret_cast<audio_error_callback>(cb));
}

/* static */ void AudioSystem::reportError(status_t err) {
    Mutex::Autolock _l(gLockErrorCallbacks);
    for (auto callback : gAudioErrorCallbacks) {
      callback(err);
    }
}

/*static*/ void AudioSystem::setDynPolicyCallback(dynamic_policy_callback cb)
+17 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <media/IAudioFlingerClient.h>
#include <media/IAudioPolicyServiceClient.h>
#include <media/MicrophoneInfo.h>
#include <set>
#include <system/audio.h>
#include <system/audio_effect.h>
#include <system/audio_policy.h>
@@ -107,7 +108,16 @@ public:
    static status_t setParameters(const String8& keyValuePairs);
    static String8  getParameters(const String8& keys);

    static void setErrorCallback(audio_error_callback cb);
    // Registers an error callback. When this callback is invoked, it means all
    // state implied by this interface has been reset.
    // Returns a token that can be used for un-registering.
    // Might block while callbacks are being invoked.
    static uintptr_t addErrorCallback(audio_error_callback cb);

    // Un-registers a callback previously added with addErrorCallback.
    // Might block while callbacks are being invoked.
    static void removeErrorCallback(uintptr_t cb);

    static void setDynPolicyCallback(dynamic_policy_callback cb);
    static void setRecordConfigCallback(record_config_callback);

@@ -560,15 +570,19 @@ private:
    static const sp<AudioFlingerClient> getAudioFlingerClient();
    static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle);

    // Invokes all registered error callbacks with the given error code.
    static void reportError(status_t err);

    static sp<AudioFlingerClient> gAudioFlingerClient;
    static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient;
    friend class AudioFlingerClient;
    friend class AudioPolicyServiceClient;

    static Mutex gLock;      // protects gAudioFlinger and gAudioErrorCallback,
    static Mutex gLock;      // protects gAudioFlinger
    static Mutex gLockErrorCallbacks;      // protects gAudioErrorCallbacks
    static Mutex gLockAPS;   // protects gAudioPolicyService and gAudioPolicyServiceClient
    static sp<IAudioFlinger> gAudioFlinger;
    static audio_error_callback gAudioErrorCallback;
    static std::set<audio_error_callback> gAudioErrorCallbacks;
    static dynamic_policy_callback gDynPolicyCallback;
    static record_config_callback gRecordConfigCallback;