IAAudioService.cpp revision 901f65deb49786f4dffd39ac965c0bb681392c0b
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#define LOG_TAG "AAudio" 18//#define LOG_NDEBUG 0 19#include <utils/Log.h> 20 21#include <aaudio/AAudio.h> 22#include <binder/IPCThreadState.h> 23 24#include "binding/AudioEndpointParcelable.h" 25#include "binding/AAudioStreamRequest.h" 26#include "binding/AAudioServiceDefinitions.h" 27#include "binding/AAudioStreamConfiguration.h" 28#include "binding/IAAudioService.h" 29#include "utility/AAudioUtilities.h" 30 31namespace android { 32 33using aaudio::aaudio_handle_t; 34 35/** 36 * This is used by the AAudio Client to talk to the AAudio Service. 37 * 38 * The order of parameters in the Parcels must match with code in AAudioService.cpp. 39 */ 40class BpAAudioService : public BpInterface<IAAudioService> 41{ 42public: 43 explicit BpAAudioService(const sp<IBinder>& impl) 44 : BpInterface<IAAudioService>(impl) 45 { 46 } 47 48 void registerClient(const sp<IAAudioClient>& client) override 49 { 50 Parcel data, reply; 51 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 52 data.writeStrongBinder(IInterface::asBinder(client)); 53 remote()->transact(REGISTER_CLIENT, data, &reply); 54 } 55 56 aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request, 57 aaudio::AAudioStreamConfiguration &configurationOutput) override { 58 Parcel data, reply; 59 // send command 60 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 61 // request.dump(); 62 request.writeToParcel(&data); 63 status_t err = remote()->transact(OPEN_STREAM, data, &reply); 64 if (err != NO_ERROR) { 65 ALOGE("BpAAudioService::client openStream transact failed %d", err); 66 return AAudioConvert_androidToAAudioResult(err); 67 } 68 // parse reply 69 aaudio_handle_t stream; 70 err = reply.readInt32(&stream); 71 if (err != NO_ERROR) { 72 ALOGE("BpAAudioService::client transact(OPEN_STREAM) readInt %d", err); 73 return AAudioConvert_androidToAAudioResult(err); 74 } else if (stream < 0) { 75 ALOGE("BpAAudioService::client OPEN_STREAM passed stream %d", stream); 76 return stream; 77 } 78 err = configurationOutput.readFromParcel(&reply); 79 if (err != NO_ERROR) { 80 ALOGE("BpAAudioService::client openStream readFromParcel failed %d", err); 81 closeStream(stream); 82 return AAudioConvert_androidToAAudioResult(err); 83 } 84 return stream; 85 } 86 87 virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override { 88 Parcel data, reply; 89 // send command 90 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 91 data.writeInt32(streamHandle); 92 status_t err = remote()->transact(CLOSE_STREAM, data, &reply); 93 if (err != NO_ERROR) { 94 ALOGE("BpAAudioService::client closeStream transact failed %d", err); 95 return AAudioConvert_androidToAAudioResult(err); 96 } 97 // parse reply 98 aaudio_result_t res; 99 reply.readInt32(&res); 100 return res; 101 } 102 103 virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle, 104 aaudio::AudioEndpointParcelable &parcelable) { 105 Parcel data, reply; 106 // send command 107 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 108 data.writeInt32(streamHandle); 109 status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply); 110 if (err != NO_ERROR) { 111 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err); 112 return AAudioConvert_androidToAAudioResult(err); 113 } 114 // parse reply 115 aaudio_result_t result; 116 err = reply.readInt32(&result); 117 if (err != NO_ERROR) { 118 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) readInt %d", err); 119 return AAudioConvert_androidToAAudioResult(err); 120 } else if (result != AAUDIO_OK) { 121 ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION passed result %d", result); 122 return result; 123 } 124 err = parcelable.readFromParcel(&reply);; 125 if (err != NO_ERROR) { 126 ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err); 127 return AAudioConvert_androidToAAudioResult(err); 128 } 129 //parcelable.dump(); 130 result = parcelable.validate(); 131 if (result != AAUDIO_OK) { 132 ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION validation fails %d", result); 133 return result; 134 } 135 return result; 136 } 137 138 // TODO should we wait for a reply? 139 virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override { 140 Parcel data, reply; 141 // send command 142 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 143 data.writeInt32(streamHandle); 144 status_t err = remote()->transact(START_STREAM, data, &reply); 145 if (err != NO_ERROR) { 146 return AAudioConvert_androidToAAudioResult(err); 147 } 148 // parse reply 149 aaudio_result_t res; 150 reply.readInt32(&res); 151 return res; 152 } 153 154 virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override { 155 Parcel data, reply; 156 // send command 157 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 158 data.writeInt32(streamHandle); 159 status_t err = remote()->transact(PAUSE_STREAM, data, &reply); 160 if (err != NO_ERROR) { 161 return AAudioConvert_androidToAAudioResult(err); 162 } 163 // parse reply 164 aaudio_result_t res; 165 reply.readInt32(&res); 166 return res; 167 } 168 169 virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) override { 170 Parcel data, reply; 171 // send command 172 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 173 data.writeInt32(streamHandle); 174 status_t err = remote()->transact(STOP_STREAM, data, &reply); 175 if (err != NO_ERROR) { 176 return AAudioConvert_androidToAAudioResult(err); 177 } 178 // parse reply 179 aaudio_result_t res; 180 reply.readInt32(&res); 181 return res; 182 } 183 184 virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override { 185 Parcel data, reply; 186 // send command 187 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 188 data.writeInt32(streamHandle); 189 status_t err = remote()->transact(FLUSH_STREAM, data, &reply); 190 if (err != NO_ERROR) { 191 return AAudioConvert_androidToAAudioResult(err); 192 } 193 // parse reply 194 aaudio_result_t res; 195 reply.readInt32(&res); 196 return res; 197 } 198 199 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, 200 pid_t clientThreadId, 201 int64_t periodNanoseconds) 202 override { 203 Parcel data, reply; 204 // send command 205 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 206 data.writeInt32(streamHandle); 207 data.writeInt32((int32_t) clientThreadId); 208 data.writeInt64(periodNanoseconds); 209 status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply); 210 if (err != NO_ERROR) { 211 return AAudioConvert_androidToAAudioResult(err); 212 } 213 // parse reply 214 aaudio_result_t res; 215 reply.readInt32(&res); 216 return res; 217 } 218 219 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, 220 pid_t clientThreadId) 221 override { 222 Parcel data, reply; 223 // send command 224 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 225 data.writeInt32(streamHandle); 226 data.writeInt32((int32_t) clientThreadId); 227 status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply); 228 if (err != NO_ERROR) { 229 return AAudioConvert_androidToAAudioResult(err); 230 } 231 // parse reply 232 aaudio_result_t res; 233 reply.readInt32(&res); 234 return res; 235 } 236 237}; 238 239// Implement an interface to the service. 240// This is here so that you don't have to link with libaaudio static library. 241IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService"); 242 243// The order of parameters in the Parcels must match with code in BpAAudioService 244 245status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, 246 Parcel* reply, uint32_t flags) { 247 aaudio_handle_t streamHandle; 248 aaudio::AAudioStreamRequest request; 249 aaudio::AAudioStreamConfiguration configuration; 250 pid_t tid; 251 int64_t nanoseconds; 252 aaudio_result_t result; 253 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags); 254 255 switch(code) { 256 case REGISTER_CLIENT: { 257 CHECK_INTERFACE(IAAudioService, data, reply); 258 sp<IAAudioClient> client = interface_cast<IAAudioClient>( 259 data.readStrongBinder()); 260 registerClient(client); 261 return NO_ERROR; 262 } break; 263 264 case OPEN_STREAM: { 265 CHECK_INTERFACE(IAAudioService, data, reply); 266 request.readFromParcel(&data); 267 result = request.validate(); 268 if (result != AAUDIO_OK) { 269 streamHandle = result; 270 } else { 271 //ALOGD("BnAAudioService::client openStream request dump --------------------"); 272 //request.dump(); 273 // Override the uid and pid from the client in case they are incorrect. 274 request.setUserId(IPCThreadState::self()->getCallingUid()); 275 request.setProcessId(IPCThreadState::self()->getCallingPid()); 276 streamHandle = openStream(request, configuration); 277 //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", 278 // streamHandle); 279 } 280 reply->writeInt32(streamHandle); 281 configuration.writeToParcel(reply); 282 return NO_ERROR; 283 } break; 284 285 case CLOSE_STREAM: { 286 CHECK_INTERFACE(IAAudioService, data, reply); 287 data.readInt32(&streamHandle); 288 result = closeStream(streamHandle); 289 //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d", 290 // streamHandle, result); 291 reply->writeInt32(result); 292 return NO_ERROR; 293 } break; 294 295 case GET_STREAM_DESCRIPTION: { 296 CHECK_INTERFACE(IAAudioService, data, reply); 297 data.readInt32(&streamHandle); 298 aaudio::AudioEndpointParcelable parcelable; 299 result = getStreamDescription(streamHandle, parcelable); 300 if (result != AAUDIO_OK) { 301 return AAudioConvert_aaudioToAndroidStatus(result); 302 } 303 result = parcelable.validate(); 304 if (result != AAUDIO_OK) { 305 ALOGE("BnAAudioService::onTransact getStreamDescription() returns %d", result); 306 parcelable.dump(); 307 return AAudioConvert_aaudioToAndroidStatus(result); 308 } 309 reply->writeInt32(result); 310 parcelable.writeToParcel(reply); 311 return NO_ERROR; 312 } break; 313 314 case START_STREAM: { 315 CHECK_INTERFACE(IAAudioService, data, reply); 316 data.readInt32(&streamHandle); 317 result = startStream(streamHandle); 318 ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d", 319 streamHandle, result); 320 reply->writeInt32(result); 321 return NO_ERROR; 322 } break; 323 324 case PAUSE_STREAM: { 325 CHECK_INTERFACE(IAAudioService, data, reply); 326 data.readInt32(&streamHandle); 327 result = pauseStream(streamHandle); 328 ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d", 329 streamHandle, result); 330 reply->writeInt32(result); 331 return NO_ERROR; 332 } break; 333 334 case STOP_STREAM: { 335 CHECK_INTERFACE(IAAudioService, data, reply); 336 data.readInt32(&streamHandle); 337 result = stopStream(streamHandle); 338 ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d", 339 streamHandle, result); 340 reply->writeInt32(result); 341 return NO_ERROR; 342 } break; 343 344 case FLUSH_STREAM: { 345 CHECK_INTERFACE(IAAudioService, data, reply); 346 data.readInt32(&streamHandle); 347 result = flushStream(streamHandle); 348 ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d", 349 streamHandle, result); 350 reply->writeInt32(result); 351 return NO_ERROR; 352 } break; 353 354 case REGISTER_AUDIO_THREAD: { 355 CHECK_INTERFACE(IAAudioService, data, reply); 356 data.readInt32(&streamHandle); 357 data.readInt32(&tid); 358 data.readInt64(&nanoseconds); 359 result = registerAudioThread(streamHandle, tid, nanoseconds); 360 ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d", 361 streamHandle, result); 362 reply->writeInt32(result); 363 return NO_ERROR; 364 } break; 365 366 case UNREGISTER_AUDIO_THREAD: { 367 CHECK_INTERFACE(IAAudioService, data, reply); 368 data.readInt32(&streamHandle); 369 data.readInt32(&tid); 370 result = unregisterAudioThread(streamHandle, tid); 371 ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d", 372 streamHandle, result); 373 reply->writeInt32(result); 374 return NO_ERROR; 375 } break; 376 377 default: 378 // ALOGW("BnAAudioService::onTransact not handled %u", code); 379 return BBinder::onTransact(code, data, reply, flags); 380 } 381} 382 383} /* namespace android */ 384