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

Commit c5f4587c authored by Ytai Ben-Tsvi's avatar Ytai Ben-Tsvi
Browse files

Convert AAudioService to AIDL

This change removes all hand-written binder code associated with
parceling of AAudio types and IAAudioService interface.

The existing types defined in the 'binding' directory have not been
replaced by their AIDL counterparts, but rather were made convertible
to/from them (in lieu of them being parcelables themselves).
The reasons are:
- Some of those types offer additional functionality rather than
  simply being data containers / serializers. For example, the
  SharedMemoryParcelable type supports mmaping a memory region.
- Reduce impact on existing code, which relies on the interface
  offered by those type, which is different than the interface offered
  by their AIDL counterparts.

The conversion between those types and their parcelable counterparts
is handled at the edge of the client (inside AAudioBinderAdapter) and
server (inside AAudioService) code.

Future changes may gradually get rid of the duality by retiring the
data types in the 'binding' directory, inlining some of the features
they are offering (such as accessor methods) and replacing others with
utility functions, operation on the parcelables directly.

Bug: 160253486
Test: Manual testing using OboeTester
      Ran atest CtsNativeMediaAAudioTestCases
      Ran atest test_aaudio_marshalling
Change-Id: I6eed19246a472dc31c1e2d6d2112d7562cf8940c
parent 734e3505
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -119,7 +119,6 @@ cc_library {
        "binding/AAudioBinderClient.cpp",
        "binding/AAudioStreamRequest.cpp",
        "binding/AAudioStreamConfiguration.cpp",
        "binding/IAAudioService.cpp",
        "binding/RingBufferParcelable.cpp",
        "binding/SharedMemoryParcelable.cpp",
        "binding/SharedRegionParcelable.cpp",
@@ -145,6 +144,27 @@ aidl_interface {
    unstable: true,
    local_include_dir: "binding/aidl",
    srcs: [
        "binding/aidl/aaudio/Endpoint.aidl",
        "binding/aidl/aaudio/RingBuffer.aidl",
        "binding/aidl/aaudio/SharedRegion.aidl",
        "binding/aidl/aaudio/StreamParameters.aidl",
        "binding/aidl/aaudio/StreamRequest.aidl",
        "binding/aidl/aaudio/IAAudioClient.aidl",
        "binding/aidl/aaudio/IAAudioService.aidl",
    ],
    imports: [
        "audio_common-aidl",
        "shared-file-region-aidl",
    ],
    backend:
    {
        cpp: {
            enabled: true,
        },
        java: {
            // TODO: need to have audio_common-aidl available in Java to enable
            //       this.
            enabled: false,
        },
    },
}
+70 −14
Original line number Diff line number Diff line
@@ -15,55 +15,111 @@
 */

#include <binding/AAudioBinderAdapter.h>
#include <utility/AAudioUtilities.h>

namespace aaudio {

AAudioBinderAdapter::AAudioBinderAdapter(android::IAAudioService *delegate)
using android::binder::Status;

AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate)
        : mDelegate(delegate) {}

void AAudioBinderAdapter::registerClient(const android::sp<aaudio::IAAudioClient> &client) {
void AAudioBinderAdapter::registerClient(const android::sp<IAAudioClient>& client) {
    mDelegate->registerClient(client);
}

aaudio_handle_t AAudioBinderAdapter::openStream(const AAudioStreamRequest& request,
                                                AAudioStreamConfiguration &configuration) {
    return mDelegate->openStream(request, configuration);
                                                AAudioStreamConfiguration& config) {
    aaudio_handle_t result;
    StreamParameters params;
    Status status = mDelegate->openStream(request.parcelable(),
                                          &params,
                                          &result);
    if (!status.isOk()) {
        result = AAudioConvert_androidToAAudioResult(status.transactionError());
    }
    config = params;
    return result;
}

aaudio_result_t AAudioBinderAdapter::closeStream(aaudio_handle_t streamHandle) {
    return mDelegate->closeStream(streamHandle);
    aaudio_result_t result;
    Status status = mDelegate->closeStream(streamHandle, &result);
    if (!status.isOk()) {
        result = AAudioConvert_androidToAAudioResult(status.transactionError());
    }
    return result;
}

aaudio_result_t AAudioBinderAdapter::getStreamDescription(aaudio_handle_t streamHandle,
                                                          AudioEndpointParcelable &parcelable) {
    return mDelegate->getStreamDescription(streamHandle, parcelable);
                                                          AudioEndpointParcelable& endpointOut) {
    aaudio_result_t result;
    Endpoint endpoint;
    Status status = mDelegate->getStreamDescription(streamHandle,
                                                    &endpoint,
                                                    &result);
    if (!status.isOk()) {
        result = AAudioConvert_androidToAAudioResult(status.transactionError());
    }
    endpointOut = std::move(endpoint);
    return result;
}

aaudio_result_t AAudioBinderAdapter::startStream(aaudio_handle_t streamHandle) {
    return mDelegate->startStream(streamHandle);
    aaudio_result_t result;
    Status status = mDelegate->startStream(streamHandle, &result);
    if (!status.isOk()) {
        result = AAudioConvert_androidToAAudioResult(status.transactionError());
    }
    return result;
}

aaudio_result_t AAudioBinderAdapter::pauseStream(aaudio_handle_t streamHandle) {
    return mDelegate->pauseStream(streamHandle);
    aaudio_result_t result;
    Status status = mDelegate->pauseStream(streamHandle, &result);
    if (!status.isOk()) {
        result = AAudioConvert_androidToAAudioResult(status.transactionError());
    }
    return result;
}

aaudio_result_t AAudioBinderAdapter::stopStream(aaudio_handle_t streamHandle) {
    return mDelegate->stopStream(streamHandle);
    aaudio_result_t result;
    Status status = mDelegate->stopStream(streamHandle, &result);
    if (!status.isOk()) {
        result = AAudioConvert_androidToAAudioResult(status.transactionError());
    }
    return result;
}

aaudio_result_t AAudioBinderAdapter::flushStream(aaudio_handle_t streamHandle) {
    return mDelegate->flushStream(streamHandle);
    aaudio_result_t result;
    Status status = mDelegate->flushStream(streamHandle, &result);
    if (!status.isOk()) {
        result = AAudioConvert_androidToAAudioResult(status.transactionError());
    }
    return result;
}

aaudio_result_t AAudioBinderAdapter::registerAudioThread(aaudio_handle_t streamHandle,
                                                         pid_t clientThreadId,
                                                         int64_t periodNanoseconds) {
    return mDelegate->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds);
    aaudio_result_t result;
    Status status = mDelegate->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds, &result);
    if (!status.isOk()) {
        result = AAudioConvert_androidToAAudioResult(status.transactionError());
    }
    return result;
}

aaudio_result_t AAudioBinderAdapter::unregisterAudioThread(aaudio_handle_t streamHandle,
                                                           pid_t clientThreadId) {
    return mDelegate->unregisterAudioThread(streamHandle, clientThreadId);
    aaudio_result_t result;
    Status status = mDelegate->unregisterAudioThread(streamHandle, clientThreadId, &result);
    if (!status.isOk()) {
        result = AAudioConvert_androidToAAudioResult(status.transactionError());
    }
    return result;
}

}  // namespace aaudio
+4 −4
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

#pragma once

#include <binding/IAAudioService.h>
#include <aaudio/IAAudioService.h>
#include <binding/AAudioServiceInterface.h>

namespace aaudio {
@@ -30,7 +30,7 @@ namespace aaudio {
 */
class AAudioBinderAdapter : public AAudioServiceInterface {
public:
    explicit AAudioBinderAdapter(android::IAAudioService* delegate);
    explicit AAudioBinderAdapter(IAAudioService* delegate);

    void registerClient(const android::sp<IAAudioClient>& client) override;

@@ -40,7 +40,7 @@ public:
    aaudio_result_t closeStream(aaudio_handle_t streamHandle) override;

    aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
                                         AudioEndpointParcelable& parcelable) override;
                                         AudioEndpointParcelable& endpoint) override;

    aaudio_result_t startStream(aaudio_handle_t streamHandle) override;

@@ -58,7 +58,7 @@ public:
                                          pid_t clientThreadId) override;

private:
    android::IAAudioService* const mDelegate;
    IAAudioService* const mDelegate;
};

}  // namespace aaudio
+35 −36
Original line number Diff line number Diff line
@@ -19,35 +19,30 @@
//#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/AAudioBinderClient.h"
//#include "binding/AAudioStreamRequest.h"
//#include "binding/AAudioStreamConfiguration.h"
//#include "binding/IAAudioService.h"
//#include "binding/AAudioServiceMessage.h"

//#include "AAudioServiceInterface.h"
#define AAUDIO_SERVICE_NAME  "media.aaudio"

using android::String16;
using android::IServiceManager;
using android::defaultServiceManager;
using android::interface_cast;
using android::IInterface;
using android::IAAudioService;
using android::Mutex;
using android::ProcessState;
using android::sp;
using android::status_t;
using android::wp;
using android::binder::Status;

using namespace aaudio;

@@ -67,20 +62,18 @@ AAudioBinderClient::AAudioBinderClient()
AAudioBinderClient::~AAudioBinderClient() {
    ALOGV("%s - destroying %p", __func__, this);
    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
const sp<IAAudioService> AAudioBinderClient::getAAudioService() {
std::shared_ptr<AAudioServiceInterface> AAudioBinderClient::getAAudioService() {
    std::shared_ptr<AAudioServiceInterface> result;
    sp<IAAudioService> aaudioService;
    bool needToRegister = false;
    {
        Mutex::Autolock _l(mServiceLock);
        if (mAAudioService.get() == nullptr) {
        if (mAdapter == nullptr) {
            sp<IBinder> binder;
            sp<IServiceManager> sm = defaultServiceManager();
            // Try several times to get the service.
@@ -99,7 +92,8 @@ const sp<IAAudioService> AAudioBinderClient::getAAudioService() {
                if (status != NO_ERROR) {
                    ALOGE("%s() - linkToDeath() returned %d", __func__, status);
                }
                mAAudioService = interface_cast<IAAudioService>(binder);
                aaudioService = interface_cast<IAAudioService>(binder);
                mAdapter.reset(new Adapter(aaudioService, mAAudioClient));
                needToRegister = true;
                // Make sure callbacks can be received by mAAudioClient
                ProcessState::self()->startThreadPool();
@@ -107,18 +101,18 @@ const sp<IAAudioService> AAudioBinderClient::getAAudioService() {
                ALOGE("AAudioBinderClient could not connect to %s", AAUDIO_SERVICE_NAME);
            }
        }
        aaudioService = mAAudioService;
        result = mAdapter;
    }
    // Do this outside the mutex lock.
    if (needToRegister && aaudioService.get() != nullptr) { // new client?
        aaudioService->registerClient(mAAudioClient);
    }
    return aaudioService;
    return result;
}

void AAudioBinderClient::dropAAudioService() {
    Mutex::Autolock _l(mServiceLock);
    mAAudioService.clear(); // force a reconnect
    mAdapter.reset();
}

/**
@@ -127,13 +121,13 @@ void AAudioBinderClient::dropAAudioService() {
* @return handle to the stream or a negative error
*/
aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request,
                                               AAudioStreamConfiguration &configurationOutput) {
                                               AAudioStreamConfiguration &configuration) {
    aaudio_handle_t stream;
    for (int i = 0; i < 2; i++) {
        const sp<IAAudioService> &service = getAAudioService();
        std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
        if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;

        stream = service->openStream(request, configurationOutput);
        stream = service->openStream(request, configuration);

        if (stream == AAUDIO_ERROR_NO_SERVICE) {
            ALOGE("openStream lost connection to AAudioService.");
@@ -146,8 +140,9 @@ aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &reques
}

aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) {
    const sp<IAAudioService> service = getAAudioService();
    std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
    if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;

    return service->closeStream(streamHandle);
}

@@ -155,33 +150,38 @@ aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) {
* used to communicate with the underlying HAL or Service.
*/
aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle,
                                                         AudioEndpointParcelable &parcelable) {
    const sp<IAAudioService> service = getAAudioService();
                                                         AudioEndpointParcelable& endpointOut) {
    std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
    if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    return service->getStreamDescription(streamHandle, parcelable);

    return service->getStreamDescription(streamHandle, endpointOut);
}

aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) {
    const sp<IAAudioService> service = getAAudioService();
    std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
    if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;

    return service->startStream(streamHandle);
}

aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) {
    const sp<IAAudioService> service = getAAudioService();
    std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
    if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;

    return service->pauseStream(streamHandle);
}

aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) {
    const sp<IAAudioService> service = getAAudioService();
    std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
    if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;

    return service->stopStream(streamHandle);
}

aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) {
    const sp<IAAudioService> service = getAAudioService();
    std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
    if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;

    return service->flushStream(streamHandle);
}

@@ -191,17 +191,16 @@ aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) {
aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle,
                                                        pid_t clientThreadId,
                                                        int64_t periodNanoseconds) {
    const sp<IAAudioService> service = getAAudioService();
    std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
    if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    return service->registerAudioThread(streamHandle,
                                        clientThreadId,
                                        periodNanoseconds);

    return service->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds);
}

aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle,
                                                          pid_t clientThreadId) {
    const sp<IAAudioService> service = getAAudioService();
    std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
    if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    return service->unregisterAudioThread(streamHandle,
                                          clientThreadId);

    return service->unregisterAudioThread(streamHandle, clientThreadId);
}
+53 −13
Original line number Diff line number Diff line
@@ -21,13 +21,15 @@
#include <utils/Singleton.h>

#include <aaudio/AAudio.h>
#include <binder/IInterface.h>

#include "aaudio/BnAAudioClient.h"
#include "AAudioServiceDefinitions.h"
#include "aaudio/IAAudioService.h"
#include "AAudioServiceInterface.h"
#include "binding/AAudioBinderAdapter.h"
#include "binding/AAudioStreamRequest.h"
#include "binding/AAudioStreamConfiguration.h"
#include "binding/AudioEndpointParcelable.h"
#include "binding/IAAudioService.h"
#include "core/AAudioStreamParameters.h"

/**
 * Implements the AAudioServiceInterface by talking to the service through Binder.
@@ -45,10 +47,6 @@ public:

    virtual ~AAudioBinderClient();

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

    void dropAAudioService();

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

    /**
@@ -65,7 +63,7 @@ public:
    * used to communicate with the underlying HAL or Service.
    */
    aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
                                                 AudioEndpointParcelable &parcelable) override;
                                         AudioEndpointParcelable &endpointOut) override;

    /**
     * Start the flow of data.
@@ -116,8 +114,7 @@ public:
        ALOGW("onStreamChange called!");
    }

    class AAudioClient : public android::IBinder::DeathRecipient , public BnAAudioClient
    {
    class AAudioClient : public android::IBinder::DeathRecipient, public BnAAudioClient {
    public:
        AAudioClient(android::wp<AAudioBinderClient> aaudioBinderClient)
                : mBinderClient(aaudioBinderClient) {
@@ -145,12 +142,55 @@ public:
        android::wp<AAudioBinderClient> mBinderClient;
    };

    // This adapter is used to convert the binder interface (delegate) to the AudioServiceInterface
    // conventions (translating between data types and respective parcelables, translating error
    // codes and calling conventions).
    // The adapter also owns the underlying service object and is responsible to unlink its death
    // listener when destroyed.
    class Adapter : public AAudioBinderAdapter {
    public:
        Adapter(const android::sp<IAAudioService>& delegate,
                const android::sp<AAudioClient>& aaudioClient)
                : AAudioBinderAdapter(delegate.get()),
                  mDelegate(delegate),
                  mAAudioClient(aaudioClient) {}

        virtual ~Adapter() {
            if (mDelegate != nullptr) {
                android::IInterface::asBinder(mDelegate)->unlinkToDeath(mAAudioClient);
            }
        }

        // This should never be called (call is rejected at the AudioBinderClient level).
        aaudio_result_t startClient(aaudio_handle_t streamHandle __unused,
                                    const android::AudioClient& client __unused,
                                    const audio_attributes_t* attr __unused,
                                    audio_port_handle_t* clientHandle __unused) override {
            LOG_ALWAYS_FATAL("Shouldn't get here");
            return AAUDIO_ERROR_UNAVAILABLE;
        }

        // This should never be called (call is rejected at the AudioBinderClient level).
        aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused,
                                   audio_port_handle_t clientHandle __unused) override {
            LOG_ALWAYS_FATAL("Shouldn't get here");
            return AAUDIO_ERROR_UNAVAILABLE;
        }

    private:
        android::sp<IAAudioService> mDelegate;
        android::sp<AAudioClient> mAAudioClient;
    };

private:
    android::Mutex                          mServiceLock;
    android::sp<android::IAAudioService>  mAAudioService;
    std::shared_ptr<AAudioServiceInterface> mAdapter;
    android::sp<AAudioClient>               mAAudioClient;

    std::shared_ptr<AAudioServiceInterface> getAAudioService();

    void dropAAudioService();

};


Loading