IAAudioService.cpp revision f53e613b3dedab3ecada2c93d8846233c442d129
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/AAudioStreamConfiguration.h" 22#include "binding/IAAudioService.h" 23#include "utility/AAudioUtilities.h" 24 25namespace android { 26 27/** 28 * This is used by the AAudio Client to talk to the AAudio Service. 29 * 30 * The order of parameters in the Parcels must match with code in AAudioService.cpp. 31 */ 32class BpAAudioService : public BpInterface<IAAudioService> 33{ 34public: 35 explicit BpAAudioService(const sp<IBinder>& impl) 36 : BpInterface<IAAudioService>(impl) 37 { 38 } 39 40 virtual aaudio_handle_t openStream(aaudio::AAudioStreamRequest &request, 41 aaudio::AAudioStreamConfiguration &configuration) override { 42 Parcel data, reply; 43 // send command 44 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 45 request.writeToParcel(&data); 46 status_t err = remote()->transact(OPEN_STREAM, data, &reply); 47 if (err != NO_ERROR) { 48 return AAudioConvert_androidToAAudioResult(err); 49 } 50 // parse reply 51 aaudio_handle_t stream; 52 reply.readInt32(&stream); 53 configuration.readFromParcel(&reply); 54 return stream; 55 } 56 57 virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override { 58 Parcel data, reply; 59 // send command 60 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 61 data.writeInt32(streamHandle); 62 status_t err = remote()->transact(CLOSE_STREAM, data, &reply); 63 if (err != NO_ERROR) { 64 return AAudioConvert_androidToAAudioResult(err); 65 } 66 // parse reply 67 aaudio_result_t res; 68 reply.readInt32(&res); 69 return res; 70 } 71 72 virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle, 73 aaudio::AudioEndpointParcelable &parcelable) { 74 Parcel data, reply; 75 // send command 76 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 77 data.writeInt32(streamHandle); 78 status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply); 79 if (err != NO_ERROR) { 80 return AAudioConvert_androidToAAudioResult(err); 81 } 82 // parse reply 83 parcelable.readFromParcel(&reply); 84 parcelable.dump(); 85 aaudio_result_t result = parcelable.validate(); 86 if (result != AAUDIO_OK) { 87 return result; 88 } 89 reply.readInt32(&result); 90 return result; 91 } 92 93 // TODO should we wait for a reply? 94 virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override { 95 Parcel data, reply; 96 // send command 97 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 98 data.writeInt32(streamHandle); 99 status_t err = remote()->transact(START_STREAM, data, &reply); 100 if (err != NO_ERROR) { 101 return AAudioConvert_androidToAAudioResult(err); 102 } 103 // parse reply 104 aaudio_result_t res; 105 reply.readInt32(&res); 106 return res; 107 } 108 109 virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override { 110 Parcel data, reply; 111 // send command 112 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 113 data.writeInt32(streamHandle); 114 status_t err = remote()->transact(PAUSE_STREAM, data, &reply); 115 if (err != NO_ERROR) { 116 return AAudioConvert_androidToAAudioResult(err); 117 } 118 // parse reply 119 aaudio_result_t res; 120 reply.readInt32(&res); 121 return res; 122 } 123 124 virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override { 125 Parcel data, reply; 126 // send command 127 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 128 data.writeInt32(streamHandle); 129 status_t err = remote()->transact(FLUSH_STREAM, data, &reply); 130 if (err != NO_ERROR) { 131 return AAudioConvert_androidToAAudioResult(err); 132 } 133 // parse reply 134 aaudio_result_t res; 135 reply.readInt32(&res); 136 return res; 137 } 138 139 virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId, 140 aaudio_nanoseconds_t periodNanoseconds) 141 override { 142 Parcel data, reply; 143 // send command 144 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 145 data.writeInt32(streamHandle); 146 data.writeInt32((int32_t) clientThreadId); 147 data.writeInt64(periodNanoseconds); 148 status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply); 149 if (err != NO_ERROR) { 150 return AAudioConvert_androidToAAudioResult(err); 151 } 152 // parse reply 153 aaudio_result_t res; 154 reply.readInt32(&res); 155 return res; 156 } 157 158 virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId) 159 override { 160 Parcel data, reply; 161 // send command 162 data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor()); 163 data.writeInt32(streamHandle); 164 data.writeInt32((int32_t) clientThreadId); 165 status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply); 166 if (err != NO_ERROR) { 167 return AAudioConvert_androidToAAudioResult(err); 168 } 169 // parse reply 170 aaudio_result_t res; 171 reply.readInt32(&res); 172 return res; 173 } 174 175}; 176 177// Implement an interface to the service. 178// This is here so that you don't have to link with liboboe static library. 179IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService"); 180 181// The order of parameters in the Parcels must match with code in BpAAudioService 182 183status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, 184 Parcel* reply, uint32_t flags) { 185 AAudioStream stream; 186 aaudio::AAudioStreamRequest request; 187 aaudio::AAudioStreamConfiguration configuration; 188 pid_t pid; 189 aaudio_nanoseconds_t nanoseconds; 190 aaudio_result_t result; 191 ALOGV("BnAAudioService::onTransact(%i) %i", code, flags); 192 data.checkInterface(this); 193 194 switch(code) { 195 case OPEN_STREAM: { 196 request.readFromParcel(&data); 197 stream = openStream(request, configuration); 198 ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", stream); 199 reply->writeInt32(stream); 200 configuration.writeToParcel(reply); 201 return NO_ERROR; 202 } break; 203 204 case CLOSE_STREAM: { 205 data.readInt32(&stream); 206 ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X", stream); 207 result = closeStream(stream); 208 reply->writeInt32(result); 209 return NO_ERROR; 210 } break; 211 212 case GET_STREAM_DESCRIPTION: { 213 data.readInt32(&stream); 214 ALOGD("BnAAudioService::onTransact GET_STREAM_DESCRIPTION 0x%08X", stream); 215 aaudio::AudioEndpointParcelable parcelable; 216 result = getStreamDescription(stream, parcelable); 217 if (result != AAUDIO_OK) { 218 return AAudioConvert_aaudioToAndroidStatus(result); 219 } 220 parcelable.dump(); 221 result = parcelable.validate(); 222 if (result != AAUDIO_OK) { 223 return AAudioConvert_aaudioToAndroidStatus(result); 224 } 225 parcelable.writeToParcel(reply); 226 reply->writeInt32(result); 227 return NO_ERROR; 228 } break; 229 230 case START_STREAM: { 231 data.readInt32(&stream); 232 result = startStream(stream); 233 ALOGD("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d", 234 stream, result); 235 reply->writeInt32(result); 236 return NO_ERROR; 237 } break; 238 239 case PAUSE_STREAM: { 240 data.readInt32(&stream); 241 result = pauseStream(stream); 242 ALOGD("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d", 243 stream, result); 244 reply->writeInt32(result); 245 return NO_ERROR; 246 } break; 247 248 case FLUSH_STREAM: { 249 data.readInt32(&stream); 250 result = flushStream(stream); 251 ALOGD("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d", 252 stream, result); 253 reply->writeInt32(result); 254 return NO_ERROR; 255 } break; 256 257 case REGISTER_AUDIO_THREAD: { 258 data.readInt32(&stream); 259 data.readInt32(&pid); 260 data.readInt64(&nanoseconds); 261 result = registerAudioThread(stream, pid, nanoseconds); 262 ALOGD("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d", 263 stream, result); 264 reply->writeInt32(result); 265 return NO_ERROR; 266 } break; 267 268 case UNREGISTER_AUDIO_THREAD: { 269 data.readInt32(&stream); 270 data.readInt32(&pid); 271 result = unregisterAudioThread(stream, pid); 272 ALOGD("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d", 273 stream, result); 274 reply->writeInt32(result); 275 return NO_ERROR; 276 } break; 277 278 default: 279 // ALOGW("BnAAudioService::onTransact not handled %u", code); 280 return BBinder::onTransact(code, data, reply, flags); 281 } 282} 283 284} /* namespace android */ 285