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

Commit ca20104a authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "Fix issue 2678048: binder death detection in AudioFlinger is broken." into kraken

parents c247328d 4f0f17d2
Loading
Loading
Loading
Loading
+62 −30
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ AudioFlinger::AudioFlinger()
    }
#ifdef LVMX
    LifeVibes::init();
    mLifeVibesClientPid = -1;
#endif
}

@@ -596,8 +597,10 @@ status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
    int musicEnabled = -1;
    if (NO_ERROR == param.get(key, value)) {
        if (value == LifevibesEnable) {
            mLifeVibesClientPid = IPCThreadState::self()->getCallingPid();
            musicEnabled = 1;
        } else if (value == LifevibesDisable) {
            mLifeVibesClientPid = -1;
            musicEnabled = 0;
        }
    }
@@ -609,7 +612,7 @@ status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
        mHardwareStatus = AUDIO_SET_PARAMETER;
        result = mAudioHardware->setParameters(keyValuePairs);
#ifdef LVMX
        if ((NO_ERROR == result) && (musicEnabled != -1)) {
        if (musicEnabled != -1) {
            LifeVibes::enableMusic((bool) musicEnabled);
        }
#endif
@@ -713,15 +716,19 @@ status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrame
void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
{

    LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
    Mutex::Autolock _l(mLock);

    int pid = IPCThreadState::self()->getCallingPid();
    if (mNotificationClients.indexOfKey(pid) < 0) {
        sp<NotificationClient> notificationClient = new NotificationClient(this,
                                                                            client,
                                                                            pid);
        LOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);

        mNotificationClients.add(pid, notificationClient);

        sp<IBinder> binder = client->asBinder();
    if (mNotificationClients.indexOf(binder) < 0) {
        LOGV("Adding notification client %p", binder.get());
        binder->linkToDeath(this);
        mNotificationClients.add(binder);
    }
        binder->linkToDeath(notificationClient);

        // the config change is always sent from playback or record threads to avoid deadlock
        // with AudioSystem::gLock
@@ -733,31 +740,33 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
            mRecordThreads.valueAt(i)->sendConfigEvent(AudioSystem::INPUT_OPENED);
        }
    }
}

void AudioFlinger::binderDied(const wp<IBinder>& who) {

    LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
void AudioFlinger::removeNotificationClient(pid_t pid)
{
    Mutex::Autolock _l(mLock);

    IBinder *binder = who.unsafe_get();

    if (binder != NULL) {
        int index = mNotificationClients.indexOf(binder);
    int index = mNotificationClients.indexOfKey(pid);
    if (index >= 0) {
            LOGV("Removing notification client %p", binder);
            mNotificationClients.removeAt(index);
        sp <NotificationClient> client = mNotificationClients.valueFor(pid);
        LOGV("removeNotificationClient() %p, pid %d", client.get(), pid);
#ifdef LVMX
        if (pid == mLifeVibesClientPid) {
            LOGV("Disabling lifevibes");
            LifeVibes::enableMusic(false);
            mLifeVibesClientPid = -1;
        }
#endif
        mNotificationClients.removeItem(pid);
    }
}

// audioConfigChanged_l() must be called with AudioFlinger::mLock held
void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2) {
void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2)
{
    size_t size = mNotificationClients.size();
    for (size_t i = 0; i < size; i++) {
        sp<IBinder> binder = mNotificationClients.itemAt(i);
        LOGV("audioConfigChanged_l() Notifying change to client %p", binder.get());
        sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
        client->ioConfigChanged(event, ioHandle, param2);
        mNotificationClients.valueAt(i)->client()->ioConfigChanged(event, ioHandle, param2);
    }
}

@@ -768,6 +777,7 @@ void AudioFlinger::removeClient_l(pid_t pid)
    mClients.removeItem(pid);
}


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

AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id)
@@ -3086,6 +3096,28 @@ const sp<MemoryDealer>& AudioFlinger::Client::heap() const

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

AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
                                                     const sp<IAudioFlingerClient>& client,
                                                     pid_t pid)
    : mAudioFlinger(audioFlinger), mPid(pid), mClient(client)
{
}

AudioFlinger::NotificationClient::~NotificationClient()
{
    mClient.clear();
}

void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
{
    sp<NotificationClient> keep(this);
    {
        mAudioFlinger->removeNotificationClient(mPid);
    }
}

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

AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
    : BnAudioTrack(),
      mTrack(track)
+27 −5
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ class AudioResampler;

static const nsecs_t kStandbyTimeInNsecs = seconds(3);

class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient
class AudioFlinger : public BnAudioFlinger
{
public:
    static void instantiate();
@@ -139,9 +139,6 @@ public:

    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output);

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

    enum hardware_call_state {
        AUDIO_HW_IDLE = 0,
        AUDIO_HW_INIT,
@@ -205,6 +202,27 @@ private:
        pid_t               mPid;
    };

    // --- Notification Client ---
    class NotificationClient : public IBinder::DeathRecipient {
    public:
                            NotificationClient(const sp<AudioFlinger>& audioFlinger,
                                                const sp<IAudioFlingerClient>& client,
                                                pid_t pid);
        virtual             ~NotificationClient();

                sp<IAudioFlingerClient>    client() { return mClient; }

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

    private:
                            NotificationClient(const NotificationClient&);
                            NotificationClient& operator = (const NotificationClient&);

        sp<AudioFlinger>        mAudioFlinger;
        pid_t                   mPid;
        sp<IAudioFlingerClient> mClient;
    };

    class TrackHandle;
    class RecordHandle;
@@ -685,6 +703,7 @@ private:


                void        removeClient_l(pid_t pid);
                void        removeNotificationClient(pid_t pid);


    // record thread
@@ -796,8 +815,11 @@ private:

                DefaultKeyedVector< int, sp<RecordThread> >    mRecordThreads;

                SortedVector< sp<IBinder> >         mNotificationClients;
                DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients;
                int                                 mNextThreadId;
#ifdef LVMX
                int mLifeVibesClientPid;
#endif
};

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