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

Commit 5f787816 authored by jiabin's avatar jiabin
Browse files

AAudio: do not call to aaudio service when the binder has dead.

When aaudio service has dead, the client should not call to service as
its stream handle may be reassigned to a new stream. Instead, when there
is binder death, the stream should be in disconnected state, there
should be an error callback fired.

In AAudioBinderAdapter, it takes a service lifetime id as a reference to
current aaudio service. When there is binder death, the service id will
be increased by 1. When AAudioBinderAdapter finds the service id provided
by the client is different from its own service id, it should reject the
request.

When a MMAP stream is open, it receives a service lifetime id to
recognize the service that it connects to. When processing data, the
client will return AAUDIO_ERROR_DISCONNECTED if current service lifetime
id is different from the one it cached.

Bug: 269531552
Test: repo steps in the bug
Test: atest AAudioTests
Test: oboeservice_fuzzer
Change-Id: Ieddd89fa2e23ad56d34a7fbccb8fb9a70917330e
parent d24e38bb
Loading
Loading
Loading
Loading
+53 −23
Original line number Diff line number Diff line
@@ -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;
@@ -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()) {
@@ -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));
    }
+14 −12
Original line number Diff line number Diff line
@@ -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
+33 −28
Original line number Diff line number Diff line
@@ -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();
@@ -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);
}
+37 −21
Original line number Diff line number Diff line
@@ -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>

@@ -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*/) {
@@ -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)
@@ -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();
@@ -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
@@ -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)) {}

@@ -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 {
@@ -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;
+17 −0
Original line number Diff line number Diff line
@@ -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