1 /* 2 ** 3 ** Copyright (c) 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 "MediaRecorder" 20 21 #include <inttypes.h> 22 23 #include <utils/Log.h> 24 #include <media/mediarecorder.h> 25 #include <binder/IServiceManager.h> 26 #include <utils/String8.h> 27 #include <media/IMediaPlayerService.h> 28 #include <media/IMediaRecorder.h> 29 #include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED 30 #include <media/stagefright/PersistentSurface.h> 31 #include <gui/IGraphicBufferProducer.h> 32 33 namespace android { 34 35 status_t MediaRecorder::setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy) 36 { 37 ALOGV("setCamera(%p,%p)", camera.get(), proxy.get()); 38 if (mMediaRecorder == NULL) { 39 ALOGE("media recorder is not initialized yet"); 40 return INVALID_OPERATION; 41 } 42 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) { 43 ALOGE("setCamera called in an invalid state(%d)", mCurrentState); 44 return INVALID_OPERATION; 45 } 46 47 status_t ret = mMediaRecorder->setCamera(camera, proxy); 48 if (OK != ret) { 49 ALOGV("setCamera failed: %d", ret); 50 mCurrentState = MEDIA_RECORDER_ERROR; 51 return ret; 52 } 53 return ret; 54 } 55 56 status_t MediaRecorder::setPreviewSurface(const sp<IGraphicBufferProducer>& surface) 57 { 58 ALOGV("setPreviewSurface(%p)", surface.get()); 59 if (mMediaRecorder == NULL) { 60 ALOGE("media recorder is not initialized yet"); 61 return INVALID_OPERATION; 62 } 63 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 64 ALOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState); 65 return INVALID_OPERATION; 66 } 67 if (!mIsVideoSourceSet) { 68 ALOGE("try to set preview surface without setting the video source first"); 69 return INVALID_OPERATION; 70 } 71 72 status_t ret = mMediaRecorder->setPreviewSurface(surface); 73 if (OK != ret) { 74 ALOGV("setPreviewSurface failed: %d", ret); 75 mCurrentState = MEDIA_RECORDER_ERROR; 76 return ret; 77 } 78 return ret; 79 } 80 81 status_t MediaRecorder::init() 82 { 83 ALOGV("init"); 84 if (mMediaRecorder == NULL) { 85 ALOGE("media recorder is not initialized yet"); 86 return INVALID_OPERATION; 87 } 88 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) { 89 ALOGE("init called in an invalid state(%d)", mCurrentState); 90 return INVALID_OPERATION; 91 } 92 93 status_t ret = mMediaRecorder->init(); 94 if (OK != ret) { 95 ALOGV("init failed: %d", ret); 96 mCurrentState = MEDIA_RECORDER_ERROR; 97 return ret; 98 } 99 100 ret = mMediaRecorder->setListener(this); 101 if (OK != ret) { 102 ALOGV("setListener failed: %d", ret); 103 mCurrentState = MEDIA_RECORDER_ERROR; 104 return ret; 105 } 106 107 mCurrentState = MEDIA_RECORDER_INITIALIZED; 108 return ret; 109 } 110 111 status_t MediaRecorder::setVideoSource(int vs) 112 { 113 ALOGV("setVideoSource(%d)", vs); 114 if (mMediaRecorder == NULL) { 115 ALOGE("media recorder is not initialized yet"); 116 return INVALID_OPERATION; 117 } 118 if (mIsVideoSourceSet) { 119 ALOGE("video source has already been set"); 120 return INVALID_OPERATION; 121 } 122 if (mCurrentState & MEDIA_RECORDER_IDLE) { 123 ALOGV("Call init() since the media recorder is not initialized yet"); 124 status_t ret = init(); 125 if (OK != ret) { 126 return ret; 127 } 128 } 129 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { 130 ALOGE("setVideoSource called in an invalid state(%d)", mCurrentState); 131 return INVALID_OPERATION; 132 } 133 134 // following call is made over the Binder Interface 135 status_t ret = mMediaRecorder->setVideoSource(vs); 136 137 if (OK != ret) { 138 ALOGV("setVideoSource failed: %d", ret); 139 mCurrentState = MEDIA_RECORDER_ERROR; 140 return ret; 141 } 142 mIsVideoSourceSet = true; 143 return ret; 144 } 145 146 status_t MediaRecorder::setAudioSource(int as) 147 { 148 ALOGV("setAudioSource(%d)", as); 149 if (mMediaRecorder == NULL) { 150 ALOGE("media recorder is not initialized yet"); 151 return INVALID_OPERATION; 152 } 153 if (mCurrentState & MEDIA_RECORDER_IDLE) { 154 ALOGV("Call init() since the media recorder is not initialized yet"); 155 status_t ret = init(); 156 if (OK != ret) { 157 return ret; 158 } 159 } 160 if (mIsAudioSourceSet) { 161 ALOGE("audio source has already been set"); 162 return INVALID_OPERATION; 163 } 164 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { 165 ALOGE("setAudioSource called in an invalid state(%d)", mCurrentState); 166 return INVALID_OPERATION; 167 } 168 169 status_t ret = mMediaRecorder->setAudioSource(as); 170 if (OK != ret) { 171 ALOGV("setAudioSource failed: %d", ret); 172 mCurrentState = MEDIA_RECORDER_ERROR; 173 return ret; 174 } 175 mIsAudioSourceSet = true; 176 return ret; 177 } 178 179 status_t MediaRecorder::setOutputFormat(int of) 180 { 181 ALOGV("setOutputFormat(%d)", of); 182 if (mMediaRecorder == NULL) { 183 ALOGE("media recorder is not initialized yet"); 184 return INVALID_OPERATION; 185 } 186 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { 187 ALOGE("setOutputFormat called in an invalid state: %d", mCurrentState); 188 return INVALID_OPERATION; 189 } 190 if (mIsVideoSourceSet 191 && of >= OUTPUT_FORMAT_AUDIO_ONLY_START //first non-video output format 192 && of < OUTPUT_FORMAT_AUDIO_ONLY_END) { 193 ALOGE("output format (%d) is meant for audio recording only" 194 " and incompatible with video recording", of); 195 return INVALID_OPERATION; 196 } 197 198 status_t ret = mMediaRecorder->setOutputFormat(of); 199 if (OK != ret) { 200 ALOGE("setOutputFormat failed: %d", ret); 201 mCurrentState = MEDIA_RECORDER_ERROR; 202 return ret; 203 } 204 mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED; 205 return ret; 206 } 207 208 status_t MediaRecorder::setVideoEncoder(int ve) 209 { 210 ALOGV("setVideoEncoder(%d)", ve); 211 if (mMediaRecorder == NULL) { 212 ALOGE("media recorder is not initialized yet"); 213 return INVALID_OPERATION; 214 } 215 if (!mIsVideoSourceSet) { 216 ALOGE("try to set the video encoder without setting the video source first"); 217 return INVALID_OPERATION; 218 } 219 if (mIsVideoEncoderSet) { 220 ALOGE("video encoder has already been set"); 221 return INVALID_OPERATION; 222 } 223 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 224 ALOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState); 225 return INVALID_OPERATION; 226 } 227 228 status_t ret = mMediaRecorder->setVideoEncoder(ve); 229 if (OK != ret) { 230 ALOGV("setVideoEncoder failed: %d", ret); 231 mCurrentState = MEDIA_RECORDER_ERROR; 232 return ret; 233 } 234 mIsVideoEncoderSet = true; 235 return ret; 236 } 237 238 status_t MediaRecorder::setAudioEncoder(int ae) 239 { 240 ALOGV("setAudioEncoder(%d)", ae); 241 if (mMediaRecorder == NULL) { 242 ALOGE("media recorder is not initialized yet"); 243 return INVALID_OPERATION; 244 } 245 if (!mIsAudioSourceSet) { 246 ALOGE("try to set the audio encoder without setting the audio source first"); 247 return INVALID_OPERATION; 248 } 249 if (mIsAudioEncoderSet) { 250 ALOGE("audio encoder has already been set"); 251 return INVALID_OPERATION; 252 } 253 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 254 ALOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState); 255 return INVALID_OPERATION; 256 } 257 258 status_t ret = mMediaRecorder->setAudioEncoder(ae); 259 if (OK != ret) { 260 ALOGV("setAudioEncoder failed: %d", ret); 261 mCurrentState = MEDIA_RECORDER_ERROR; 262 return ret; 263 } 264 mIsAudioEncoderSet = true; 265 return ret; 266 } 267 268 status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length) 269 { 270 ALOGV("setOutputFile(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length); 271 if (mMediaRecorder == NULL) { 272 ALOGE("media recorder is not initialized yet"); 273 return INVALID_OPERATION; 274 } 275 if (mIsOutputFileSet) { 276 ALOGE("output file has already been set"); 277 return INVALID_OPERATION; 278 } 279 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 280 ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState); 281 return INVALID_OPERATION; 282 } 283 284 // It appears that if an invalid file descriptor is passed through 285 // binder calls, the server-side of the inter-process function call 286 // is skipped. As a result, the check at the server-side to catch 287 // the invalid file descritpor never gets invoked. This is to workaround 288 // this issue by checking the file descriptor first before passing 289 // it through binder call. 290 if (fd < 0) { 291 ALOGE("Invalid file descriptor: %d", fd); 292 return BAD_VALUE; 293 } 294 295 status_t ret = mMediaRecorder->setOutputFile(fd, offset, length); 296 if (OK != ret) { 297 ALOGV("setOutputFile failed: %d", ret); 298 mCurrentState = MEDIA_RECORDER_ERROR; 299 return ret; 300 } 301 mIsOutputFileSet = true; 302 return ret; 303 } 304 305 status_t MediaRecorder::setVideoSize(int width, int height) 306 { 307 ALOGV("setVideoSize(%d, %d)", width, height); 308 if (mMediaRecorder == NULL) { 309 ALOGE("media recorder is not initialized yet"); 310 return INVALID_OPERATION; 311 } 312 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 313 ALOGE("setVideoSize called in an invalid state: %d", mCurrentState); 314 return INVALID_OPERATION; 315 } 316 if (!mIsVideoSourceSet) { 317 ALOGE("Cannot set video size without setting video source first"); 318 return INVALID_OPERATION; 319 } 320 321 status_t ret = mMediaRecorder->setVideoSize(width, height); 322 if (OK != ret) { 323 ALOGE("setVideoSize failed: %d", ret); 324 mCurrentState = MEDIA_RECORDER_ERROR; 325 return ret; 326 } 327 328 return ret; 329 } 330 331 // Query a SurfaceMediaSurface through the Mediaserver, over the 332 // binder interface. This is used by the Filter Framework (MediaEncoder) 333 // to get an <IGraphicBufferProducer> object to hook up to ANativeWindow. 334 sp<IGraphicBufferProducer> MediaRecorder:: 335 querySurfaceMediaSourceFromMediaServer() 336 { 337 Mutex::Autolock _l(mLock); 338 mSurfaceMediaSource = 339 mMediaRecorder->querySurfaceMediaSource(); 340 if (mSurfaceMediaSource == NULL) { 341 ALOGE("SurfaceMediaSource could not be initialized!"); 342 } 343 return mSurfaceMediaSource; 344 } 345 346 347 348 status_t MediaRecorder::setInputSurface(const sp<PersistentSurface>& surface) 349 { 350 ALOGV("setInputSurface"); 351 if (mMediaRecorder == NULL) { 352 ALOGE("media recorder is not initialized yet"); 353 return INVALID_OPERATION; 354 } 355 bool isInvalidState = (mCurrentState & 356 (MEDIA_RECORDER_PREPARED | 357 MEDIA_RECORDER_RECORDING)); 358 if (isInvalidState) { 359 ALOGE("setInputSurface is called in an invalid state: %d", mCurrentState); 360 return INVALID_OPERATION; 361 } 362 363 return mMediaRecorder->setInputSurface(surface->getBufferConsumer()); 364 } 365 366 status_t MediaRecorder::setVideoFrameRate(int frames_per_second) 367 { 368 ALOGV("setVideoFrameRate(%d)", frames_per_second); 369 if (mMediaRecorder == NULL) { 370 ALOGE("media recorder is not initialized yet"); 371 return INVALID_OPERATION; 372 } 373 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 374 ALOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState); 375 return INVALID_OPERATION; 376 } 377 if (!mIsVideoSourceSet) { 378 ALOGE("Cannot set video frame rate without setting video source first"); 379 return INVALID_OPERATION; 380 } 381 382 status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second); 383 if (OK != ret) { 384 ALOGE("setVideoFrameRate failed: %d", ret); 385 mCurrentState = MEDIA_RECORDER_ERROR; 386 return ret; 387 } 388 return ret; 389 } 390 391 status_t MediaRecorder::setParameters(const String8& params) { 392 ALOGV("setParameters(%s)", params.string()); 393 if (mMediaRecorder == NULL) { 394 ALOGE("media recorder is not initialized yet"); 395 return INVALID_OPERATION; 396 } 397 398 bool isInvalidState = (mCurrentState & 399 (MEDIA_RECORDER_PREPARED | 400 MEDIA_RECORDER_RECORDING | 401 MEDIA_RECORDER_ERROR)); 402 if (isInvalidState) { 403 ALOGE("setParameters is called in an invalid state: %d", mCurrentState); 404 return INVALID_OPERATION; 405 } 406 407 status_t ret = mMediaRecorder->setParameters(params); 408 if (OK != ret) { 409 ALOGE("setParameters(%s) failed: %d", params.string(), ret); 410 // Do not change our current state to MEDIA_RECORDER_ERROR, failures 411 // of the only currently supported parameters, "max-duration" and 412 // "max-filesize" are _not_ fatal. 413 } 414 415 return ret; 416 } 417 418 status_t MediaRecorder::prepare() 419 { 420 ALOGV("prepare"); 421 if (mMediaRecorder == NULL) { 422 ALOGE("media recorder is not initialized yet"); 423 return INVALID_OPERATION; 424 } 425 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 426 ALOGE("prepare called in an invalid state: %d", mCurrentState); 427 return INVALID_OPERATION; 428 } 429 if (mIsAudioSourceSet != mIsAudioEncoderSet) { 430 if (mIsAudioSourceSet) { 431 ALOGE("audio source is set, but audio encoder is not set"); 432 } else { // must not happen, since setAudioEncoder checks this already 433 ALOGE("audio encoder is set, but audio source is not set"); 434 } 435 return INVALID_OPERATION; 436 } 437 438 if (mIsVideoSourceSet != mIsVideoEncoderSet) { 439 if (mIsVideoSourceSet) { 440 ALOGE("video source is set, but video encoder is not set"); 441 } else { // must not happen, since setVideoEncoder checks this already 442 ALOGE("video encoder is set, but video source is not set"); 443 } 444 return INVALID_OPERATION; 445 } 446 447 status_t ret = mMediaRecorder->prepare(); 448 if (OK != ret) { 449 ALOGE("prepare failed: %d", ret); 450 mCurrentState = MEDIA_RECORDER_ERROR; 451 return ret; 452 } 453 mCurrentState = MEDIA_RECORDER_PREPARED; 454 return ret; 455 } 456 457 status_t MediaRecorder::getMaxAmplitude(int* max) 458 { 459 ALOGV("getMaxAmplitude"); 460 if (mMediaRecorder == NULL) { 461 ALOGE("media recorder is not initialized yet"); 462 return INVALID_OPERATION; 463 } 464 if (mCurrentState & MEDIA_RECORDER_ERROR) { 465 ALOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState); 466 return INVALID_OPERATION; 467 } 468 469 status_t ret = mMediaRecorder->getMaxAmplitude(max); 470 if (OK != ret) { 471 ALOGE("getMaxAmplitude failed: %d", ret); 472 mCurrentState = MEDIA_RECORDER_ERROR; 473 return ret; 474 } 475 return ret; 476 } 477 478 status_t MediaRecorder::start() 479 { 480 ALOGV("start"); 481 if (mMediaRecorder == NULL) { 482 ALOGE("media recorder is not initialized yet"); 483 return INVALID_OPERATION; 484 } 485 if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) { 486 ALOGE("start called in an invalid state: %d", mCurrentState); 487 return INVALID_OPERATION; 488 } 489 490 status_t ret = mMediaRecorder->start(); 491 if (OK != ret) { 492 ALOGE("start failed: %d", ret); 493 mCurrentState = MEDIA_RECORDER_ERROR; 494 return ret; 495 } 496 mCurrentState = MEDIA_RECORDER_RECORDING; 497 return ret; 498 } 499 500 status_t MediaRecorder::stop() 501 { 502 ALOGV("stop"); 503 if (mMediaRecorder == NULL) { 504 ALOGE("media recorder is not initialized yet"); 505 return INVALID_OPERATION; 506 } 507 if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) { 508 ALOGE("stop called in an invalid state: %d", mCurrentState); 509 return INVALID_OPERATION; 510 } 511 512 status_t ret = mMediaRecorder->stop(); 513 if (OK != ret) { 514 ALOGE("stop failed: %d", ret); 515 mCurrentState = MEDIA_RECORDER_ERROR; 516 return ret; 517 } 518 519 // FIXME: 520 // stop and reset are semantically different. 521 // We treat them the same for now, and will change this in the future. 522 doCleanUp(); 523 mCurrentState = MEDIA_RECORDER_IDLE; 524 return ret; 525 } 526 527 // Reset should be OK in any state 528 status_t MediaRecorder::reset() 529 { 530 ALOGV("reset"); 531 if (mMediaRecorder == NULL) { 532 ALOGE("media recorder is not initialized yet"); 533 return INVALID_OPERATION; 534 } 535 536 doCleanUp(); 537 status_t ret = UNKNOWN_ERROR; 538 switch (mCurrentState) { 539 case MEDIA_RECORDER_IDLE: 540 ret = OK; 541 break; 542 543 case MEDIA_RECORDER_RECORDING: 544 case MEDIA_RECORDER_DATASOURCE_CONFIGURED: 545 case MEDIA_RECORDER_PREPARED: 546 case MEDIA_RECORDER_ERROR: { 547 ret = doReset(); 548 if (OK != ret) { 549 return ret; // No need to continue 550 } 551 } // Intentional fall through 552 case MEDIA_RECORDER_INITIALIZED: 553 ret = close(); 554 break; 555 556 default: { 557 ALOGE("Unexpected non-existing state: %d", mCurrentState); 558 break; 559 } 560 } 561 return ret; 562 } 563 564 status_t MediaRecorder::close() 565 { 566 ALOGV("close"); 567 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { 568 ALOGE("close called in an invalid state: %d", mCurrentState); 569 return INVALID_OPERATION; 570 } 571 status_t ret = mMediaRecorder->close(); 572 if (OK != ret) { 573 ALOGE("close failed: %d", ret); 574 mCurrentState = MEDIA_RECORDER_ERROR; 575 return UNKNOWN_ERROR; 576 } else { 577 mCurrentState = MEDIA_RECORDER_IDLE; 578 } 579 return ret; 580 } 581 582 status_t MediaRecorder::doReset() 583 { 584 ALOGV("doReset"); 585 status_t ret = mMediaRecorder->reset(); 586 if (OK != ret) { 587 ALOGE("doReset failed: %d", ret); 588 mCurrentState = MEDIA_RECORDER_ERROR; 589 return ret; 590 } else { 591 mCurrentState = MEDIA_RECORDER_INITIALIZED; 592 } 593 return ret; 594 } 595 596 void MediaRecorder::doCleanUp() 597 { 598 ALOGV("doCleanUp"); 599 mIsAudioSourceSet = false; 600 mIsVideoSourceSet = false; 601 mIsAudioEncoderSet = false; 602 mIsVideoEncoderSet = false; 603 mIsOutputFileSet = false; 604 } 605 606 // Release should be OK in any state 607 status_t MediaRecorder::release() 608 { 609 ALOGV("release"); 610 if (mMediaRecorder != NULL) { 611 return mMediaRecorder->release(); 612 } 613 return INVALID_OPERATION; 614 } 615 616 MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSource(NULL) 617 { 618 ALOGV("constructor"); 619 620 const sp<IMediaPlayerService>& service(getMediaPlayerService()); 621 if (service != NULL) { 622 mMediaRecorder = service->createMediaRecorder(opPackageName); 623 } 624 if (mMediaRecorder != NULL) { 625 mCurrentState = MEDIA_RECORDER_IDLE; 626 } 627 628 629 doCleanUp(); 630 } 631 632 status_t MediaRecorder::initCheck() 633 { 634 return mMediaRecorder != 0 ? NO_ERROR : NO_INIT; 635 } 636 637 MediaRecorder::~MediaRecorder() 638 { 639 ALOGV("destructor"); 640 if (mMediaRecorder != NULL) { 641 mMediaRecorder.clear(); 642 } 643 644 if (mSurfaceMediaSource != NULL) { 645 mSurfaceMediaSource.clear(); 646 } 647 } 648 649 status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener) 650 { 651 ALOGV("setListener"); 652 Mutex::Autolock _l(mLock); 653 mListener = listener; 654 655 return NO_ERROR; 656 } 657 658 status_t MediaRecorder::setClientName(const String16& clientName) 659 { 660 ALOGV("setClientName"); 661 if (mMediaRecorder == NULL) { 662 ALOGE("media recorder is not initialized yet"); 663 return INVALID_OPERATION; 664 } 665 bool isInvalidState = (mCurrentState & 666 (MEDIA_RECORDER_PREPARED | 667 MEDIA_RECORDER_RECORDING | 668 MEDIA_RECORDER_ERROR)); 669 if (isInvalidState) { 670 ALOGE("setClientName is called in an invalid state: %d", mCurrentState); 671 return INVALID_OPERATION; 672 } 673 674 mMediaRecorder->setClientName(clientName); 675 676 return NO_ERROR; 677 } 678 679 void MediaRecorder::notify(int msg, int ext1, int ext2) 680 { 681 ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); 682 683 sp<MediaRecorderListener> listener; 684 mLock.lock(); 685 listener = mListener; 686 mLock.unlock(); 687 688 if (listener != NULL) { 689 Mutex::Autolock _l(mNotifyLock); 690 ALOGV("callback application"); 691 listener->notify(msg, ext1, ext2); 692 ALOGV("back from callback"); 693 } 694 } 695 696 void MediaRecorder::died() 697 { 698 ALOGV("died"); 699 notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0); 700 } 701 702 } // namespace android 703