1204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk/*
2204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * Copyright (C) 2016 The Android Open Source Project
3204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
4204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * Licensed under the Apache License, Version 2.0 (the "License");
5204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * you may not use this file except in compliance with the License.
6204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * You may obtain a copy of the License at
7204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
8204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *      http://www.apache.org/licenses/LICENSE-2.0
9204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
10204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * Unless required by applicable law or agreed to in writing, software
11204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * distributed under the License is distributed on an "AS IS" BASIS,
12204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * See the License for the specific language governing permissions and
14204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * limitations under the License.
15204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk */
16204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
17a4eb0d86a29be2763be5fac51727858d5095794bPhil Burk#include <aaudio/AAudio.h>
18204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
19204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include "binding/AudioEndpointParcelable.h"
205ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include "binding/AAudioStreamRequest.h"
213316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk#include "binding/AAudioServiceDefinitions.h"
225ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include "binding/AAudioStreamConfiguration.h"
235ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include "binding/IAAudioService.h"
245ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include "utility/AAudioUtilities.h"
25204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
26204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burknamespace android {
27204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
283316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkusing aaudio::aaudio_handle_t;
293316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk
30204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk/**
315ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk * This is used by the AAudio Client to talk to the AAudio Service.
32204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
335ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk * The order of parameters in the Parcels must match with code in AAudioService.cpp.
34204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk */
355ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkclass BpAAudioService : public BpInterface<IAAudioService>
36204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk{
37204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkpublic:
385ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    explicit BpAAudioService(const sp<IBinder>& impl)
395ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        : BpInterface<IAAudioService>(impl)
40204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    {
41204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
42204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
43c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    virtual aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request,
44c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                     aaudio::AAudioStreamConfiguration &configurationOutput) override {
45204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        Parcel data, reply;
46204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // send command
475ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
4871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        ALOGV("BpAAudioService::client openStream --------------------");
4971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        // request.dump();
50204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        request.writeToParcel(&data);
51204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        status_t err = remote()->transact(OPEN_STREAM, data, &reply);
5271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        ALOGV("BpAAudioService::client openStream returned %d", err);
53204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (err != NO_ERROR) {
5471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            ALOGE("BpAAudioService::client openStream transact failed %d", err);
555ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAudioConvert_androidToAAudioResult(err);
56204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
57204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // parse reply
585ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        aaudio_handle_t stream;
5971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        err = reply.readInt32(&stream);
6071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        if (err != NO_ERROR) {
6171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            ALOGE("BpAAudioService::client transact(OPEN_STREAM) readInt %d", err);
6271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            return AAudioConvert_androidToAAudioResult(err);
6371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        } else if (stream < 0) {
6471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            ALOGE("BpAAudioService::client OPEN_STREAM passed stream %d", stream);
6571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            return stream;
6671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        }
67c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        err = configurationOutput.readFromParcel(&reply);
68c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        if (err != NO_ERROR) {
69c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGE("BpAAudioService::client openStream readFromParcel failed %d", err);
70c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            closeStream(stream);
71c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            return AAudioConvert_androidToAAudioResult(err);
72c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        }
73204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        return stream;
74204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
75204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
765ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override {
77204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        Parcel data, reply;
78204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // send command
795ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
80204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt32(streamHandle);
81204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        status_t err = remote()->transact(CLOSE_STREAM, data, &reply);
82204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (err != NO_ERROR) {
8371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            ALOGE("BpAAudioService::client closeStream transact failed %d", err);
845ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAudioConvert_androidToAAudioResult(err);
85204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
86204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // parse reply
875ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        aaudio_result_t res;
88204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        reply.readInt32(&res);
89204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        return res;
90204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
91204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
925ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
935ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk                                               aaudio::AudioEndpointParcelable &parcelable)   {
94204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        Parcel data, reply;
95204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // send command
965ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
97204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt32(streamHandle);
98204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply);
99204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (err != NO_ERROR) {
100c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err);
1015ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAudioConvert_androidToAAudioResult(err);
102204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
103204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // parse reply
104c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        aaudio_result_t result;
105c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        err = reply.readInt32(&result);
106c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        if (err != NO_ERROR) {
107c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) readInt %d", err);
108c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            return AAudioConvert_androidToAAudioResult(err);
109c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        } else if (result != AAUDIO_OK) {
110c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION passed result %d", result);
111c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            return result;
112c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        }
113c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        err = parcelable.readFromParcel(&reply);;
114c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        if (err != NO_ERROR) {
115c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err);
116c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            return AAudioConvert_androidToAAudioResult(err);
117c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        }
118c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        //parcelable.dump();
119c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        result = parcelable.validate();
1205ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        if (result != AAUDIO_OK) {
121c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION validation fails %d", result);
122204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return result;
123204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
124204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        return result;
125204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
126204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
127204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    // TODO should we wait for a reply?
1285ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override {
129204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        Parcel data, reply;
130204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // send command
1315ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
132204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt32(streamHandle);
133204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        status_t err = remote()->transact(START_STREAM, data, &reply);
134204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (err != NO_ERROR) {
1355ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAudioConvert_androidToAAudioResult(err);
136204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
137204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // parse reply
1385ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        aaudio_result_t res;
139204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        reply.readInt32(&res);
140204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        return res;
141204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
142204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
1435ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override {
144204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        Parcel data, reply;
145204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // send command
1465ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
147204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt32(streamHandle);
148204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        status_t err = remote()->transact(PAUSE_STREAM, data, &reply);
149204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (err != NO_ERROR) {
1505ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAudioConvert_androidToAAudioResult(err);
151204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
152204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // parse reply
1535ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        aaudio_result_t res;
154204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        reply.readInt32(&res);
155204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        return res;
156204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
157204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
15871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) override {
15971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        Parcel data, reply;
16071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        // send command
16171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
16271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        data.writeInt32(streamHandle);
16371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        status_t err = remote()->transact(STOP_STREAM, data, &reply);
16471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        if (err != NO_ERROR) {
16571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            return AAudioConvert_androidToAAudioResult(err);
16671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        }
16771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        // parse reply
16871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        aaudio_result_t res;
16971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        reply.readInt32(&res);
17071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        return res;
17171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    }
17271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk
1735ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override {
174204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        Parcel data, reply;
175204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // send command
1765ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
177204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt32(streamHandle);
178204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        status_t err = remote()->transact(FLUSH_STREAM, data, &reply);
179204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (err != NO_ERROR) {
1805ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAudioConvert_androidToAAudioResult(err);
181204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
182204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // parse reply
1835ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        aaudio_result_t res;
184204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        reply.readInt32(&res);
185204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        return res;
186204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
187204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
188c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
189c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                              pid_t clientProcessId,
190c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                              pid_t clientThreadId,
1913316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                                              int64_t periodNanoseconds)
192204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    override {
193204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        Parcel data, reply;
194204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // send command
1955ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
196204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt32(streamHandle);
197c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        data.writeInt32((int32_t) clientProcessId);
198204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt32((int32_t) clientThreadId);
199204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt64(periodNanoseconds);
200204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply);
201204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (err != NO_ERROR) {
2025ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAudioConvert_androidToAAudioResult(err);
203204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
204204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // parse reply
2055ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        aaudio_result_t res;
206204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        reply.readInt32(&res);
207204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        return res;
208204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
209204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
210c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
211c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                                  pid_t clientProcessId,
212c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                                  pid_t clientThreadId)
213204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    override {
214204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        Parcel data, reply;
215204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // send command
2165ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
217204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt32(streamHandle);
218c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        data.writeInt32((int32_t) clientProcessId);
219204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        data.writeInt32((int32_t) clientThreadId);
220204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply);
221204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        if (err != NO_ERROR) {
2225ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            return AAudioConvert_androidToAAudioResult(err);
223204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        }
224204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        // parse reply
2255ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        aaudio_result_t res;
226204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        reply.readInt32(&res);
227204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        return res;
228204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
229204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
230204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk};
231204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
232204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk// Implement an interface to the service.
233c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk// This is here so that you don't have to link with libaaudio static library.
2345ed503c7a66c90f93759c90237a9b432dbd93f9fPhil BurkIMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
235204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
2365ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk// The order of parameters in the Parcels must match with code in BpAAudioService
237204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
2385ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkstatus_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
239204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk                                        Parcel* reply, uint32_t flags) {
2403316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    aaudio_handle_t stream;
2415ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio::AAudioStreamRequest request;
2425ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio::AAudioStreamConfiguration configuration;
243204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    pid_t pid;
244c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    pid_t tid;
2453316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    int64_t nanoseconds;
2465ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_result_t result;
2475ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
248204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    data.checkInterface(this);
249204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
250204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    switch(code) {
251204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        case OPEN_STREAM: {
252204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            request.readFromParcel(&data);
253c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
25471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            //ALOGD("BnAAudioService::client openStream request dump --------------------");
25571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            //request.dump();
256c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
257204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            stream = openStream(request, configuration);
25871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", stream);
259204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            reply->writeInt32(stream);
260204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            configuration.writeToParcel(reply);
261204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return NO_ERROR;
262204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        } break;
263204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
264204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        case CLOSE_STREAM: {
265204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt32(&stream);
266204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            result = closeStream(stream);
26771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
26871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            //      stream, result);
269204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            reply->writeInt32(result);
270204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return NO_ERROR;
271204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        } break;
272204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
273204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        case GET_STREAM_DESCRIPTION: {
274204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt32(&stream);
2755ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            aaudio::AudioEndpointParcelable parcelable;
276204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            result = getStreamDescription(stream, parcelable);
2775ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            if (result != AAUDIO_OK) {
2785ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk                return AAudioConvert_aaudioToAndroidStatus(result);
279204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            }
280204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            result = parcelable.validate();
2815ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            if (result != AAUDIO_OK) {
282c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                ALOGE("BnAAudioService::onTransact getStreamDescription() returns %d", result);
283c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                parcelable.dump();
2845ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk                return AAudioConvert_aaudioToAndroidStatus(result);
285204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            }
286204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            reply->writeInt32(result);
287c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            parcelable.writeToParcel(reply);
288204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return NO_ERROR;
289204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        } break;
290204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
291204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        case START_STREAM: {
292204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt32(&stream);
293204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            result = startStream(stream);
294c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
295204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk                    stream, result);
296204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            reply->writeInt32(result);
297204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return NO_ERROR;
298204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        } break;
299204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
300204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        case PAUSE_STREAM: {
301204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt32(&stream);
302204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            result = pauseStream(stream);
303c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
30471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk                  stream, result);
30571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            reply->writeInt32(result);
30671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            return NO_ERROR;
30771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        } break;
30871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk
30971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        case STOP_STREAM: {
31071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            data.readInt32(&stream);
31171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            result = stopStream(stream);
31271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
31371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk                  stream, result);
314204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            reply->writeInt32(result);
315204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return NO_ERROR;
316204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        } break;
317204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
318204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        case FLUSH_STREAM: {
319204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt32(&stream);
320204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            result = flushStream(stream);
321c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
322204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk                    stream, result);
323204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            reply->writeInt32(result);
324204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return NO_ERROR;
325204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        } break;
326204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
327204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        case REGISTER_AUDIO_THREAD: {
328204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt32(&stream);
329204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt32(&pid);
330c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            data.readInt32(&tid);
331204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt64(&nanoseconds);
332c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            result = registerAudioThread(stream, pid, tid, nanoseconds);
333c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
334204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk                    stream, result);
335204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            reply->writeInt32(result);
336204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return NO_ERROR;
337204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        } break;
338204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
339204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        case UNREGISTER_AUDIO_THREAD: {
340204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt32(&stream);
341204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            data.readInt32(&pid);
342c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            data.readInt32(&tid);
343c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            result = unregisterAudioThread(stream, pid, tid);
344c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
345204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk                    stream, result);
346204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            reply->writeInt32(result);
347204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return NO_ERROR;
348204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        } break;
349204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
350204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        default:
3515ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk            // ALOGW("BnAAudioService::onTransact not handled %u", code);
352204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk            return BBinder::onTransact(code, data, reply, flags);
353204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
354204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk}
355204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
356204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk} /* namespace android */
357