IAAudioService.cpp revision c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fb
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <aaudio/AAudioDefinitions.h> 18 19#include "binding/AudioEndpointParcelable.h" 20#include "binding/AAudioStreamRequest.h" 21#include "binding/AAudioServiceDefinitions.h" 22#include "binding/AAudioStreamConfiguration.h" 23#include "binding/IAAudioService.h" 24#include "utility/AAudioUtilities.h" 25 26namespace android { 27 28using aaudio::aaudio_handle_t; 29 30/** 31 * This is used by the AAudio Client to talk to the AAudio Service. 32 * 33 * The order of parameters in the Parcels must match with code in AAudioService.cpp. 34 */ 35class BpAAudioService : public BpInterface<IAAudioService> 36{ 37public: 38 explicit BpAAudioService(const sp<IBinder>& impl) 39 : BpInterface<IAAudioService>(impl) 40 { 41 } 42 43 virtual aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request, 44 aaudio::AAudioStreamConfiguration &configurationOutput) override { 45 Parcel data, reply; 46 // send command 47 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 48 ALOGE("BpAAudioService::client openStream request dump --------------------"); 49 request.dump(); 50 request.writeToParcel(&data); 51 status_t err = remote()->transact(OPEN_STREAM, data, &reply); 52 if (err != NO_ERROR) { 53 return AAudioConvert_androidToAAudioResult(err); 54 } 55 // parse reply 56 aaudio_handle_t stream; 57 reply.readInt32(&stream); 58 err = configurationOutput.readFromParcel(&reply); 59 if (err != NO_ERROR) { 60 ALOGE("BpAAudioService::client openStream readFromParcel failed %d", err); 61 closeStream(stream); 62 return AAudioConvert_androidToAAudioResult(err); 63 } 64 return stream; 65 } 66 67 virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override { 68 Parcel data, reply; 69 // send command 70 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 71 data.writeInt32(streamHandle); 72 status_t err = remote()->transact(CLOSE_STREAM, data, &reply); 73 if (err != NO_ERROR) { 74 return AAudioConvert_androidToAAudioResult(err); 75 } 76 // parse reply 77 aaudio_result_t res; 78 reply.readInt32(&res); 79 return res; 80 } 81 82 virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle, 83 aaudio::AudioEndpointParcelable &parcelable) { 84 Parcel data, reply; 85 // send command 86 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 87 data.writeInt32(streamHandle); 88 status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply); 89 if (err != NO_ERROR) { 90 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err); 91 return AAudioConvert_androidToAAudioResult(err); 92 } 93 // parse reply 94 aaudio_result_t result; 95 err = reply.readInt32(&result); 96 if (err != NO_ERROR) { 97 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) readInt %d", err); 98 return AAudioConvert_androidToAAudioResult(err); 99 } else if (result != AAUDIO_OK) { 100 ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION passed result %d", result); 101 return result; 102 } 103 err = parcelable.readFromParcel(&reply);; 104 if (err != NO_ERROR) { 105 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err); 106 return AAudioConvert_androidToAAudioResult(err); 107 } 108 //parcelable.dump(); 109 result = parcelable.validate(); 110 if (result != AAUDIO_OK) { 111 ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION validation fails %d", result); 112 return result; 113 } 114 return result; 115 } 116 117 // TODO should we wait for a reply? 118 virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override { 119 Parcel data, reply; 120 // send command 121 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 122 data.writeInt32(streamHandle); 123 status_t err = remote()->transact(START_STREAM, data, &reply); 124 if (err != NO_ERROR) { 125 return AAudioConvert_androidToAAudioResult(err); 126 } 127 // parse reply 128 aaudio_result_t res; 129 reply.readInt32(&res); 130 return res; 131 } 132 133 virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override { 134 Parcel data, reply; 135 // send command 136 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 137 data.writeInt32(streamHandle); 138 status_t err = remote()->transact(PAUSE_STREAM, data, &reply); 139 if (err != NO_ERROR) { 140 return AAudioConvert_androidToAAudioResult(err); 141 } 142 // parse reply 143 aaudio_result_t res; 144 reply.readInt32(&res); 145 return res; 146 } 147 148 virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override { 149 Parcel data, reply; 150 // send command 151 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 152 data.writeInt32(streamHandle); 153 status_t err = remote()->transact(FLUSH_STREAM, data, &reply); 154 if (err != NO_ERROR) { 155 return AAudioConvert_androidToAAudioResult(err); 156 } 157 // parse reply 158 aaudio_result_t res; 159 reply.readInt32(&res); 160 return res; 161 } 162 163 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, 164 pid_t clientProcessId, 165 pid_t clientThreadId, 166 int64_t periodNanoseconds) 167 override { 168 Parcel data, reply; 169 // send command 170 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 171 data.writeInt32(streamHandle); 172 data.writeInt32((int32_t) clientProcessId); 173 data.writeInt32((int32_t) clientThreadId); 174 data.writeInt64(periodNanoseconds); 175 status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply); 176 if (err != NO_ERROR) { 177 return AAudioConvert_androidToAAudioResult(err); 178 } 179 // parse reply 180 aaudio_result_t res; 181 reply.readInt32(&res); 182 return res; 183 } 184 185 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, 186 pid_t clientProcessId, 187 pid_t clientThreadId) 188 override { 189 Parcel data, reply; 190 // send command 191 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 192 data.writeInt32(streamHandle); 193 data.writeInt32((int32_t) clientProcessId); 194 data.writeInt32((int32_t) clientThreadId); 195 status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply); 196 if (err != NO_ERROR) { 197 return AAudioConvert_androidToAAudioResult(err); 198 } 199 // parse reply 200 aaudio_result_t res; 201 reply.readInt32(&res); 202 return res; 203 } 204 205}; 206 207// Implement an interface to the service. 208// This is here so that you don't have to link with libaaudio static library. 209IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService"); 210 211// The order of parameters in the Parcels must match with code in BpAAudioService 212 213status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, 214 Parcel* reply, uint32_t flags) { 215 aaudio_handle_t stream; 216 aaudio::AAudioStreamRequest request; 217 aaudio::AAudioStreamConfiguration configuration; 218 pid_t pid; 219 pid_t tid; 220 int64_t nanoseconds; 221 aaudio_result_t result; 222 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags); 223 data.checkInterface(this); 224 225 switch(code) { 226 case OPEN_STREAM: { 227 request.readFromParcel(&data); 228 229 ALOGD("BnAAudioService::client openStream request dump --------------------"); 230 request.dump(); 231 232 stream = openStream(request, configuration); 233 ALOGV("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", stream); 234 reply->writeInt32(stream); 235 configuration.writeToParcel(reply); 236 return NO_ERROR; 237 } break; 238 239 case CLOSE_STREAM: { 240 data.readInt32(&stream); 241 ALOGV("BnAAudioService::onTransact CLOSE_STREAM 0x%08X", stream); 242 result = closeStream(stream); 243 reply->writeInt32(result); 244 return NO_ERROR; 245 } break; 246 247 case GET_STREAM_DESCRIPTION: { 248 data.readInt32(&stream); 249 ALOGI("BnAAudioService::onTransact GET_STREAM_DESCRIPTION 0x%08X", stream); 250 aaudio::AudioEndpointParcelable parcelable; 251 result = getStreamDescription(stream, parcelable); 252 ALOGI("BnAAudioService::onTransact getStreamDescription() returns %d", result); 253 if (result != AAUDIO_OK) { 254 return AAudioConvert_aaudioToAndroidStatus(result); 255 } 256 result = parcelable.validate(); 257 if (result != AAUDIO_OK) { 258 ALOGE("BnAAudioService::onTransact getStreamDescription() returns %d", result); 259 parcelable.dump(); 260 return AAudioConvert_aaudioToAndroidStatus(result); 261 } 262 reply->writeInt32(result); 263 parcelable.writeToParcel(reply); 264 return NO_ERROR; 265 } break; 266 267 case START_STREAM: { 268 data.readInt32(&stream); 269 result = startStream(stream); 270 ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d", 271 stream, result); 272 reply->writeInt32(result); 273 return NO_ERROR; 274 } break; 275 276 case PAUSE_STREAM: { 277 data.readInt32(&stream); 278 result = pauseStream(stream); 279 ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d", 280 stream, result); 281 reply->writeInt32(result); 282 return NO_ERROR; 283 } break; 284 285 case FLUSH_STREAM: { 286 data.readInt32(&stream); 287 result = flushStream(stream); 288 ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d", 289 stream, result); 290 reply->writeInt32(result); 291 return NO_ERROR; 292 } break; 293 294 case REGISTER_AUDIO_THREAD: { 295 data.readInt32(&stream); 296 data.readInt32(&pid); 297 data.readInt32(&tid); 298 data.readInt64(&nanoseconds); 299 result = registerAudioThread(stream, pid, tid, nanoseconds); 300 ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d", 301 stream, result); 302 reply->writeInt32(result); 303 return NO_ERROR; 304 } break; 305 306 case UNREGISTER_AUDIO_THREAD: { 307 data.readInt32(&stream); 308 data.readInt32(&pid); 309 data.readInt32(&tid); 310 result = unregisterAudioThread(stream, pid, tid); 311 ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d", 312 stream, result); 313 reply->writeInt32(result); 314 return NO_ERROR; 315 } break; 316 317 default: 318 // ALOGW("BnAAudioService::onTransact not handled %u", code); 319 return BBinder::onTransact(code, data, reply, flags); 320 } 321} 322 323} /* namespace android */ 324