Loading media/libaaudio/src/binding/AAudioBinderAdapter.cpp +53 −23 Original line number Diff line number Diff line Loading @@ -23,14 +23,15 @@ namespace aaudio { using android::aidl_utils::statusTFromBinderStatus; using android::binder::Status; AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate) : mDelegate(delegate) {} AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate, int32_t serviceLifetimeId) : mDelegate(delegate), mServiceLifetimeId(serviceLifetimeId) {} void AAudioBinderAdapter::registerClient(const android::sp<IAAudioClient>& client) { mDelegate->registerClient(client); } aaudio_handle_t AAudioBinderAdapter::openStream(const AAudioStreamRequest& request, AAudioHandleInfo AAudioBinderAdapter::openStream(const AAudioStreamRequest& request, AAudioStreamConfiguration& config) { aaudio_handle_t result; StreamParameters params; Loading @@ -41,23 +42,29 @@ aaudio_handle_t AAudioBinderAdapter::openStream(const AAudioStreamRequest& reque result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } config = params; return result; return {mServiceLifetimeId, result}; } aaudio_result_t AAudioBinderAdapter::closeStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::closeStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->closeStream(streamHandle, &result); Status status = mDelegate->closeStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::getStreamDescription(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderAdapter::getStreamDescription(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable& endpointOut) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Endpoint endpoint; Status status = mDelegate->getStreamDescription(streamHandle, Status status = mDelegate->getStreamDescription(streamHandleInfo.getHandle(), &endpoint, &result); if (!status.isOk()) { Loading @@ -67,68 +74,91 @@ aaudio_result_t AAudioBinderAdapter::getStreamDescription(aaudio_handle_t stream return result; } aaudio_result_t AAudioBinderAdapter::startStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::startStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->startStream(streamHandle, &result); Status status = mDelegate->startStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::pauseStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::pauseStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->pauseStream(streamHandle, &result); Status status = mDelegate->pauseStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::stopStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::stopStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->stopStream(streamHandle, &result); Status status = mDelegate->stopStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::flushStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::flushStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->flushStream(streamHandle, &result); Status status = mDelegate->flushStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::registerAudioThread(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderAdapter::registerAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId, int64_t periodNanoseconds) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds, &result); Status status = mDelegate->registerAudioThread( streamHandleInfo.getHandle(), clientThreadId, periodNanoseconds, &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::unregisterAudioThread(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderAdapter::unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->unregisterAudioThread(streamHandle, clientThreadId, &result); Status status = mDelegate->unregisterAudioThread( streamHandleInfo.getHandle(), clientThreadId, &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::exitStandby(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderAdapter::exitStandby(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &endpointOut) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Endpoint endpoint; Status status = mDelegate->exitStandby(streamHandle, &endpoint, &result); Status status = mDelegate->exitStandby(streamHandleInfo.getHandle(), &endpoint, &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } Loading media/libaaudio/src/binding/AAudioBinderAdapter.h +14 −12 Original line number Diff line number Diff line Loading @@ -30,38 +30,40 @@ namespace aaudio { */ class AAudioBinderAdapter : public AAudioServiceInterface { public: explicit AAudioBinderAdapter(IAAudioService* delegate); AAudioBinderAdapter(IAAudioService* delegate, int32_t serviceLifetimeId); void registerClient(const android::sp<IAAudioClient>& client) override; aaudio_handle_t openStream(const AAudioStreamRequest& request, AAudioHandleInfo openStream(const AAudioStreamRequest& request, AAudioStreamConfiguration& configuration) override; aaudio_result_t closeStream(aaudio_handle_t streamHandle) override; aaudio_result_t closeStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle, aaudio_result_t getStreamDescription(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable& endpoint) override; aaudio_result_t startStream(aaudio_handle_t streamHandle) override; aaudio_result_t startStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override; aaudio_result_t pauseStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t stopStream(aaudio_handle_t streamHandle) override; aaudio_result_t stopStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t flushStream(aaudio_handle_t streamHandle) override; aaudio_result_t flushStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, aaudio_result_t registerAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId, int64_t periodNanoseconds) override; aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, aaudio_result_t unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId) override; aaudio_result_t exitStandby(aaudio_handle_t streamHandle, aaudio_result_t exitStandby(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &parcelable) override; private: IAAudioService* const mDelegate; // A unique id to recognize the service that the adapter connected to. const int32_t mServiceLifetimeId; }; } // namespace aaudio media/libaaudio/src/binding/AAudioBinderClient.cpp +33 −28 Original line number Diff line number Diff line Loading @@ -90,7 +90,8 @@ std::shared_ptr<AAudioServiceInterface> AAudioBinderClient::getAAudioService() { ALOGE("%s() - linkToDeath() returned %d", __func__, status); } aaudioService = interface_cast<IAAudioService>(binder); mAdapter = std::make_shared<Adapter>(aaudioService, mAAudioClient); mAdapter = std::make_shared<Adapter>( aaudioService, mAAudioClient, mAAudioClient->getServiceLifetimeId()); needToRegister = true; // Make sure callbacks can be received by mAAudioClient ProcessState::self()->startThreadPool(); Loading @@ -115,97 +116,101 @@ void AAudioBinderClient::dropAAudioService() { /** * @param request info needed to create the stream * @param configuration contains information about the created stream * @return handle to the stream or a negative error * @return an object for aaudio handle information, which includes the connected * aaudio service lifetime id to recognize the connected aaudio service * and aaudio handle to recognize the stream. If an error occurs, the * aaudio handle will be set as the negative error. */ aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request, AAudioHandleInfo AAudioBinderClient::openStream(const AAudioStreamRequest &request, AAudioStreamConfiguration &configuration) { aaudio_handle_t stream; for (int i = 0; i < 2; i++) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; if (service.get() == nullptr) { return {}; } stream = service->openStream(request, configuration); AAudioHandleInfo handleInfo = service->openStream(request, configuration); if (stream == AAUDIO_ERROR_NO_SERVICE) { if (handleInfo.getHandle() == AAUDIO_ERROR_NO_SERVICE) { ALOGE("openStream lost connection to AAudioService."); dropAAudioService(); // force a reconnect } else { break; return handleInfo; } } return stream; return {}; } aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::closeStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->closeStream(streamHandle); return service->closeStream(streamHandleInfo); } /* Get an immutable description of the in-memory queues * used to communicate with the underlying HAL or Service. */ aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderClient::getStreamDescription(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable& endpointOut) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->getStreamDescription(streamHandle, endpointOut); return service->getStreamDescription(streamHandleInfo, endpointOut); } aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::startStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->startStream(streamHandle); return service->startStream(streamHandleInfo); } aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::pauseStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->pauseStream(streamHandle); return service->pauseStream(streamHandleInfo); } aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::stopStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->stopStream(streamHandle); return service->stopStream(streamHandleInfo); } aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::flushStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->flushStream(streamHandle); return service->flushStream(streamHandleInfo); } /** * Manage the specified thread as a low latency audio thread. */ aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderClient::registerAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId, int64_t periodNanoseconds) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds); return service->registerAudioThread(streamHandleInfo, clientThreadId, periodNanoseconds); } aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderClient::unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->unregisterAudioThread(streamHandle, clientThreadId); return service->unregisterAudioThread(streamHandleInfo, clientThreadId); } aaudio_result_t AAudioBinderClient::exitStandby(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderClient::exitStandby(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &endpointOut) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->exitStandby(streamHandle, endpointOut); return service->exitStandby(streamHandleInfo, endpointOut); } media/libaaudio/src/binding/AAudioBinderClient.h +37 −21 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #ifndef ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H #define ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H #include <mutex> #include <utils/RefBase.h> #include <utils/Singleton.h> Loading Loading @@ -52,63 +54,66 @@ public: /** * @param request info needed to create the stream * @param configuration contains resulting information about the created stream * @return handle to the stream or a negative error * @return an object for aaudio handle information, which includes the connected * aaudio service lifetime id to recognize the connected aaudio service * and aaudio handle to recognize the stream. If an error occurs, the * aaudio handle will be set as the negative error. */ aaudio_handle_t openStream(const AAudioStreamRequest &request, AAudioHandleInfo openStream(const AAudioStreamRequest &request, AAudioStreamConfiguration &configurationOutput) override; aaudio_result_t closeStream(aaudio_handle_t streamHandle) override; aaudio_result_t closeStream(const AAudioHandleInfo& streamHandleInfo) override; /* Get an immutable description of the in-memory queues * used to communicate with the underlying HAL or Service. */ aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle, aaudio_result_t getStreamDescription(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &endpointOut) override; /** * Start the flow of data. * This is asynchronous. When complete, the service will send a STARTED event. */ aaudio_result_t startStream(aaudio_handle_t streamHandle) override; aaudio_result_t startStream(const AAudioHandleInfo& streamHandleInfo) override; /** * Stop the flow of data such that start() can resume without loss of data. * This is asynchronous. When complete, the service will send a PAUSED event. */ aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override; aaudio_result_t pauseStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t stopStream(aaudio_handle_t streamHandle) override; aaudio_result_t stopStream(const AAudioHandleInfo& streamHandleInfo) override; /** * Discard any data held by the underlying HAL or Service. * This is asynchronous. When complete, the service will send a FLUSHED event. */ aaudio_result_t flushStream(aaudio_handle_t streamHandle) override; aaudio_result_t flushStream(const AAudioHandleInfo& streamHandleInfo) override; /** * Manage the specified thread as a low latency audio thread. * TODO Consider passing this information as part of the startStream() call. */ aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, aaudio_result_t registerAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId, int64_t periodNanoseconds) override; aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, aaudio_result_t unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId) override; aaudio_result_t startClient(aaudio_handle_t streamHandle __unused, aaudio_result_t startClient(const AAudioHandleInfo& streamHandleInfo __unused, const android::AudioClient& client __unused, const audio_attributes_t *attr __unused, audio_port_handle_t *clientHandle __unused) override { return AAUDIO_ERROR_UNAVAILABLE; } aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused, aaudio_result_t stopClient(const AAudioHandleInfo& streamHandleInfo __unused, audio_port_handle_t clientHandle __unused) override { return AAUDIO_ERROR_UNAVAILABLE; } aaudio_result_t exitStandby(aaudio_handle_t streamHandle, aaudio_result_t exitStandby(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &endpointOut) override; void onStreamChange(aaudio_handle_t /*handle*/, int32_t /*opcode*/, int32_t /*value*/) { Loading @@ -117,6 +122,10 @@ public: ALOGW("onStreamChange called!"); } int32_t getServiceLifetimeId() const { return mAAudioClient->getServiceLifetimeId(); } class AAudioClient : public android::IBinder::DeathRecipient, public BnAAudioClient { public: explicit AAudioClient(const android::wp<AAudioBinderClient>& aaudioBinderClient) Loading @@ -125,6 +134,7 @@ public: // implement DeathRecipient virtual void binderDied(const android::wp<android::IBinder>& who __unused) { mServiceLifetimeId++; android::sp<AAudioBinderClient> client = mBinderClient.promote(); if (client.get() != nullptr) { client->dropAAudioService(); Loading @@ -141,8 +151,13 @@ public: } return android::binder::Status::ok(); } int32_t getServiceLifetimeId() const { return mServiceLifetimeId.load(); } private: android::wp<AAudioBinderClient> mBinderClient; std::atomic_int mServiceLifetimeId{0}; }; // This adapter is used to convert the binder interface (delegate) to the AudioServiceInterface Loading @@ -153,8 +168,9 @@ public: class Adapter : public AAudioBinderAdapter { public: Adapter(const android::sp<IAAudioService>& delegate, android::sp<AAudioClient> aaudioClient) : AAudioBinderAdapter(delegate.get()), android::sp<AAudioClient> aaudioClient, int32_t serviceLifetimeId) : AAudioBinderAdapter(delegate.get(), serviceLifetimeId), mDelegate(delegate), mAAudioClient(std::move(aaudioClient)) {} Loading @@ -165,7 +181,7 @@ public: } // This should never be called (call is rejected at the AudioBinderClient level). aaudio_result_t startClient(aaudio_handle_t streamHandle __unused, aaudio_result_t startClient(const AAudioHandleInfo& streamHandle __unused, const android::AudioClient& client __unused, const audio_attributes_t* attr __unused, audio_port_handle_t* clientHandle __unused) override { Loading @@ -174,7 +190,7 @@ public: } // This should never be called (call is rejected at the AudioBinderClient level). aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused, aaudio_result_t stopClient(const AAudioHandleInfo& streamHandle __unused, audio_port_handle_t clientHandle __unused) override { LOG_ALWAYS_FATAL("Shouldn't get here"); return AAUDIO_ERROR_UNAVAILABLE; Loading media/libaaudio/src/binding/AAudioServiceDefinitions.h +17 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,23 @@ typedef struct EndpointDescriptor_s { RingBufferDescriptor dataQueueDescriptor; // playback or capture } EndpointDescriptor; static constexpr int32_t AAUDIO_SERVICE_LIFETIME_ID_INVALID = -1; class AAudioHandleInfo { public: AAudioHandleInfo() : AAudioHandleInfo(AAUDIO_SERVICE_LIFETIME_ID_INVALID, AAUDIO_HANDLE_INVALID) {} AAudioHandleInfo(int32_t serviceLifetimeId, aaudio_handle_t handle) : mServiceLifetimeId(serviceLifetimeId), mHandle(handle) {} int32_t getServiceLifetimeId() const { return mServiceLifetimeId; } aaudio_handle_t getHandle() const { return mHandle; } private: int32_t mServiceLifetimeId; aaudio_handle_t mHandle; }; } // namespace aaudio #endif //BINDING_AAUDIOSERVICEDEFINITIONS_H Loading
media/libaaudio/src/binding/AAudioBinderAdapter.cpp +53 −23 Original line number Diff line number Diff line Loading @@ -23,14 +23,15 @@ namespace aaudio { using android::aidl_utils::statusTFromBinderStatus; using android::binder::Status; AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate) : mDelegate(delegate) {} AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate, int32_t serviceLifetimeId) : mDelegate(delegate), mServiceLifetimeId(serviceLifetimeId) {} void AAudioBinderAdapter::registerClient(const android::sp<IAAudioClient>& client) { mDelegate->registerClient(client); } aaudio_handle_t AAudioBinderAdapter::openStream(const AAudioStreamRequest& request, AAudioHandleInfo AAudioBinderAdapter::openStream(const AAudioStreamRequest& request, AAudioStreamConfiguration& config) { aaudio_handle_t result; StreamParameters params; Loading @@ -41,23 +42,29 @@ aaudio_handle_t AAudioBinderAdapter::openStream(const AAudioStreamRequest& reque result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } config = params; return result; return {mServiceLifetimeId, result}; } aaudio_result_t AAudioBinderAdapter::closeStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::closeStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->closeStream(streamHandle, &result); Status status = mDelegate->closeStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::getStreamDescription(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderAdapter::getStreamDescription(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable& endpointOut) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Endpoint endpoint; Status status = mDelegate->getStreamDescription(streamHandle, Status status = mDelegate->getStreamDescription(streamHandleInfo.getHandle(), &endpoint, &result); if (!status.isOk()) { Loading @@ -67,68 +74,91 @@ aaudio_result_t AAudioBinderAdapter::getStreamDescription(aaudio_handle_t stream return result; } aaudio_result_t AAudioBinderAdapter::startStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::startStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->startStream(streamHandle, &result); Status status = mDelegate->startStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::pauseStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::pauseStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->pauseStream(streamHandle, &result); Status status = mDelegate->pauseStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::stopStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::stopStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->stopStream(streamHandle, &result); Status status = mDelegate->stopStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::flushStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderAdapter::flushStream(const AAudioHandleInfo& streamHandleInfo) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->flushStream(streamHandle, &result); Status status = mDelegate->flushStream(streamHandleInfo.getHandle(), &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::registerAudioThread(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderAdapter::registerAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId, int64_t periodNanoseconds) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds, &result); Status status = mDelegate->registerAudioThread( streamHandleInfo.getHandle(), clientThreadId, periodNanoseconds, &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::unregisterAudioThread(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderAdapter::unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Status status = mDelegate->unregisterAudioThread(streamHandle, clientThreadId, &result); Status status = mDelegate->unregisterAudioThread( streamHandleInfo.getHandle(), clientThreadId, &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } return result; } aaudio_result_t AAudioBinderAdapter::exitStandby(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderAdapter::exitStandby(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &endpointOut) { if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) { return AAUDIO_ERROR_DISCONNECTED; } aaudio_result_t result; Endpoint endpoint; Status status = mDelegate->exitStandby(streamHandle, &endpoint, &result); Status status = mDelegate->exitStandby(streamHandleInfo.getHandle(), &endpoint, &result); if (!status.isOk()) { result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status)); } Loading
media/libaaudio/src/binding/AAudioBinderAdapter.h +14 −12 Original line number Diff line number Diff line Loading @@ -30,38 +30,40 @@ namespace aaudio { */ class AAudioBinderAdapter : public AAudioServiceInterface { public: explicit AAudioBinderAdapter(IAAudioService* delegate); AAudioBinderAdapter(IAAudioService* delegate, int32_t serviceLifetimeId); void registerClient(const android::sp<IAAudioClient>& client) override; aaudio_handle_t openStream(const AAudioStreamRequest& request, AAudioHandleInfo openStream(const AAudioStreamRequest& request, AAudioStreamConfiguration& configuration) override; aaudio_result_t closeStream(aaudio_handle_t streamHandle) override; aaudio_result_t closeStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle, aaudio_result_t getStreamDescription(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable& endpoint) override; aaudio_result_t startStream(aaudio_handle_t streamHandle) override; aaudio_result_t startStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override; aaudio_result_t pauseStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t stopStream(aaudio_handle_t streamHandle) override; aaudio_result_t stopStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t flushStream(aaudio_handle_t streamHandle) override; aaudio_result_t flushStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, aaudio_result_t registerAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId, int64_t periodNanoseconds) override; aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, aaudio_result_t unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId) override; aaudio_result_t exitStandby(aaudio_handle_t streamHandle, aaudio_result_t exitStandby(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &parcelable) override; private: IAAudioService* const mDelegate; // A unique id to recognize the service that the adapter connected to. const int32_t mServiceLifetimeId; }; } // namespace aaudio
media/libaaudio/src/binding/AAudioBinderClient.cpp +33 −28 Original line number Diff line number Diff line Loading @@ -90,7 +90,8 @@ std::shared_ptr<AAudioServiceInterface> AAudioBinderClient::getAAudioService() { ALOGE("%s() - linkToDeath() returned %d", __func__, status); } aaudioService = interface_cast<IAAudioService>(binder); mAdapter = std::make_shared<Adapter>(aaudioService, mAAudioClient); mAdapter = std::make_shared<Adapter>( aaudioService, mAAudioClient, mAAudioClient->getServiceLifetimeId()); needToRegister = true; // Make sure callbacks can be received by mAAudioClient ProcessState::self()->startThreadPool(); Loading @@ -115,97 +116,101 @@ void AAudioBinderClient::dropAAudioService() { /** * @param request info needed to create the stream * @param configuration contains information about the created stream * @return handle to the stream or a negative error * @return an object for aaudio handle information, which includes the connected * aaudio service lifetime id to recognize the connected aaudio service * and aaudio handle to recognize the stream. If an error occurs, the * aaudio handle will be set as the negative error. */ aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request, AAudioHandleInfo AAudioBinderClient::openStream(const AAudioStreamRequest &request, AAudioStreamConfiguration &configuration) { aaudio_handle_t stream; for (int i = 0; i < 2; i++) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; if (service.get() == nullptr) { return {}; } stream = service->openStream(request, configuration); AAudioHandleInfo handleInfo = service->openStream(request, configuration); if (stream == AAUDIO_ERROR_NO_SERVICE) { if (handleInfo.getHandle() == AAUDIO_ERROR_NO_SERVICE) { ALOGE("openStream lost connection to AAudioService."); dropAAudioService(); // force a reconnect } else { break; return handleInfo; } } return stream; return {}; } aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::closeStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->closeStream(streamHandle); return service->closeStream(streamHandleInfo); } /* Get an immutable description of the in-memory queues * used to communicate with the underlying HAL or Service. */ aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderClient::getStreamDescription(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable& endpointOut) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->getStreamDescription(streamHandle, endpointOut); return service->getStreamDescription(streamHandleInfo, endpointOut); } aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::startStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->startStream(streamHandle); return service->startStream(streamHandleInfo); } aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::pauseStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->pauseStream(streamHandle); return service->pauseStream(streamHandleInfo); } aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::stopStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->stopStream(streamHandle); return service->stopStream(streamHandleInfo); } aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) { aaudio_result_t AAudioBinderClient::flushStream(const AAudioHandleInfo& streamHandleInfo) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->flushStream(streamHandle); return service->flushStream(streamHandleInfo); } /** * Manage the specified thread as a low latency audio thread. */ aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderClient::registerAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId, int64_t periodNanoseconds) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds); return service->registerAudioThread(streamHandleInfo, clientThreadId, periodNanoseconds); } aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderClient::unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->unregisterAudioThread(streamHandle, clientThreadId); return service->unregisterAudioThread(streamHandleInfo, clientThreadId); } aaudio_result_t AAudioBinderClient::exitStandby(aaudio_handle_t streamHandle, aaudio_result_t AAudioBinderClient::exitStandby(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &endpointOut) { std::shared_ptr<AAudioServiceInterface> service = getAAudioService(); if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; return service->exitStandby(streamHandle, endpointOut); return service->exitStandby(streamHandleInfo, endpointOut); }
media/libaaudio/src/binding/AAudioBinderClient.h +37 −21 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #ifndef ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H #define ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H #include <mutex> #include <utils/RefBase.h> #include <utils/Singleton.h> Loading Loading @@ -52,63 +54,66 @@ public: /** * @param request info needed to create the stream * @param configuration contains resulting information about the created stream * @return handle to the stream or a negative error * @return an object for aaudio handle information, which includes the connected * aaudio service lifetime id to recognize the connected aaudio service * and aaudio handle to recognize the stream. If an error occurs, the * aaudio handle will be set as the negative error. */ aaudio_handle_t openStream(const AAudioStreamRequest &request, AAudioHandleInfo openStream(const AAudioStreamRequest &request, AAudioStreamConfiguration &configurationOutput) override; aaudio_result_t closeStream(aaudio_handle_t streamHandle) override; aaudio_result_t closeStream(const AAudioHandleInfo& streamHandleInfo) override; /* Get an immutable description of the in-memory queues * used to communicate with the underlying HAL or Service. */ aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle, aaudio_result_t getStreamDescription(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &endpointOut) override; /** * Start the flow of data. * This is asynchronous. When complete, the service will send a STARTED event. */ aaudio_result_t startStream(aaudio_handle_t streamHandle) override; aaudio_result_t startStream(const AAudioHandleInfo& streamHandleInfo) override; /** * Stop the flow of data such that start() can resume without loss of data. * This is asynchronous. When complete, the service will send a PAUSED event. */ aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override; aaudio_result_t pauseStream(const AAudioHandleInfo& streamHandleInfo) override; aaudio_result_t stopStream(aaudio_handle_t streamHandle) override; aaudio_result_t stopStream(const AAudioHandleInfo& streamHandleInfo) override; /** * Discard any data held by the underlying HAL or Service. * This is asynchronous. When complete, the service will send a FLUSHED event. */ aaudio_result_t flushStream(aaudio_handle_t streamHandle) override; aaudio_result_t flushStream(const AAudioHandleInfo& streamHandleInfo) override; /** * Manage the specified thread as a low latency audio thread. * TODO Consider passing this information as part of the startStream() call. */ aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, aaudio_result_t registerAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId, int64_t periodNanoseconds) override; aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, aaudio_result_t unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo, pid_t clientThreadId) override; aaudio_result_t startClient(aaudio_handle_t streamHandle __unused, aaudio_result_t startClient(const AAudioHandleInfo& streamHandleInfo __unused, const android::AudioClient& client __unused, const audio_attributes_t *attr __unused, audio_port_handle_t *clientHandle __unused) override { return AAUDIO_ERROR_UNAVAILABLE; } aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused, aaudio_result_t stopClient(const AAudioHandleInfo& streamHandleInfo __unused, audio_port_handle_t clientHandle __unused) override { return AAUDIO_ERROR_UNAVAILABLE; } aaudio_result_t exitStandby(aaudio_handle_t streamHandle, aaudio_result_t exitStandby(const AAudioHandleInfo& streamHandleInfo, AudioEndpointParcelable &endpointOut) override; void onStreamChange(aaudio_handle_t /*handle*/, int32_t /*opcode*/, int32_t /*value*/) { Loading @@ -117,6 +122,10 @@ public: ALOGW("onStreamChange called!"); } int32_t getServiceLifetimeId() const { return mAAudioClient->getServiceLifetimeId(); } class AAudioClient : public android::IBinder::DeathRecipient, public BnAAudioClient { public: explicit AAudioClient(const android::wp<AAudioBinderClient>& aaudioBinderClient) Loading @@ -125,6 +134,7 @@ public: // implement DeathRecipient virtual void binderDied(const android::wp<android::IBinder>& who __unused) { mServiceLifetimeId++; android::sp<AAudioBinderClient> client = mBinderClient.promote(); if (client.get() != nullptr) { client->dropAAudioService(); Loading @@ -141,8 +151,13 @@ public: } return android::binder::Status::ok(); } int32_t getServiceLifetimeId() const { return mServiceLifetimeId.load(); } private: android::wp<AAudioBinderClient> mBinderClient; std::atomic_int mServiceLifetimeId{0}; }; // This adapter is used to convert the binder interface (delegate) to the AudioServiceInterface Loading @@ -153,8 +168,9 @@ public: class Adapter : public AAudioBinderAdapter { public: Adapter(const android::sp<IAAudioService>& delegate, android::sp<AAudioClient> aaudioClient) : AAudioBinderAdapter(delegate.get()), android::sp<AAudioClient> aaudioClient, int32_t serviceLifetimeId) : AAudioBinderAdapter(delegate.get(), serviceLifetimeId), mDelegate(delegate), mAAudioClient(std::move(aaudioClient)) {} Loading @@ -165,7 +181,7 @@ public: } // This should never be called (call is rejected at the AudioBinderClient level). aaudio_result_t startClient(aaudio_handle_t streamHandle __unused, aaudio_result_t startClient(const AAudioHandleInfo& streamHandle __unused, const android::AudioClient& client __unused, const audio_attributes_t* attr __unused, audio_port_handle_t* clientHandle __unused) override { Loading @@ -174,7 +190,7 @@ public: } // This should never be called (call is rejected at the AudioBinderClient level). aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused, aaudio_result_t stopClient(const AAudioHandleInfo& streamHandle __unused, audio_port_handle_t clientHandle __unused) override { LOG_ALWAYS_FATAL("Shouldn't get here"); return AAUDIO_ERROR_UNAVAILABLE; Loading
media/libaaudio/src/binding/AAudioServiceDefinitions.h +17 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,23 @@ typedef struct EndpointDescriptor_s { RingBufferDescriptor dataQueueDescriptor; // playback or capture } EndpointDescriptor; static constexpr int32_t AAUDIO_SERVICE_LIFETIME_ID_INVALID = -1; class AAudioHandleInfo { public: AAudioHandleInfo() : AAudioHandleInfo(AAUDIO_SERVICE_LIFETIME_ID_INVALID, AAUDIO_HANDLE_INVALID) {} AAudioHandleInfo(int32_t serviceLifetimeId, aaudio_handle_t handle) : mServiceLifetimeId(serviceLifetimeId), mHandle(handle) {} int32_t getServiceLifetimeId() const { return mServiceLifetimeId; } aaudio_handle_t getHandle() const { return mHandle; } private: int32_t mServiceLifetimeId; aaudio_handle_t mHandle; }; } // namespace aaudio #endif //BINDING_AAUDIOSERVICEDEFINITIONS_H