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

Commit b28753e1 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio port: support multiple clients

Add support for more than one audio port callback client per process.

Change-Id: I657c4fc28d5d2d993307551e3e69567dc60196cb
parent d4d55cdf
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -346,7 +346,8 @@ public:

    };

    static void setAudioPortCallback(sp<AudioPortCallback> callBack);
    static status_t addAudioPortCallback(const sp<AudioPortCallback>& callBack);
    static status_t removeAudioPortCallback(const sp<AudioPortCallback>& callBack);

private:

@@ -373,12 +374,19 @@ private:
        AudioPolicyServiceClient() {
        }

        status_t addAudioPortCallback(const sp<AudioPortCallback>& callBack);
        status_t removeAudioPortCallback(const sp<AudioPortCallback>& callBack);

        // DeathRecipient
        virtual void binderDied(const wp<IBinder>& who);

        // IAudioPolicyServiceClient
        virtual void onAudioPortListUpdate();
        virtual void onAudioPatchListUpdate();

    private:
        Mutex                               mLock;
        Vector <sp <AudioPortCallback> >    mAudioPortCallbacks;
    };

    static sp<AudioFlingerClient> gAudioFlingerClient;
@@ -390,7 +398,6 @@ private:
    static Mutex gLockCache; // protects gOutputs, gPrevInSamplingRate, gPrevInFormat,
                             // gPrevInChannelMask and gInBuffSize
    static Mutex gLockAPS;   // protects gAudioPolicyService and gAudioPolicyServiceClient
    static Mutex gLockAPC;   // protects gAudioPortCallback
    static sp<IAudioFlinger> gAudioFlinger;
    static audio_error_callback gAudioErrorCallback;

@@ -405,8 +412,6 @@ private:
    // list of output descriptors containing cached parameters
    // (sampling rate, framecount, channel count...)
    static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs;

    static sp<AudioPortCallback> gAudioPortCallback;
};

};  // namespace android
+68 −23
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ namespace android {
Mutex AudioSystem::gLock;
Mutex AudioSystem::gLockCache;
Mutex AudioSystem::gLockAPS;
Mutex AudioSystem::gLockAPC;
sp<IAudioFlinger> AudioSystem::gAudioFlinger;
sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
@@ -48,8 +47,6 @@ audio_format_t AudioSystem::gPrevInFormat;
audio_channel_mask_t AudioSystem::gPrevInChannelMask;
size_t AudioSystem::gInBuffSize = 0;    // zero indicates cache is invalid

sp<AudioSystem::AudioPortCallback> AudioSystem::gAudioPortCallback;

// establish binder interface to AudioFlinger service
const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
{
@@ -873,7 +870,6 @@ void AudioSystem::clearAudioConfigCache()
        Mutex::Autolock _l(gLockAPS);
        gAudioPolicyService.clear();
    }
    // Do not clear gAudioPortCallback
}

bool AudioSystem::isOffloadSupported(const audio_offload_info_t& info)
@@ -933,12 +929,31 @@ status_t AudioSystem::setAudioPortConfig(const struct audio_port_config *config)
    return aps->setAudioPortConfig(config);
}

void AudioSystem::setAudioPortCallback(sp<AudioPortCallback> callBack)
status_t AudioSystem::addAudioPortCallback(const sp<AudioPortCallback>& callBack)
{
    Mutex::Autolock _l(gLockAPC);
    gAudioPortCallback = callBack;
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;

    Mutex::Autolock _l(gLockAPS);
    if (gAudioPolicyServiceClient == 0) {
        return NO_INIT;
    }
    return gAudioPolicyServiceClient->addAudioPortCallback(callBack);
}

status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callBack)
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;

    Mutex::Autolock _l(gLockAPS);
    if (gAudioPolicyServiceClient == 0) {
        return NO_INIT;
    }
    return gAudioPolicyServiceClient->removeAudioPortCallback(callBack);
}


status_t AudioSystem::acquireSoundTriggerSession(audio_session_t *session,
                                       audio_io_handle_t *ioHandle,
                                       audio_devices_t *device)
@@ -971,36 +986,66 @@ status_t AudioSystem::registerPolicyMixes(Vector<AudioMix> mixes, bool registrat

// ---------------------------------------------------------------------------

void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
status_t AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
        const sp<AudioPortCallback>& callBack)
{
    {
        Mutex::Autolock _l(gLockAPC);
        if (gAudioPortCallback != 0) {
            gAudioPortCallback->onServiceDied();
    Mutex::Autolock _l(mLock);
    for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
        if (mAudioPortCallbacks[i] == callBack) {
            return INVALID_OPERATION;
        }
    }
    {
        Mutex::Autolock _l(gLockAPS);
        AudioSystem::gAudioPolicyService.clear();
    mAudioPortCallbacks.add(callBack);
    return NO_ERROR;
}

    ALOGW("AudioPolicyService server died!");
status_t AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback(
        const sp<AudioPortCallback>& callBack)
{
    Mutex::Autolock _l(mLock);
    size_t i;
    for (i = 0; i < mAudioPortCallbacks.size(); i++) {
        if (mAudioPortCallbacks[i] == callBack) {
            break;
        }
    }
    if (i == mAudioPortCallbacks.size()) {
        return INVALID_OPERATION;
    }
    mAudioPortCallbacks.removeAt(i);
    return NO_ERROR;
}

void AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate()
{
    Mutex::Autolock _l(gLockAPC);
    if (gAudioPortCallback != 0) {
        gAudioPortCallback->onAudioPortListUpdate();
    Mutex::Autolock _l(mLock);
    for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
        mAudioPortCallbacks[i]->onAudioPortListUpdate();
    }
}

void AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate()
{
    Mutex::Autolock _l(gLockAPC);
    if (gAudioPortCallback != 0) {
        gAudioPortCallback->onAudioPatchListUpdate();
    Mutex::Autolock _l(mLock);
    for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
        mAudioPortCallbacks[i]->onAudioPatchListUpdate();
    }
}

void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
{
    {
        Mutex::Autolock _l(mLock);
        for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
            mAudioPortCallbacks[i]->onServiceDied();
        }
    }
    {
        Mutex::Autolock _l(gLockAPS);
        AudioSystem::gAudioPolicyService.clear();
    }

    ALOGW("AudioPolicyService server died!");
}

} // namespace android