1/* //device/extlibs/pv/android/IAudioflinger.cpp 2** 3** Copyright 2007, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#define LOG_TAG "IAudioFlinger" 19#include <utils/Log.h> 20 21#include <stdint.h> 22#include <sys/types.h> 23 24#include <utils/Parcel.h> 25 26#include <media/IAudioFlinger.h> 27 28namespace android { 29 30enum { 31 CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION, 32 OPEN_RECORD, 33 SAMPLE_RATE, 34 CHANNEL_COUNT, 35 FORMAT, 36 FRAME_COUNT, 37 LATENCY, 38 SET_MASTER_VOLUME, 39 SET_MASTER_MUTE, 40 MASTER_VOLUME, 41 MASTER_MUTE, 42 SET_STREAM_VOLUME, 43 SET_STREAM_MUTE, 44 STREAM_VOLUME, 45 STREAM_MUTE, 46 SET_MODE, 47 GET_MODE, 48 SET_ROUTING, 49 GET_ROUTING, 50 SET_MIC_MUTE, 51 GET_MIC_MUTE, 52 IS_MUSIC_ACTIVE, 53 SET_PARAMETER, 54 REGISTER_CLIENT, 55 GET_INPUTBUFFERSIZE, 56 WAKE_UP, 57 IS_A2DP_ENABLED 58}; 59 60class BpAudioFlinger : public BpInterface<IAudioFlinger> 61{ 62public: 63 BpAudioFlinger(const sp<IBinder>& impl) 64 : BpInterface<IAudioFlinger>(impl) 65 { 66 } 67 68 virtual sp<IAudioTrack> createTrack( 69 pid_t pid, 70 int streamType, 71 uint32_t sampleRate, 72 int format, 73 int channelCount, 74 int frameCount, 75 uint32_t flags, 76 const sp<IMemory>& sharedBuffer, 77 status_t *status) 78 { 79 Parcel data, reply; 80 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 81 data.writeInt32(pid); 82 data.writeInt32(streamType); 83 data.writeInt32(sampleRate); 84 data.writeInt32(format); 85 data.writeInt32(channelCount); 86 data.writeInt32(frameCount); 87 data.writeInt32(flags); 88 data.writeStrongBinder(sharedBuffer->asBinder()); 89 status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply); 90 if (lStatus != NO_ERROR) { 91 LOGE("createTrack error: %s", strerror(-lStatus)); 92 } 93 lStatus = reply.readInt32(); 94 if (status) { 95 *status = lStatus; 96 } 97 return interface_cast<IAudioTrack>(reply.readStrongBinder()); 98 } 99 100 virtual sp<IAudioRecord> openRecord( 101 pid_t pid, 102 int inputSource, 103 uint32_t sampleRate, 104 int format, 105 int channelCount, 106 int frameCount, 107 uint32_t flags, 108 status_t *status) 109 { 110 Parcel data, reply; 111 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 112 data.writeInt32(pid); 113 data.writeInt32(inputSource); 114 data.writeInt32(sampleRate); 115 data.writeInt32(format); 116 data.writeInt32(channelCount); 117 data.writeInt32(frameCount); 118 data.writeInt32(flags); 119 remote()->transact(OPEN_RECORD, data, &reply); 120 status_t lStatus = reply.readInt32(); 121 if (status) { 122 *status = lStatus; 123 } 124 return interface_cast<IAudioRecord>(reply.readStrongBinder()); 125 } 126 127 virtual uint32_t sampleRate(int output) const 128 { 129 Parcel data, reply; 130 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 131 data.writeInt32(output); 132 remote()->transact(SAMPLE_RATE, data, &reply); 133 return reply.readInt32(); 134 } 135 136 virtual int channelCount(int output) const 137 { 138 Parcel data, reply; 139 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 140 data.writeInt32(output); 141 remote()->transact(CHANNEL_COUNT, data, &reply); 142 return reply.readInt32(); 143 } 144 145 virtual int format(int output) const 146 { 147 Parcel data, reply; 148 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 149 data.writeInt32(output); 150 remote()->transact(FORMAT, data, &reply); 151 return reply.readInt32(); 152 } 153 154 virtual size_t frameCount(int output) const 155 { 156 Parcel data, reply; 157 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 158 data.writeInt32(output); 159 remote()->transact(FRAME_COUNT, data, &reply); 160 return reply.readInt32(); 161 } 162 163 virtual uint32_t latency(int output) const 164 { 165 Parcel data, reply; 166 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 167 data.writeInt32(output); 168 remote()->transact(LATENCY, data, &reply); 169 return reply.readInt32(); 170 } 171 172 virtual status_t setMasterVolume(float value) 173 { 174 Parcel data, reply; 175 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 176 data.writeFloat(value); 177 remote()->transact(SET_MASTER_VOLUME, data, &reply); 178 return reply.readInt32(); 179 } 180 181 virtual status_t setMasterMute(bool muted) 182 { 183 Parcel data, reply; 184 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 185 data.writeInt32(muted); 186 remote()->transact(SET_MASTER_MUTE, data, &reply); 187 return reply.readInt32(); 188 } 189 190 virtual float masterVolume() const 191 { 192 Parcel data, reply; 193 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 194 remote()->transact(MASTER_VOLUME, data, &reply); 195 return reply.readFloat(); 196 } 197 198 virtual bool masterMute() const 199 { 200 Parcel data, reply; 201 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 202 remote()->transact(MASTER_MUTE, data, &reply); 203 return reply.readInt32(); 204 } 205 206 virtual status_t setStreamVolume(int stream, float value) 207 { 208 Parcel data, reply; 209 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 210 data.writeInt32(stream); 211 data.writeFloat(value); 212 remote()->transact(SET_STREAM_VOLUME, data, &reply); 213 return reply.readInt32(); 214 } 215 216 virtual status_t setStreamMute(int stream, bool muted) 217 { 218 Parcel data, reply; 219 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 220 data.writeInt32(stream); 221 data.writeInt32(muted); 222 remote()->transact(SET_STREAM_MUTE, data, &reply); 223 return reply.readInt32(); 224 } 225 226 virtual float streamVolume(int stream) const 227 { 228 Parcel data, reply; 229 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 230 data.writeInt32(stream); 231 remote()->transact(STREAM_VOLUME, data, &reply); 232 return reply.readFloat(); 233 } 234 235 virtual bool streamMute(int stream) const 236 { 237 Parcel data, reply; 238 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 239 data.writeInt32(stream); 240 remote()->transact(STREAM_MUTE, data, &reply); 241 return reply.readInt32(); 242 } 243 244 virtual status_t setRouting(int mode, uint32_t routes, uint32_t mask) 245 { 246 Parcel data, reply; 247 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 248 data.writeInt32(mode); 249 data.writeInt32(routes); 250 data.writeInt32(mask); 251 remote()->transact(SET_ROUTING, data, &reply); 252 return reply.readInt32(); 253 } 254 255 virtual uint32_t getRouting(int mode) const 256 { 257 Parcel data, reply; 258 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 259 data.writeInt32(mode); 260 remote()->transact(GET_ROUTING, data, &reply); 261 return reply.readInt32(); 262 } 263 264 virtual status_t setMode(int mode) 265 { 266 Parcel data, reply; 267 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 268 data.writeInt32(mode); 269 remote()->transact(SET_MODE, data, &reply); 270 return reply.readInt32(); 271 } 272 273 virtual int getMode() const 274 { 275 Parcel data, reply; 276 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 277 remote()->transact(GET_MODE, data, &reply); 278 return reply.readInt32(); 279 } 280 281 virtual status_t setMicMute(bool state) 282 { 283 Parcel data, reply; 284 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 285 data.writeInt32(state); 286 remote()->transact(SET_MIC_MUTE, data, &reply); 287 return reply.readInt32(); 288 } 289 290 virtual bool getMicMute() const 291 { 292 Parcel data, reply; 293 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 294 remote()->transact(GET_MIC_MUTE, data, &reply); 295 return reply.readInt32(); 296 } 297 298 virtual bool isMusicActive() const 299 { 300 Parcel data, reply; 301 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 302 remote()->transact(IS_MUSIC_ACTIVE, data, &reply); 303 return reply.readInt32(); 304 } 305 306 virtual status_t setParameter(const char* key, const char* value) 307 { 308 Parcel data, reply; 309 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 310 data.writeCString(key); 311 data.writeCString(value); 312 remote()->transact(SET_PARAMETER, data, &reply); 313 return reply.readInt32(); 314 } 315 316 virtual void registerClient(const sp<IAudioFlingerClient>& client) 317 { 318 Parcel data, reply; 319 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 320 data.writeStrongBinder(client->asBinder()); 321 remote()->transact(REGISTER_CLIENT, data, &reply); 322 } 323 324 virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 325 { 326 Parcel data, reply; 327 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 328 data.writeInt32(sampleRate); 329 data.writeInt32(format); 330 data.writeInt32(channelCount); 331 remote()->transact(GET_INPUTBUFFERSIZE, data, &reply); 332 return reply.readInt32(); 333 } 334 335 virtual void wakeUp() 336 { 337 Parcel data, reply; 338 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 339 remote()->transact(WAKE_UP, data, &reply, IBinder::FLAG_ONEWAY); 340 return; 341 } 342 343 virtual bool isA2dpEnabled() const 344 { 345 Parcel data, reply; 346 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 347 remote()->transact(IS_A2DP_ENABLED, data, &reply); 348 return (bool)reply.readInt32(); 349 } 350}; 351 352IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger"); 353 354// ---------------------------------------------------------------------- 355 356#define CHECK_INTERFACE(interface, data, reply) \ 357 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 358 LOGW("Call incorrectly routed to " #interface); \ 359 return PERMISSION_DENIED; \ 360 } } while (0) 361 362status_t BnAudioFlinger::onTransact( 363 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 364{ 365 switch(code) { 366 case CREATE_TRACK: { 367 CHECK_INTERFACE(IAudioFlinger, data, reply); 368 pid_t pid = data.readInt32(); 369 int streamType = data.readInt32(); 370 uint32_t sampleRate = data.readInt32(); 371 int format = data.readInt32(); 372 int channelCount = data.readInt32(); 373 size_t bufferCount = data.readInt32(); 374 uint32_t flags = data.readInt32(); 375 sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder()); 376 status_t status; 377 sp<IAudioTrack> track = createTrack(pid, 378 streamType, sampleRate, format, 379 channelCount, bufferCount, flags, buffer, &status); 380 reply->writeInt32(status); 381 reply->writeStrongBinder(track->asBinder()); 382 return NO_ERROR; 383 } break; 384 case OPEN_RECORD: { 385 CHECK_INTERFACE(IAudioFlinger, data, reply); 386 pid_t pid = data.readInt32(); 387 int inputSource = data.readInt32(); 388 uint32_t sampleRate = data.readInt32(); 389 int format = data.readInt32(); 390 int channelCount = data.readInt32(); 391 size_t bufferCount = data.readInt32(); 392 uint32_t flags = data.readInt32(); 393 status_t status; 394 sp<IAudioRecord> record = openRecord(pid, inputSource, 395 sampleRate, format, channelCount, bufferCount, flags, &status); 396 reply->writeInt32(status); 397 reply->writeStrongBinder(record->asBinder()); 398 return NO_ERROR; 399 } break; 400 case SAMPLE_RATE: { 401 CHECK_INTERFACE(IAudioFlinger, data, reply); 402 int output = data.readInt32(); 403 reply->writeInt32( sampleRate(output) ); 404 return NO_ERROR; 405 } break; 406 case CHANNEL_COUNT: { 407 CHECK_INTERFACE(IAudioFlinger, data, reply); 408 int output = data.readInt32(); 409 reply->writeInt32( channelCount(output) ); 410 return NO_ERROR; 411 } break; 412 case FORMAT: { 413 CHECK_INTERFACE(IAudioFlinger, data, reply); 414 int output = data.readInt32(); 415 reply->writeInt32( format(output) ); 416 return NO_ERROR; 417 } break; 418 case FRAME_COUNT: { 419 CHECK_INTERFACE(IAudioFlinger, data, reply); 420 int output = data.readInt32(); 421 reply->writeInt32( frameCount(output) ); 422 return NO_ERROR; 423 } break; 424 case LATENCY: { 425 CHECK_INTERFACE(IAudioFlinger, data, reply); 426 int output = data.readInt32(); 427 reply->writeInt32( latency(output) ); 428 return NO_ERROR; 429 } break; 430 case SET_MASTER_VOLUME: { 431 CHECK_INTERFACE(IAudioFlinger, data, reply); 432 reply->writeInt32( setMasterVolume(data.readFloat()) ); 433 return NO_ERROR; 434 } break; 435 case SET_MASTER_MUTE: { 436 CHECK_INTERFACE(IAudioFlinger, data, reply); 437 reply->writeInt32( setMasterMute(data.readInt32()) ); 438 return NO_ERROR; 439 } break; 440 case MASTER_VOLUME: { 441 CHECK_INTERFACE(IAudioFlinger, data, reply); 442 reply->writeFloat( masterVolume() ); 443 return NO_ERROR; 444 } break; 445 case MASTER_MUTE: { 446 CHECK_INTERFACE(IAudioFlinger, data, reply); 447 reply->writeInt32( masterMute() ); 448 return NO_ERROR; 449 } break; 450 case SET_STREAM_VOLUME: { 451 CHECK_INTERFACE(IAudioFlinger, data, reply); 452 int stream = data.readInt32(); 453 reply->writeInt32( setStreamVolume(stream, data.readFloat()) ); 454 return NO_ERROR; 455 } break; 456 case SET_STREAM_MUTE: { 457 CHECK_INTERFACE(IAudioFlinger, data, reply); 458 int stream = data.readInt32(); 459 reply->writeInt32( setStreamMute(stream, data.readInt32()) ); 460 return NO_ERROR; 461 } break; 462 case STREAM_VOLUME: { 463 CHECK_INTERFACE(IAudioFlinger, data, reply); 464 int stream = data.readInt32(); 465 reply->writeFloat( streamVolume(stream) ); 466 return NO_ERROR; 467 } break; 468 case STREAM_MUTE: { 469 CHECK_INTERFACE(IAudioFlinger, data, reply); 470 int stream = data.readInt32(); 471 reply->writeInt32( streamMute(stream) ); 472 return NO_ERROR; 473 } break; 474 case SET_ROUTING: { 475 CHECK_INTERFACE(IAudioFlinger, data, reply); 476 int mode = data.readInt32(); 477 uint32_t routes = data.readInt32(); 478 uint32_t mask = data.readInt32(); 479 reply->writeInt32( setRouting(mode, routes, mask) ); 480 return NO_ERROR; 481 } break; 482 case GET_ROUTING: { 483 CHECK_INTERFACE(IAudioFlinger, data, reply); 484 int mode = data.readInt32(); 485 reply->writeInt32( getRouting(mode) ); 486 return NO_ERROR; 487 } break; 488 case SET_MODE: { 489 CHECK_INTERFACE(IAudioFlinger, data, reply); 490 int mode = data.readInt32(); 491 reply->writeInt32( setMode(mode) ); 492 return NO_ERROR; 493 } break; 494 case GET_MODE: { 495 CHECK_INTERFACE(IAudioFlinger, data, reply); 496 reply->writeInt32( getMode() ); 497 return NO_ERROR; 498 } break; 499 case SET_MIC_MUTE: { 500 CHECK_INTERFACE(IAudioFlinger, data, reply); 501 int state = data.readInt32(); 502 reply->writeInt32( setMicMute(state) ); 503 return NO_ERROR; 504 } break; 505 case GET_MIC_MUTE: { 506 CHECK_INTERFACE(IAudioFlinger, data, reply); 507 reply->writeInt32( getMicMute() ); 508 return NO_ERROR; 509 } break; 510 case IS_MUSIC_ACTIVE: { 511 CHECK_INTERFACE(IAudioFlinger, data, reply); 512 reply->writeInt32( isMusicActive() ); 513 return NO_ERROR; 514 } break; 515 case SET_PARAMETER: { 516 CHECK_INTERFACE(IAudioFlinger, data, reply); 517 const char *key = data.readCString(); 518 const char *value = data.readCString(); 519 reply->writeInt32( setParameter(key, value) ); 520 return NO_ERROR; 521 } break; 522 case REGISTER_CLIENT: { 523 CHECK_INTERFACE(IAudioFlinger, data, reply); 524 sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(data.readStrongBinder()); 525 registerClient(client); 526 return NO_ERROR; 527 } break; 528 case GET_INPUTBUFFERSIZE: { 529 CHECK_INTERFACE(IAudioFlinger, data, reply); 530 uint32_t sampleRate = data.readInt32(); 531 int format = data.readInt32(); 532 int channelCount = data.readInt32(); 533 reply->writeInt32( getInputBufferSize(sampleRate, format, channelCount) ); 534 return NO_ERROR; 535 } break; 536 case WAKE_UP: { 537 CHECK_INTERFACE(IAudioFlinger, data, reply); 538 wakeUp(); 539 return NO_ERROR; 540 } break; 541 case IS_A2DP_ENABLED: { 542 CHECK_INTERFACE(IAudioFlinger, data, reply); 543 reply->writeInt32( (int)isA2dpEnabled() ); 544 return NO_ERROR; 545 } break; 546 default: 547 return BBinder::onTransact(code, data, reply, flags); 548 } 549} 550 551// ---------------------------------------------------------------------------- 552 553}; // namespace android 554