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

Commit 11e8d335 authored by Phil Burk's avatar Phil Burk
Browse files

aaudio: close MMAP stream if client dies

Notify client when audio service dies. Clear connection.
Notify AAudio service when client dies. Close client streams.

Use sp<> to track ServiceStreams.

Bug: 38267698
Test: test_no_close.cpp
Change-Id: I5f1699ed3b8b7bd960947c0028a89ca8419ce7a0
parent 1fa57e8d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@
#include "AAudioSimplePlayer.h"

#define SAMPLE_RATE           48000
#define NUM_SECONDS           20
#define NUM_SECONDS           4

#define MMAP_POLICY              AAUDIO_UNSPECIFIED
//#define MMAP_POLICY              AAUDIO_POLICY_NEVER
+2 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ LOCAL_SRC_FILES = \
    binding/AAudioBinderClient.cpp \
    binding/AAudioStreamRequest.cpp \
    binding/AAudioStreamConfiguration.cpp \
    binding/IAAudioClient.cpp \
    binding/IAAudioService.cpp \
    binding/RingBufferParcelable.cpp \
    binding/SharedMemoryParcelable.cpp \
@@ -109,6 +110,7 @@ LOCAL_SRC_FILES = core/AudioStream.cpp \
    binding/AAudioBinderClient.cpp \
    binding/AAudioStreamRequest.cpp \
    binding/AAudioStreamConfiguration.cpp \
    binding/IAAudioClient.cpp \
    binding/IAAudioService.cpp \
    binding/RingBufferParcelable.cpp \
    binding/SharedMemoryParcelable.cpp \
+62 −36
Original line number Diff line number Diff line
@@ -19,44 +19,64 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>

#include <binder/IInterface.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <utils/Mutex.h>
#include <utils/RefBase.h>
#include <utils/Singleton.h>
#include <media/AudioSystem.h>

#include <aaudio/AAudio.h>

#include "AudioEndpointParcelable.h"
#include "binding/AAudioStreamRequest.h"
#include "binding/AAudioStreamConfiguration.h"
#include "binding/IAAudioService.h"
#include "binding/AAudioServiceMessage.h"
#include "binding/AAudioBinderClient.h"
//#include "binding/AAudioStreamRequest.h"
//#include "binding/AAudioStreamConfiguration.h"
//#include "binding/IAAudioService.h"
//#include "binding/AAudioServiceMessage.h"

#include "AAudioBinderClient.h"
#include "AAudioServiceInterface.h"
//#include "AAudioServiceInterface.h"

using android::String16;
using android::IServiceManager;
using android::defaultServiceManager;
using android::interface_cast;
using android::IInterface;
using android::IAAudioService;
using android::Mutex;
using android::sp;
using android::wp;

using namespace aaudio;

static android::Mutex gServiceLock;
static sp<IAAudioService>  gAAudioService;

ANDROID_SINGLETON_STATIC_INSTANCE(AAudioBinderClient);

AAudioBinderClient::AAudioBinderClient()
        : AAudioServiceInterface()
        , Singleton<AAudioBinderClient>() {

    mAAudioClient = new AAudioClient(this);
    ALOGD("AAudioBinderClient() created mAAudioClient = %p", mAAudioClient.get());
}

AAudioBinderClient::~AAudioBinderClient() {
    Mutex::Autolock _l(mServiceLock);
    if (mAAudioService != 0) {
        IInterface::asBinder(mAAudioService)->unlinkToDeath(mAAudioClient);
    }
}

// TODO Share code with other service clients.
// Helper function to get access to the "AAudioService" service.
// This code was modeled after frameworks/av/media/libaudioclient/AudioSystem.cpp
static const sp<IAAudioService> getAAudioService() {
const sp<IAAudioService> AAudioBinderClient::getAAudioService() {
    sp<IAAudioService> aaudioService;
    bool needToRegister = false;
    {
        Mutex::Autolock _l(mServiceLock);
        if (mAAudioService == 0) {
            sp<IBinder> binder;
    Mutex::Autolock _l(gServiceLock);
    if (gAAudioService == 0) {
            sp<IServiceManager> sm = defaultServiceManager();
            // Try several times to get the service.
            int retries = 4;
@@ -68,26 +88,32 @@ static const sp<IAAudioService> getAAudioService() {
            } while (retries-- > 0);

            if (binder != 0) {
            // TODO Add linkToDeath() like in frameworks/av/media/libaudioclient/AudioSystem.cpp
            // TODO Create a DeathRecipient that disconnects all active streams.
            gAAudioService = interface_cast<IAAudioService>(binder);
                // Ask for notification if the service dies.
                status_t status = binder->linkToDeath(mAAudioClient);
                ALOGD("getAAudioService: linkToDeath(mAAudioClient = %p) returned %d",
                      mAAudioClient.get(), status);
                mAAudioService = interface_cast<IAAudioService>(binder);
                needToRegister = true;
                // Make sure callbacks can be received by mAAudioClient
                android::ProcessState::self()->startThreadPool();
            } else {
            ALOGE("AudioStreamInternal could not get %s", AAUDIO_SERVICE_NAME);
                ALOGE("AAudioBinderClient could not connect to %s", AAUDIO_SERVICE_NAME);
            }
        }
    return gAAudioService;
        aaudioService = mAAudioService;
    }

static void dropAAudioService() {
    Mutex::Autolock _l(gServiceLock);
    gAAudioService.clear(); // force a reconnect
    // Do this outside the mutex lock.
    if (needToRegister && aaudioService != 0) { // new client?
        aaudioService->registerClient(mAAudioClient);
    }
    return aaudioService;
}

AAudioBinderClient::AAudioBinderClient()
        : AAudioServiceInterface()
        , Singleton<AAudioBinderClient>() {}
void AAudioBinderClient::dropAAudioService() {
    Mutex::Autolock _l(mServiceLock);
    mAAudioService.clear(); // force a reconnect
}

AAudioBinderClient::~AAudioBinderClient() {}

/**
* @param request info needed to create the stream
+50 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H
#define ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H

#include <utils/RefBase.h>
#include <utils/Singleton.h>

#include <aaudio/AAudio.h>
@@ -25,14 +26,16 @@
#include "binding/AAudioStreamRequest.h"
#include "binding/AAudioStreamConfiguration.h"
#include "binding/AudioEndpointParcelable.h"
#include "binding/IAAudioService.h"

/**
 * Implements the AAudioServiceInterface by talking to the actual service through Binder.
 * Implements the AAudioServiceInterface by talking to the service through Binder.
 */

namespace aaudio {

class AAudioBinderClient : public AAudioServiceInterface
class AAudioBinderClient : public virtual android::RefBase
        , public AAudioServiceInterface
        , public android::Singleton<AAudioBinderClient> {

public:
@@ -41,6 +44,12 @@ public:

    virtual ~AAudioBinderClient();

    const android::sp<android::IAAudioService> getAAudioService();

    void dropAAudioService();

    void registerClient(const android::sp<android::IAAudioClient>& client __unused) override {}

    /**
     * @param request info needed to create the stream
     * @param configuration contains resulting information about the created stream
@@ -87,6 +96,45 @@ public:

    aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
                                                  pid_t clientThreadId) override;

    void onStreamChange(aaudio_handle_t handle, int32_t opcode, int32_t value) {
        // TODO This is just a stub so we can have a client Binder to pass to the service.
        // TODO Implemented in a later CL.
        ALOGW("onStreamChange called!");
    }

    class AAudioClient : public android::IBinder::DeathRecipient , public android::BnAAudioClient
    {
    public:
        AAudioClient(android::wp<AAudioBinderClient> aaudioBinderClient)
            : mBinderClient(aaudioBinderClient) {
        }

        // implement DeathRecipient
        virtual void binderDied(const android::wp<android::IBinder>& who __unused) {
            android::sp<AAudioBinderClient> client = mBinderClient.promote();
            if (client != 0) {
                client->dropAAudioService();
            }
            ALOGW("AAudio service binderDied()!");
        }

        // implement BnAAudioClient
        void onStreamChange(aaudio_handle_t handle, int32_t opcode, int32_t value) {
            android::sp<AAudioBinderClient> client = mBinderClient.promote();
            if (client != 0) {
                client->onStreamChange(handle, opcode, value);
            }
        }
    private:
        android::wp<AAudioBinderClient> mBinderClient;
    };


    android::Mutex               mServiceLock;
    android::sp<android::IAAudioService>  mAAudioService;
    android::sp<AAudioClient>    mAAudioClient;

};


+7 −2
Original line number Diff line number Diff line
@@ -29,8 +29,9 @@ using android::IBinder;

namespace android {

enum aaudio_commands_t {
    OPEN_STREAM = IBinder::FIRST_CALL_TRANSACTION,
enum aaudio_service_commands_t {
    REGISTER_CLIENT = IBinder::FIRST_CALL_TRANSACTION,
    OPEN_STREAM,
    CLOSE_STREAM,
    GET_STREAM_DESCRIPTION,
    START_STREAM,
@@ -41,6 +42,10 @@ enum aaudio_commands_t {
    UNREGISTER_AUDIO_THREAD
};

enum aaudio_client_commands_t {
    ON_STREAM_CHANGE = IBinder::FIRST_CALL_TRANSACTION
};

} // namespace android

namespace aaudio {
Loading