1/* 2 ** 3 ** Copyright 2008, 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_NDEBUG 0 19#define LOG_TAG "IMediaRecorder" 20 21#include <inttypes.h> 22#include <unistd.h> 23 24#include <utils/Log.h> 25#include <binder/Parcel.h> 26#include <camera/android/hardware/ICamera.h> 27#include <camera/ICameraRecordingProxy.h> 28#include <media/IMediaRecorderClient.h> 29#include <media/IMediaRecorder.h> 30#include <gui/Surface.h> 31#include <gui/IGraphicBufferProducer.h> 32#include <media/stagefright/PersistentSurface.h> 33 34namespace android { 35 36enum { 37 RELEASE = IBinder::FIRST_CALL_TRANSACTION, 38 INIT, 39 CLOSE, 40 SET_INPUT_SURFACE, 41 QUERY_SURFACE_MEDIASOURCE, 42 RESET, 43 STOP, 44 START, 45 PREPARE, 46 GET_MAX_AMPLITUDE, 47 SET_VIDEO_SOURCE, 48 SET_AUDIO_SOURCE, 49 SET_OUTPUT_FORMAT, 50 SET_VIDEO_ENCODER, 51 SET_AUDIO_ENCODER, 52 SET_OUTPUT_FILE_FD, 53 SET_NEXT_OUTPUT_FILE_FD, 54 SET_VIDEO_SIZE, 55 SET_VIDEO_FRAMERATE, 56 SET_PARAMETERS, 57 SET_PREVIEW_SURFACE, 58 SET_CAMERA, 59 SET_LISTENER, 60 SET_CLIENT_NAME, 61 PAUSE, 62 RESUME, 63 GET_METRICS, 64 SET_INPUT_DEVICE, 65 GET_ROUTED_DEVICE_ID, 66 ENABLE_AUDIO_DEVICE_CALLBACK, 67 GET_ACTIVE_MICROPHONES, 68 69}; 70 71class BpMediaRecorder: public BpInterface<IMediaRecorder> 72{ 73public: 74 explicit BpMediaRecorder(const sp<IBinder>& impl) 75 : BpInterface<IMediaRecorder>(impl) 76 { 77 } 78 79 status_t setCamera(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy) 80 { 81 ALOGV("setCamera(%p,%p)", camera.get(), proxy.get()); 82 Parcel data, reply; 83 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 84 data.writeStrongBinder(IInterface::asBinder(camera)); 85 data.writeStrongBinder(IInterface::asBinder(proxy)); 86 remote()->transact(SET_CAMERA, data, &reply); 87 return reply.readInt32(); 88 } 89 90 status_t setInputSurface(const sp<PersistentSurface>& surface) 91 { 92 ALOGV("setInputSurface(%p)", surface.get()); 93 Parcel data, reply; 94 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 95 surface->writeToParcel(&data); 96 remote()->transact(SET_INPUT_SURFACE, data, &reply); 97 return reply.readInt32(); 98 } 99 100 sp<IGraphicBufferProducer> querySurfaceMediaSource() 101 { 102 ALOGV("Query SurfaceMediaSource"); 103 Parcel data, reply; 104 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 105 remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply); 106 int returnedNull = reply.readInt32(); 107 if (returnedNull) { 108 return NULL; 109 } 110 return interface_cast<IGraphicBufferProducer>(reply.readStrongBinder()); 111 } 112 113 status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface) 114 { 115 ALOGV("setPreviewSurface(%p)", surface.get()); 116 Parcel data, reply; 117 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 118 data.writeStrongBinder(IInterface::asBinder(surface)); 119 remote()->transact(SET_PREVIEW_SURFACE, data, &reply); 120 return reply.readInt32(); 121 } 122 123 status_t init() 124 { 125 ALOGV("init"); 126 Parcel data, reply; 127 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 128 remote()->transact(INIT, data, &reply); 129 return reply.readInt32(); 130 } 131 132 status_t setVideoSource(int vs) 133 { 134 ALOGV("setVideoSource(%d)", vs); 135 Parcel data, reply; 136 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 137 data.writeInt32(vs); 138 remote()->transact(SET_VIDEO_SOURCE, data, &reply); 139 return reply.readInt32(); 140 } 141 142 status_t setAudioSource(int as) 143 { 144 ALOGV("setAudioSource(%d)", as); 145 Parcel data, reply; 146 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 147 data.writeInt32(as); 148 remote()->transact(SET_AUDIO_SOURCE, data, &reply); 149 return reply.readInt32(); 150 } 151 152 status_t setOutputFormat(int of) 153 { 154 ALOGV("setOutputFormat(%d)", of); 155 Parcel data, reply; 156 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 157 data.writeInt32(of); 158 remote()->transact(SET_OUTPUT_FORMAT, data, &reply); 159 return reply.readInt32(); 160 } 161 162 status_t setVideoEncoder(int ve) 163 { 164 ALOGV("setVideoEncoder(%d)", ve); 165 Parcel data, reply; 166 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 167 data.writeInt32(ve); 168 remote()->transact(SET_VIDEO_ENCODER, data, &reply); 169 return reply.readInt32(); 170 } 171 172 status_t setAudioEncoder(int ae) 173 { 174 ALOGV("setAudioEncoder(%d)", ae); 175 Parcel data, reply; 176 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 177 data.writeInt32(ae); 178 remote()->transact(SET_AUDIO_ENCODER, data, &reply); 179 return reply.readInt32(); 180 } 181 182 status_t setOutputFile(int fd) { 183 ALOGV("setOutputFile(%d)", fd); 184 Parcel data, reply; 185 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 186 data.writeFileDescriptor(fd); 187 remote()->transact(SET_OUTPUT_FILE_FD, data, &reply); 188 return reply.readInt32(); 189 } 190 191 status_t setNextOutputFile(int fd) { 192 ALOGV("setNextOutputFile(%d)", fd); 193 Parcel data, reply; 194 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 195 data.writeFileDescriptor(fd); 196 remote()->transact(SET_NEXT_OUTPUT_FILE_FD, data, &reply); 197 return reply.readInt32(); 198 } 199 200 status_t setVideoSize(int width, int height) 201 { 202 ALOGV("setVideoSize(%dx%d)", width, height); 203 Parcel data, reply; 204 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 205 data.writeInt32(width); 206 data.writeInt32(height); 207 remote()->transact(SET_VIDEO_SIZE, data, &reply); 208 return reply.readInt32(); 209 } 210 211 status_t setVideoFrameRate(int frames_per_second) 212 { 213 ALOGV("setVideoFrameRate(%d)", frames_per_second); 214 Parcel data, reply; 215 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 216 data.writeInt32(frames_per_second); 217 remote()->transact(SET_VIDEO_FRAMERATE, data, &reply); 218 return reply.readInt32(); 219 } 220 221 status_t setParameters(const String8& params) 222 { 223 ALOGV("setParameter(%s)", params.string()); 224 Parcel data, reply; 225 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 226 data.writeString8(params); 227 remote()->transact(SET_PARAMETERS, data, &reply); 228 return reply.readInt32(); 229 } 230 231 status_t setListener(const sp<IMediaRecorderClient>& listener) 232 { 233 ALOGV("setListener(%p)", listener.get()); 234 Parcel data, reply; 235 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 236 data.writeStrongBinder(IInterface::asBinder(listener)); 237 remote()->transact(SET_LISTENER, data, &reply); 238 return reply.readInt32(); 239 } 240 241 status_t setClientName(const String16& clientName) 242 { 243 ALOGV("setClientName(%s)", String8(clientName).string()); 244 Parcel data, reply; 245 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 246 data.writeString16(clientName); 247 remote()->transact(SET_CLIENT_NAME, data, &reply); 248 return reply.readInt32(); 249 } 250 251 status_t prepare() 252 { 253 ALOGV("prepare"); 254 Parcel data, reply; 255 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 256 remote()->transact(PREPARE, data, &reply); 257 return reply.readInt32(); 258 } 259 260 status_t getMaxAmplitude(int* max) 261 { 262 ALOGV("getMaxAmplitude"); 263 Parcel data, reply; 264 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 265 remote()->transact(GET_MAX_AMPLITUDE, data, &reply); 266 *max = reply.readInt32(); 267 return reply.readInt32(); 268 } 269 270 status_t getMetrics(Parcel* reply) 271 { 272 ALOGV("getMetrics"); 273 Parcel data; 274 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 275 status_t ret = remote()->transact(GET_METRICS, data, reply); 276 if (ret == NO_ERROR) { 277 return OK; 278 } 279 return UNKNOWN_ERROR; 280 } 281 282 status_t start() 283 { 284 ALOGV("start"); 285 Parcel data, reply; 286 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 287 remote()->transact(START, data, &reply); 288 return reply.readInt32(); 289 } 290 291 status_t stop() 292 { 293 ALOGV("stop"); 294 Parcel data, reply; 295 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 296 remote()->transact(STOP, data, &reply); 297 return reply.readInt32(); 298 } 299 300 status_t reset() 301 { 302 ALOGV("reset"); 303 Parcel data, reply; 304 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 305 remote()->transact(RESET, data, &reply); 306 return reply.readInt32(); 307 } 308 309 status_t pause() 310 { 311 ALOGV("pause"); 312 Parcel data, reply; 313 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 314 remote()->transact(PAUSE, data, &reply); 315 return reply.readInt32(); 316 } 317 318 status_t resume() 319 { 320 ALOGV("resume"); 321 Parcel data, reply; 322 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 323 remote()->transact(RESUME, data, &reply); 324 return reply.readInt32(); 325 } 326 327 status_t close() 328 { 329 ALOGV("close"); 330 Parcel data, reply; 331 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 332 remote()->transact(CLOSE, data, &reply); 333 return reply.readInt32(); 334 } 335 336 status_t release() 337 { 338 ALOGV("release"); 339 Parcel data, reply; 340 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 341 remote()->transact(RELEASE, data, &reply); 342 return reply.readInt32(); 343 } 344 345 status_t setInputDevice(audio_port_handle_t deviceId) 346 { 347 ALOGV("setInputDevice"); 348 Parcel data, reply; 349 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 350 data.writeInt32(deviceId); 351 352 status_t status = remote()->transact(SET_INPUT_DEVICE, data, &reply); 353 if (status != OK) { 354 ALOGE("setInputDevice binder call failed: %d", status); 355 return status; 356 } 357 return reply.readInt32();; 358 } 359 360 audio_port_handle_t getRoutedDeviceId(audio_port_handle_t *deviceId) 361 { 362 ALOGV("getRoutedDeviceId"); 363 Parcel data, reply; 364 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 365 366 status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply); 367 if (status != OK) { 368 ALOGE("getRoutedDeviceid binder call failed: %d", status); 369 *deviceId = AUDIO_PORT_HANDLE_NONE; 370 return status; 371 } 372 373 status = reply.readInt32(); 374 if (status != NO_ERROR) { 375 *deviceId = AUDIO_PORT_HANDLE_NONE; 376 } else { 377 *deviceId = reply.readInt32(); 378 } 379 return status; 380 } 381 382 status_t enableAudioDeviceCallback(bool enabled) 383 { 384 ALOGV("enableAudioDeviceCallback"); 385 Parcel data, reply; 386 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 387 data.writeBool(enabled); 388 status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply); 389 if (status != OK) { 390 ALOGE("enableAudioDeviceCallback binder call failed: %d, %d", enabled, status); 391 return status; 392 } 393 return reply.readInt32(); 394 } 395 396 status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones) 397 { 398 ALOGV("getActiveMicrophones"); 399 Parcel data, reply; 400 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 401 status_t status = remote()->transact(GET_ACTIVE_MICROPHONES, data, &reply); 402 if (status != OK 403 || (status = (status_t)reply.readInt32()) != NO_ERROR) { 404 return status; 405 } 406 status = reply.readParcelableVector(activeMicrophones); 407 return status; 408 } 409 410}; 411 412IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder"); 413 414// ---------------------------------------------------------------------- 415 416status_t BnMediaRecorder::onTransact( 417 uint32_t code, const Parcel& data, Parcel* reply, 418 uint32_t flags) 419{ 420 switch (code) { 421 case RELEASE: { 422 ALOGV("RELEASE"); 423 CHECK_INTERFACE(IMediaRecorder, data, reply); 424 reply->writeInt32(release()); 425 return NO_ERROR; 426 } break; 427 case INIT: { 428 ALOGV("INIT"); 429 CHECK_INTERFACE(IMediaRecorder, data, reply); 430 reply->writeInt32(init()); 431 return NO_ERROR; 432 } break; 433 case CLOSE: { 434 ALOGV("CLOSE"); 435 CHECK_INTERFACE(IMediaRecorder, data, reply); 436 reply->writeInt32(close()); 437 return NO_ERROR; 438 } break; 439 case RESET: { 440 ALOGV("RESET"); 441 CHECK_INTERFACE(IMediaRecorder, data, reply); 442 reply->writeInt32(reset()); 443 return NO_ERROR; 444 } break; 445 case STOP: { 446 ALOGV("STOP"); 447 CHECK_INTERFACE(IMediaRecorder, data, reply); 448 reply->writeInt32(stop()); 449 return NO_ERROR; 450 } break; 451 case START: { 452 ALOGV("START"); 453 CHECK_INTERFACE(IMediaRecorder, data, reply); 454 reply->writeInt32(start()); 455 return NO_ERROR; 456 } break; 457 case PAUSE: { 458 ALOGV("PAUSE"); 459 CHECK_INTERFACE(IMediaRecorder, data, reply); 460 reply->writeInt32(pause()); 461 return NO_ERROR; 462 } break; 463 case RESUME: { 464 ALOGV("RESUME"); 465 CHECK_INTERFACE(IMediaRecorder, data, reply); 466 reply->writeInt32(resume()); 467 return NO_ERROR; 468 } break; 469 case PREPARE: { 470 ALOGV("PREPARE"); 471 CHECK_INTERFACE(IMediaRecorder, data, reply); 472 reply->writeInt32(prepare()); 473 return NO_ERROR; 474 } break; 475 case GET_MAX_AMPLITUDE: { 476 ALOGV("GET_MAX_AMPLITUDE"); 477 CHECK_INTERFACE(IMediaRecorder, data, reply); 478 int max = 0; 479 status_t ret = getMaxAmplitude(&max); 480 reply->writeInt32(max); 481 reply->writeInt32(ret); 482 return NO_ERROR; 483 } break; 484 case GET_METRICS: { 485 ALOGV("GET_METRICS"); 486 status_t ret = getMetrics(reply); 487 return ret; 488 } break; 489 case SET_VIDEO_SOURCE: { 490 ALOGV("SET_VIDEO_SOURCE"); 491 CHECK_INTERFACE(IMediaRecorder, data, reply); 492 int vs = data.readInt32(); 493 reply->writeInt32(setVideoSource(vs)); 494 return NO_ERROR; 495 } break; 496 case SET_AUDIO_SOURCE: { 497 ALOGV("SET_AUDIO_SOURCE"); 498 CHECK_INTERFACE(IMediaRecorder, data, reply); 499 int as = data.readInt32(); 500 reply->writeInt32(setAudioSource(as)); 501 return NO_ERROR; 502 } break; 503 case SET_OUTPUT_FORMAT: { 504 ALOGV("SET_OUTPUT_FORMAT"); 505 CHECK_INTERFACE(IMediaRecorder, data, reply); 506 int of = data.readInt32(); 507 reply->writeInt32(setOutputFormat(of)); 508 return NO_ERROR; 509 } break; 510 case SET_VIDEO_ENCODER: { 511 ALOGV("SET_VIDEO_ENCODER"); 512 CHECK_INTERFACE(IMediaRecorder, data, reply); 513 int ve = data.readInt32(); 514 reply->writeInt32(setVideoEncoder(ve)); 515 return NO_ERROR; 516 } break; 517 case SET_AUDIO_ENCODER: { 518 ALOGV("SET_AUDIO_ENCODER"); 519 CHECK_INTERFACE(IMediaRecorder, data, reply); 520 int ae = data.readInt32(); 521 reply->writeInt32(setAudioEncoder(ae)); 522 return NO_ERROR; 523 524 } break; 525 case SET_OUTPUT_FILE_FD: { 526 ALOGV("SET_OUTPUT_FILE_FD"); 527 CHECK_INTERFACE(IMediaRecorder, data, reply); 528 int fd = dup(data.readFileDescriptor()); 529 reply->writeInt32(setOutputFile(fd)); 530 ::close(fd); 531 return NO_ERROR; 532 } break; 533 case SET_NEXT_OUTPUT_FILE_FD: { 534 ALOGV("SET_NEXT_OUTPUT_FILE_FD"); 535 CHECK_INTERFACE(IMediaRecorder, data, reply); 536 int fd = dup(data.readFileDescriptor()); 537 reply->writeInt32(setNextOutputFile(fd)); 538 ::close(fd); 539 return NO_ERROR; 540 } break; 541 case SET_VIDEO_SIZE: { 542 ALOGV("SET_VIDEO_SIZE"); 543 CHECK_INTERFACE(IMediaRecorder, data, reply); 544 int width = data.readInt32(); 545 int height = data.readInt32(); 546 reply->writeInt32(setVideoSize(width, height)); 547 return NO_ERROR; 548 } break; 549 case SET_VIDEO_FRAMERATE: { 550 ALOGV("SET_VIDEO_FRAMERATE"); 551 CHECK_INTERFACE(IMediaRecorder, data, reply); 552 int frames_per_second = data.readInt32(); 553 reply->writeInt32(setVideoFrameRate(frames_per_second)); 554 return NO_ERROR; 555 } break; 556 case SET_PARAMETERS: { 557 ALOGV("SET_PARAMETER"); 558 CHECK_INTERFACE(IMediaRecorder, data, reply); 559 reply->writeInt32(setParameters(data.readString8())); 560 return NO_ERROR; 561 } break; 562 case SET_LISTENER: { 563 ALOGV("SET_LISTENER"); 564 CHECK_INTERFACE(IMediaRecorder, data, reply); 565 sp<IMediaRecorderClient> listener = 566 interface_cast<IMediaRecorderClient>(data.readStrongBinder()); 567 reply->writeInt32(setListener(listener)); 568 return NO_ERROR; 569 } break; 570 case SET_CLIENT_NAME: { 571 ALOGV("SET_CLIENT_NAME"); 572 CHECK_INTERFACE(IMediaRecorder, data, reply); 573 reply->writeInt32(setClientName(data.readString16())); 574 return NO_ERROR; 575 } 576 case SET_PREVIEW_SURFACE: { 577 ALOGV("SET_PREVIEW_SURFACE"); 578 CHECK_INTERFACE(IMediaRecorder, data, reply); 579 sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>( 580 data.readStrongBinder()); 581 reply->writeInt32(setPreviewSurface(surface)); 582 return NO_ERROR; 583 } break; 584 case SET_CAMERA: { 585 ALOGV("SET_CAMERA"); 586 CHECK_INTERFACE(IMediaRecorder, data, reply); 587 sp<hardware::ICamera> camera = 588 interface_cast<hardware::ICamera>(data.readStrongBinder()); 589 sp<ICameraRecordingProxy> proxy = 590 interface_cast<ICameraRecordingProxy>(data.readStrongBinder()); 591 reply->writeInt32(setCamera(camera, proxy)); 592 return NO_ERROR; 593 } break; 594 case SET_INPUT_SURFACE: { 595 ALOGV("SET_INPUT_SURFACE"); 596 CHECK_INTERFACE(IMediaRecorder, data, reply); 597 sp<PersistentSurface> surface = new PersistentSurface(); 598 surface->readFromParcel(&data); 599 reply->writeInt32(setInputSurface(surface)); 600 return NO_ERROR; 601 } break; 602 case QUERY_SURFACE_MEDIASOURCE: { 603 ALOGV("QUERY_SURFACE_MEDIASOURCE"); 604 CHECK_INTERFACE(IMediaRecorder, data, reply); 605 // call the mediaserver side to create 606 // a surfacemediasource 607 sp<IGraphicBufferProducer> surfaceMediaSource = querySurfaceMediaSource(); 608 // The mediaserver might have failed to create a source 609 int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ; 610 reply->writeInt32(returnedNull); 611 if (!returnedNull) { 612 reply->writeStrongBinder(IInterface::asBinder(surfaceMediaSource)); 613 } 614 return NO_ERROR; 615 } break; 616 case SET_INPUT_DEVICE: { 617 ALOGV("SET_INPUT_DEVICE"); 618 CHECK_INTERFACE(IMediaRecorder, data, reply); 619 audio_port_handle_t deviceId; 620 status_t status = data.readInt32(&deviceId); 621 if (status == NO_ERROR) { 622 reply->writeInt32(setInputDevice(deviceId)); 623 } else { 624 reply->writeInt32(BAD_VALUE); 625 } 626 return NO_ERROR; 627 } break; 628 case GET_ROUTED_DEVICE_ID: { 629 ALOGV("GET_ROUTED_DEVICE_ID"); 630 CHECK_INTERFACE(IMediaRecorder, data, reply); 631 audio_port_handle_t deviceId; 632 status_t status = getRoutedDeviceId(&deviceId); 633 reply->writeInt32(status); 634 if (status == NO_ERROR) { 635 reply->writeInt32(deviceId); 636 } 637 return NO_ERROR; 638 } break; 639 case ENABLE_AUDIO_DEVICE_CALLBACK: { 640 ALOGV("ENABLE_AUDIO_DEVICE_CALLBACK"); 641 CHECK_INTERFACE(IMediaRecorder, data, reply); 642 bool enabled; 643 status_t status = data.readBool(&enabled); 644 if (status == NO_ERROR) { 645 reply->writeInt32(enableAudioDeviceCallback(enabled)); 646 } else { 647 reply->writeInt32(BAD_VALUE); 648 } 649 return NO_ERROR; 650 } break; 651 case GET_ACTIVE_MICROPHONES: { 652 ALOGV("GET_ACTIVE_MICROPHONES"); 653 CHECK_INTERFACE(IMediaRecorder, data, reply); 654 std::vector<media::MicrophoneInfo> activeMicrophones; 655 status_t status = getActiveMicrophones(&activeMicrophones); 656 reply->writeInt32(status); 657 if (status != NO_ERROR) { 658 return NO_ERROR; 659 } 660 reply->writeParcelableVector(activeMicrophones); 661 return NO_ERROR; 662 663 } 664 default: 665 return BBinder::onTransact(code, data, reply, flags); 666 } 667} 668 669// ---------------------------------------------------------------------------- 670 671} // namespace android 672