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

Commit 0ba4597e authored by Jagan Devarajan's avatar Jagan Devarajan Committed by Steve Kondik
Browse files

/platform/frameworks/base: Add support for A2DP notification to audioflinger

clients

- Whenever A2DP is connected, clients of audioflinger were not notified.
- This is needed incase of LPA decoding, to ensure that the A2DP is
  handled and stream is routed to correct outputs.
- Add support for A2DP notification when the client is registering (if A2DP
  is already connected).
- Add new API in audioflinger to de-register the client - for multiple
  playbacks, otherwise AF will have the old client and it will result in
  wrong notification.

Change-Id: I56a7a8e25af8313a616164f9ba286be979364261
parent 4820fe62
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -307,6 +307,7 @@ public:
        INPUT_CLOSED,
        INPUT_CONFIG_CHANGED,
        STREAM_CONFIG_CHANGED,
        A2DP_OUTPUT_STATE,
        NUM_CONFIG_EVENTS
    };

+2 −0
Original line number Diff line number Diff line
@@ -135,6 +135,8 @@ public:
    virtual status_t setStreamOutput(uint32_t stream, int output) = 0;

    virtual status_t setVoiceVolume(float volume) = 0;

    virtual status_t deregisterClient(const sp<IAudioFlingerClient>& client) { return false; };
};


+49 −1
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ AudioFlinger::AudioFlinger()
        mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextThreadId(0)
{
    mHardwareStatus = AUDIO_HW_IDLE;
    mA2DPHandle = -1;

    mAudioHardware = AudioHardwareInterface::create();

@@ -674,6 +675,29 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
    for (size_t i = 0; i < mRecordThreads.size(); i++) {
        mRecordThreads.valueAt(i)->sendConfigEvent(AudioSystem::INPUT_OPENED);
    }

    // Send the notification to the client only once.
    if (mA2DPHandle != -1) {
        LOGV("A2DP active. Notifying the registered client");
        client->ioConfigChanged(AudioSystem::A2DP_OUTPUT_STATE, mA2DPHandle, NULL);
    }
}

status_t AudioFlinger::deregisterClient(const sp<IAudioFlingerClient>& client)
{
    LOGV("deregisterClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
    Mutex::Autolock _l(mLock);

	sp<IBinder> binder = client->asBinder();

	int index = mNotificationClients.indexOf(binder);

    if (index >= 0) {
		mNotificationClients.removeAt(index);
        return true;
    }

    return false;
}

// audioConfigChanged_l() must be called with AudioFlinger::mLock held
@@ -1150,8 +1174,14 @@ void AudioFlinger::PlaybackThread::audioConfigChanged(int event, int param) {
        break;
    }
    Mutex::Autolock _l(mAudioFlinger->mLock);
    if (event != AudioSystem::A2DP_OUTPUT_STATE) {
       mAudioFlinger->audioConfigChanged_l(event, mId, param2);
    }
    else
    {
        mAudioFlinger->audioConfigChanged_l(event, param, NULL);
    }
}

void AudioFlinger::PlaybackThread::readOutputParameters()
{
@@ -3664,6 +3694,12 @@ int AudioFlinger::openOutput(uint32_t *pDevices,
        if (pChannels) *pChannels = channels;
        if (pLatencyMs) *pLatencyMs = thread->latency();

        // if the device is a A2DP, then this is an A2DP Output
        if ( true == AudioSystem::isA2dpDevice((AudioSystem::audio_devices) *pDevices) )
        {
            mA2DPHandle = mNextThreadId;
            LOGV("A2DP device activated. The handle is set to %d", mA2DPHandle);
        }
        return mNextThreadId;
    }

@@ -3774,6 +3810,13 @@ status_t AudioFlinger::closeOutput(int output)
        void *param2 = 0;
        audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, param2);
        mPlaybackThreads.removeItem(output);

        if (mA2DPHandle == output)
        {
            mA2DPHandle = -1;
            LOGV("A2DP OutputClosed Notifying Client");
            audioConfigChanged_l(AudioSystem::A2DP_OUTPUT_STATE, mA2DPHandle, param2);
        }
    }
    thread->exit();

@@ -3932,6 +3975,11 @@ status_t AudioFlinger::setStreamOutput(uint32_t stream, int output)

    dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream);

    if ( mA2DPHandle == output ) {
        LOGV("A2DP Activated and hence notifying the client");
        dstThread->sendConfigEvent(AudioSystem::A2DP_OUTPUT_STATE, mA2DPHandle);
    }

    return NO_ERROR;
}

+3 −0
Original line number Diff line number Diff line
@@ -143,6 +143,8 @@ public:

    virtual status_t setVoiceVolume(float volume);

    virtual status_t deregisterClient(const sp<IAudioFlingerClient>& client);

    enum hardware_call_state {
        AUDIO_HW_IDLE = 0,
        AUDIO_HW_INIT,
@@ -815,6 +817,7 @@ private:

                SortedVector< sp<IBinder> >         mNotificationClients;
                int                                 mNextThreadId;
                int                                 mA2DPHandle; // Handle to notify client (MIO)
                KeyedVector<audio_io_handle_t, AudioStreamOut *> mOutputSessions;   // list of output descriptors
};

+1 −0
Original line number Diff line number Diff line
@@ -265,6 +265,7 @@ status_t AudioTrack::set(
    mNewPosition = 0;
    mUpdatePeriod = 0;
    mFlags = flags;
    mAudioSession = -1;

    return NO_ERROR;
}
Loading