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

Commit 56828e8f authored by Sidipotu Ashok's avatar Sidipotu Ashok Committed by Steve Kondik
Browse files

audoflinger: Add A2DP Notifications.

LPAPlayer needs A2DP Notifications to support LPA over BT-A2DP
devices.

Change-Id: Ib43231fd51070059cbe876ec54ee7c542bf2caa3
parent 97643261
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -144,6 +144,9 @@ public:
        INPUT_CLOSED,
        INPUT_CONFIG_CHANGED,
        STREAM_CONFIG_CHANGED,
#ifdef QCOM_HARDWARE
        A2DP_OUTPUT_STATE,
#endif
        NUM_CONFIG_EVENTS
    };

+83 −0
Original line number Diff line number Diff line
@@ -245,6 +245,9 @@ AudioFlinger::AudioFlinger()
void AudioFlinger::onFirstRef()
{
    int rc = 0;
#ifdef QCOM_HARDWARE
    mA2DPHandle = -1;
#endif

    Mutex::Autolock _l(mLock);

@@ -722,6 +725,9 @@ status_t AudioFlinger::setMasterVolume(float value)

    float swmv = value;

#ifdef QCOM_HARDWARE
    mA2DPHandle = -1;
#endif
    Mutex::Autolock _l(mLock);

    // when hw supports master volume, don't scale in sw mixer
@@ -1237,6 +1243,16 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)

    Mutex::Autolock _l(mLock);

#ifdef QCOM_HARDWARE
    sp<IBinder> binder = client->asBinder();
    if (mNotificationClients.indexOfKey(binder) < 0) {
        sp<NotificationClient> notificationClient = new NotificationClient(this,
                                                                            client,
                                                                            binder);
        ALOGV("registerClient() client %p, binder %d", notificationClient.get(), binder.get());

        mNotificationClients.add(binder, notificationClient);
#else
    pid_t pid = IPCThreadState::self()->getCallingPid();
    if (mNotificationClients.indexOfKey(pid) < 0) {
        sp<NotificationClient> notificationClient = new NotificationClient(this,
@@ -1245,6 +1261,7 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
        ALOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);

        mNotificationClients.add(pid, notificationClient);
#endif

        sp<IBinder> binder = client->asBinder();
        binder->linkToDeath(notificationClient);
@@ -1259,14 +1276,46 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
            mRecordThreads.valueAt(i)->sendConfigEvent(AudioSystem::INPUT_OPENED);
        }
    }
#ifdef QCOM_HARDWARE
    // Send the notification to the client only once.
    if (mA2DPHandle != -1) {
        ALOGV("A2DP active. Notifying the registered client");
        client->ioConfigChanged(AudioSystem::A2DP_OUTPUT_STATE, mA2DPHandle, &mA2DPHandle);
    }
#endif
}

#ifdef QCOM_HARDWARE
status_t AudioFlinger::deregisterClient(const sp<IAudioFlingerClient>& client)
#else
void AudioFlinger::removeNotificationClient(pid_t pid)
#endif
{
#ifdef QCOM_HARDWARE
    ALOGV("deregisterClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
#endif
    Mutex::Autolock _l(mLock);

#ifndef QCOM_HARDWARE
    mNotificationClients.removeItem(pid);
#else
    sp<IBinder> binder = client->asBinder();
    int index = mNotificationClients.indexOfKey(binder);
    if (index >= 0) {
        mNotificationClients.removeItemsAt(index);
        return true;
    }
    return false;
}

void AudioFlinger::removeNotificationClient(sp<IBinder> binder)
{
    Mutex::Autolock _l(mLock);

    mNotificationClients.removeItem(binder);

    int pid = IPCThreadState::self()->getCallingPid();
#endif
    ALOGV("%d died, releasing its sessions", pid);
    size_t num = mAudioSessionRefs.size();
    bool removed = false;
@@ -6086,8 +6135,13 @@ void AudioFlinger::Client::releaseTimedTrack()

AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
                                                     const sp<IAudioFlingerClient>& client,
#ifdef QCOM_HARDWARE
                                                     sp<IBinder> binder)
    : mAudioFlinger(audioFlinger), mBinder(binder), mAudioFlingerClient(client)
#else
                                                     pid_t pid)
    : mAudioFlinger(audioFlinger), mPid(pid), mAudioFlingerClient(client)
#endif
{
}

@@ -6098,7 +6152,11 @@ AudioFlinger::NotificationClient::~NotificationClient()
void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
{
    sp<NotificationClient> keep(this);
#ifdef QCOM_HARDWARE
    mAudioFlinger->removeNotificationClient(mBinder);
#else
    mAudioFlinger->removeNotificationClient(mPid);
#endif
}

// ----------------------------------------------------------------------------
@@ -7370,6 +7428,16 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
#endif
            mPlaybackThreads.add(id, thread);

#ifdef QCOM_HARDWARE
        // if the device is a A2DP, then this is an A2DP Output
        if ( true == audio_is_a2dp_device((audio_devices_t) *pDevices) )
        {
            mA2DPHandle = id;
            ALOGV("A2DP device activated. The handle is set to %d", mA2DPHandle);
        }
#endif


        if (pSamplingRate != NULL) *pSamplingRate = config.sample_rate;
        if (pFormat != NULL) *pFormat = config.format;
        if (pChannelMask != NULL) *pChannelMask = config.channel_mask;
@@ -7497,6 +7565,14 @@ status_t AudioFlinger::closeOutput(audio_io_handle_t output)
        }
        audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, NULL);
        mPlaybackThreads.removeItem(output);
#ifdef QCOM_HARDWARE
        if (mA2DPHandle == output)
        {
            mA2DPHandle = -1;
            ALOGV("A2DP OutputClosed Notifying Client");
            audioConfigChanged_l(AudioSystem::A2DP_OUTPUT_STATE, mA2DPHandle, &mA2DPHandle);
        }
#endif
    }
    thread->exit();
    // The thread entity (active unit of execution) is no longer running here,
@@ -7694,6 +7770,13 @@ status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_hand
        }
    }

#ifdef QCOM_HARDWARE
    if ( mA2DPHandle == output ) {
        ALOGV("A2DP Activated and hence notifying the client");
        audioConfigChanged_l(AudioSystem::A2DP_OUTPUT_STATE, mA2DPHandle, &output);
    }
#endif

    return NO_ERROR;
}

+20 −0
Original line number Diff line number Diff line
@@ -157,6 +157,9 @@ public:

    virtual     void        registerClient(const sp<IAudioFlingerClient>& client);

#ifdef QCOM_HARDWARE
    virtual status_t deregisterClient(const sp<IAudioFlingerClient>& client);
#endif
    virtual     size_t      getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const;

    virtual audio_io_handle_t openOutput(audio_module_handle_t module,
@@ -327,7 +330,11 @@ private:
    public:
                            NotificationClient(const sp<AudioFlinger>& audioFlinger,
                                                const sp<IAudioFlingerClient>& client,
#ifdef QCOM_HARDWARE
                                                sp<IBinder> binder);
#else
                                                pid_t pid);
#endif
        virtual             ~NotificationClient();

                sp<IAudioFlingerClient> audioFlingerClient() const { return mAudioFlingerClient; }
@@ -340,7 +347,11 @@ private:
                            NotificationClient& operator = (const NotificationClient&);

        const sp<AudioFlinger>  mAudioFlinger;
#ifdef QCOM_HARDWARE
        sp<IBinder>             mBinder;
#else
        const pid_t             mPid;
#endif
        const sp<IAudioFlingerClient> mAudioFlingerClient;
    };

@@ -1373,7 +1384,11 @@ private:
    };

                void        removeClient_l(pid_t pid);
#ifdef QCOM_HARDWARE
                void        removeNotificationClient(sp<IBinder> binder);
#else
                void        removeNotificationClient(pid_t pid);
#endif


    // record thread
@@ -1981,12 +1996,17 @@ mutable Mutex mLock; // mutex for process, commands and handl

                DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> >    mRecordThreads;

#ifdef QCOM_HARDWARE
                DefaultKeyedVector< sp<IBinder>, sp<NotificationClient> >    mNotificationClients;
#else
                DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients;
#endif
                volatile int32_t                    mNextUniqueId;  // updated by android_atomic_inc
                audio_mode_t                        mMode;
                bool                                mBtNrecIsOff;
#ifdef QCOM_HARDWARE
                DefaultKeyedVector<audio_io_handle_t, AudioSessionDescriptor *> mDirectAudioTracks;
                int                                 mA2DPHandle; // Handle to notify A2DP connection status
#endif

                // protected by mLock