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 31 namespace android { 32 33 using 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 */ 40 class BpAAudioService : public BpInterface<IAAudioService> 41 { 42 public: 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 return result; 130 } 131 132 // TODO should we wait for a reply? 133 virtual aaudio_result_t startStream(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(START_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 pauseStream(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(PAUSE_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 stopStream(aaudio_handle_t streamHandle) override { 164 Parcel data, reply; 165 // send command 166 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 167 data.writeInt32(streamHandle); 168 status_t err = remote()->transact(STOP_STREAM, data, &reply); 169 if (err != NO_ERROR) { 170 return AAudioConvert_androidToAAudioResult(err); 171 } 172 // parse reply 173 aaudio_result_t res; 174 reply.readInt32(&res); 175 return res; 176 } 177 178 virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override { 179 Parcel data, reply; 180 // send command 181 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 182 data.writeInt32(streamHandle); 183 status_t err = remote()->transact(FLUSH_STREAM, data, &reply); 184 if (err != NO_ERROR) { 185 return AAudioConvert_androidToAAudioResult(err); 186 } 187 // parse reply 188 aaudio_result_t res; 189 reply.readInt32(&res); 190 return res; 191 } 192 193 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, 194 pid_t clientThreadId, 195 int64_t periodNanoseconds) 196 override { 197 Parcel data, reply; 198 // send command 199 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 200 data.writeInt32(streamHandle); 201 data.writeInt32((int32_t) clientThreadId); 202 data.writeInt64(periodNanoseconds); 203 status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply); 204 if (err != NO_ERROR) { 205 return AAudioConvert_androidToAAudioResult(err); 206 } 207 // parse reply 208 aaudio_result_t res; 209 reply.readInt32(&res); 210 return res; 211 } 212 213 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, 214 pid_t clientThreadId) 215 override { 216 Parcel data, reply; 217 // send command 218 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 219 data.writeInt32(streamHandle); 220 data.writeInt32((int32_t) clientThreadId); 221 status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply); 222 if (err != NO_ERROR) { 223 return AAudioConvert_androidToAAudioResult(err); 224 } 225 // parse reply 226 aaudio_result_t res; 227 reply.readInt32(&res); 228 return res; 229 } 230 231 }; 232 233 // Implement an interface to the service. 234 // This is here so that you don't have to link with libaaudio static library. 235 IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService"); 236 237 // The order of parameters in the Parcels must match with code in BpAAudioService 238 239 status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, 240 Parcel* reply, uint32_t flags) { 241 aaudio_handle_t streamHandle; 242 aaudio::AAudioStreamRequest request; 243 aaudio::AAudioStreamConfiguration configuration; 244 pid_t tid; 245 int64_t nanoseconds; 246 aaudio_result_t result; 247 status_t status = NO_ERROR; 248 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags); 249 250 switch(code) { 251 case REGISTER_CLIENT: { 252 CHECK_INTERFACE(IAAudioService, data, reply); 253 sp<IAAudioClient> client = interface_cast<IAAudioClient>( 254 data.readStrongBinder()); 255 registerClient(client); 256 return NO_ERROR; 257 } break; 258 259 case OPEN_STREAM: { 260 CHECK_INTERFACE(IAAudioService, data, reply); 261 request.readFromParcel(&data); 262 result = request.validate(); 263 if (result != AAUDIO_OK) { 264 streamHandle = result; 265 } else { 266 //ALOGD("BnAAudioService::client openStream request dump --------------------"); 267 //request.dump(); 268 // Override the uid and pid from the client in case they are incorrect. 269 request.setUserId(IPCThreadState::self()->getCallingUid()); 270 request.setProcessId(IPCThreadState::self()->getCallingPid()); 271 streamHandle = openStream(request, configuration); 272 //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", 273 // streamHandle); 274 } 275 reply->writeInt32(streamHandle); 276 configuration.writeToParcel(reply); 277 return NO_ERROR; 278 } break; 279 280 case CLOSE_STREAM: { 281 CHECK_INTERFACE(IAAudioService, data, reply); 282 data.readInt32(&streamHandle); 283 result = closeStream(streamHandle); 284 //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d", 285 // streamHandle, result); 286 reply->writeInt32(result); 287 return NO_ERROR; 288 } break; 289 290 case GET_STREAM_DESCRIPTION: { 291 CHECK_INTERFACE(IAAudioService, data, reply); 292 status = data.readInt32(&streamHandle); 293 if (status != NO_ERROR) { 294 return status; 295 } 296 aaudio::AudioEndpointParcelable parcelable; 297 result = getStreamDescription(streamHandle, parcelable); 298 if (result != AAUDIO_OK) { 299 return AAudioConvert_aaudioToAndroidStatus(result); 300 } 301 status = reply->writeInt32(result); 302 if (status != NO_ERROR) { 303 return status; 304 } 305 return parcelable.writeToParcel(reply); 306 } break; 307 308 case START_STREAM: { 309 CHECK_INTERFACE(IAAudioService, data, reply); 310 data.readInt32(&streamHandle); 311 result = startStream(streamHandle); 312 ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d", 313 streamHandle, result); 314 reply->writeInt32(result); 315 return NO_ERROR; 316 } break; 317 318 case PAUSE_STREAM: { 319 CHECK_INTERFACE(IAAudioService, data, reply); 320 data.readInt32(&streamHandle); 321 result = pauseStream(streamHandle); 322 ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d", 323 streamHandle, result); 324 reply->writeInt32(result); 325 return NO_ERROR; 326 } break; 327 328 case STOP_STREAM: { 329 CHECK_INTERFACE(IAAudioService, data, reply); 330 data.readInt32(&streamHandle); 331 result = stopStream(streamHandle); 332 ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d", 333 streamHandle, result); 334 reply->writeInt32(result); 335 return NO_ERROR; 336 } break; 337 338 case FLUSH_STREAM: { 339 CHECK_INTERFACE(IAAudioService, data, reply); 340 data.readInt32(&streamHandle); 341 result = flushStream(streamHandle); 342 ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d", 343 streamHandle, result); 344 reply->writeInt32(result); 345 return NO_ERROR; 346 } break; 347 348 case REGISTER_AUDIO_THREAD: { 349 CHECK_INTERFACE(IAAudioService, data, reply); 350 data.readInt32(&streamHandle); 351 data.readInt32(&tid); 352 data.readInt64(&nanoseconds); 353 result = registerAudioThread(streamHandle, tid, nanoseconds); 354 ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d", 355 streamHandle, result); 356 reply->writeInt32(result); 357 return NO_ERROR; 358 } break; 359 360 case UNREGISTER_AUDIO_THREAD: { 361 CHECK_INTERFACE(IAAudioService, data, reply); 362 data.readInt32(&streamHandle); 363 data.readInt32(&tid); 364 result = unregisterAudioThread(streamHandle, tid); 365 ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d", 366 streamHandle, result); 367 reply->writeInt32(result); 368 return NO_ERROR; 369 } break; 370 371 default: 372 // ALOGW("BnAAudioService::onTransact not handled %u", code); 373 return BBinder::onTransact(code, data, reply, flags); 374 } 375 } 376 377 } /* namespace android */ 378