1 /* 2 * Copyright (C) 2012 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 "CameraClient" 18 //#define LOG_NDEBUG 0 19 20 #include <cutils/properties.h> 21 #include <gui/Surface.h> 22 23 #include "api1/CameraClient.h" 24 #include "device1/CameraHardwareInterface.h" 25 #include "CameraService.h" 26 27 namespace android { 28 29 #define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__); 30 #define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__); 31 32 static int getCallingPid() { 33 return IPCThreadState::self()->getCallingPid(); 34 } 35 36 CameraClient::CameraClient(const sp<CameraService>& cameraService, 37 const sp<ICameraClient>& cameraClient, 38 const String16& clientPackageName, 39 int cameraId, int cameraFacing, 40 int clientPid, int clientUid, 41 int servicePid, bool legacyMode): 42 Client(cameraService, cameraClient, clientPackageName, 43 cameraId, cameraFacing, clientPid, clientUid, servicePid) 44 { 45 int callingPid = getCallingPid(); 46 LOG1("CameraClient::CameraClient E (pid %d, id %d)", callingPid, cameraId); 47 48 mHardware = NULL; 49 mMsgEnabled = 0; 50 mSurface = 0; 51 mPreviewWindow = 0; 52 mDestructionStarted = false; 53 54 // Callback is disabled by default 55 mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP; 56 mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT); 57 mLegacyMode = legacyMode; 58 mPlayShutterSound = true; 59 LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId); 60 } 61 62 status_t CameraClient::initialize(CameraModule *module) { 63 int callingPid = getCallingPid(); 64 status_t res; 65 66 LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId); 67 68 // Verify ops permissions 69 res = startCameraOps(); 70 if (res != OK) { 71 return res; 72 } 73 74 char camera_device_name[10]; 75 snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId); 76 77 mHardware = new CameraHardwareInterface(camera_device_name); 78 res = mHardware->initialize(module); 79 if (res != OK) { 80 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)", 81 __FUNCTION__, mCameraId, strerror(-res), res); 82 mHardware.clear(); 83 return res; 84 } 85 86 mHardware->setCallbacks(notifyCallback, 87 dataCallback, 88 dataCallbackTimestamp, 89 (void *)(uintptr_t)mCameraId); 90 91 // Enable zoom, error, focus, and metadata messages by default 92 enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS | 93 CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE); 94 95 LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId); 96 return OK; 97 } 98 99 100 // tear down the client 101 CameraClient::~CameraClient() { 102 mDestructionStarted = true; 103 int callingPid = getCallingPid(); 104 LOG1("CameraClient::~CameraClient E (pid %d, this %p)", callingPid, this); 105 106 disconnect(); 107 LOG1("CameraClient::~CameraClient X (pid %d, this %p)", callingPid, this); 108 } 109 110 status_t CameraClient::dump(int fd, const Vector<String16>& args) { 111 const size_t SIZE = 256; 112 char buffer[SIZE]; 113 114 size_t len = snprintf(buffer, SIZE, "Client[%d] (%p) with UID %d\n", 115 mCameraId, 116 (getRemoteCallback() != NULL ? 117 IInterface::asBinder(getRemoteCallback()).get() : NULL), 118 mClientUid); 119 len = (len > SIZE - 1) ? SIZE - 1 : len; 120 write(fd, buffer, len); 121 122 len = snprintf(buffer, SIZE, "Latest set parameters:\n"); 123 len = (len > SIZE - 1) ? SIZE - 1 : len; 124 write(fd, buffer, len); 125 126 mLatestSetParameters.dump(fd, args); 127 128 const char *enddump = "\n\n"; 129 write(fd, enddump, strlen(enddump)); 130 131 return mHardware->dump(fd, args); 132 } 133 134 // ---------------------------------------------------------------------------- 135 136 status_t CameraClient::checkPid() const { 137 int callingPid = getCallingPid(); 138 if (callingPid == mClientPid) return NO_ERROR; 139 140 ALOGW("attempt to use a locked camera from a different process" 141 " (old pid %d, new pid %d)", mClientPid, callingPid); 142 return EBUSY; 143 } 144 145 status_t CameraClient::checkPidAndHardware() const { 146 status_t result = checkPid(); 147 if (result != NO_ERROR) return result; 148 if (mHardware == 0) { 149 ALOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid()); 150 return INVALID_OPERATION; 151 } 152 return NO_ERROR; 153 } 154 155 status_t CameraClient::lock() { 156 int callingPid = getCallingPid(); 157 LOG1("lock (pid %d)", callingPid); 158 Mutex::Autolock lock(mLock); 159 160 // lock camera to this client if the the camera is unlocked 161 if (mClientPid == 0) { 162 mClientPid = callingPid; 163 return NO_ERROR; 164 } 165 166 // returns NO_ERROR if the client already owns the camera, EBUSY otherwise 167 return checkPid(); 168 } 169 170 status_t CameraClient::unlock() { 171 int callingPid = getCallingPid(); 172 LOG1("unlock (pid %d)", callingPid); 173 Mutex::Autolock lock(mLock); 174 175 // allow anyone to use camera (after they lock the camera) 176 status_t result = checkPid(); 177 if (result == NO_ERROR) { 178 if (mHardware->recordingEnabled()) { 179 ALOGE("Not allowed to unlock camera during recording."); 180 return INVALID_OPERATION; 181 } 182 mClientPid = 0; 183 LOG1("clear mRemoteCallback (pid %d)", callingPid); 184 // we need to remove the reference to ICameraClient so that when the app 185 // goes away, the reference count goes to 0. 186 mRemoteCallback.clear(); 187 } 188 return result; 189 } 190 191 // connect a new client to the camera 192 status_t CameraClient::connect(const sp<ICameraClient>& client) { 193 int callingPid = getCallingPid(); 194 LOG1("connect E (pid %d)", callingPid); 195 Mutex::Autolock lock(mLock); 196 197 if (mClientPid != 0 && checkPid() != NO_ERROR) { 198 ALOGW("Tried to connect to a locked camera (old pid %d, new pid %d)", 199 mClientPid, callingPid); 200 return EBUSY; 201 } 202 203 if (mRemoteCallback != 0 && 204 (IInterface::asBinder(client) == IInterface::asBinder(mRemoteCallback))) { 205 LOG1("Connect to the same client"); 206 return NO_ERROR; 207 } 208 209 mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP; 210 mClientPid = callingPid; 211 mRemoteCallback = client; 212 213 LOG1("connect X (pid %d)", callingPid); 214 return NO_ERROR; 215 } 216 217 static void disconnectWindow(const sp<ANativeWindow>& window) { 218 if (window != 0) { 219 status_t result = native_window_api_disconnect(window.get(), 220 NATIVE_WINDOW_API_CAMERA); 221 if (result != NO_ERROR) { 222 ALOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result), 223 result); 224 } 225 } 226 } 227 228 void CameraClient::disconnect() { 229 int callingPid = getCallingPid(); 230 LOG1("disconnect E (pid %d)", callingPid); 231 Mutex::Autolock lock(mLock); 232 233 // Allow both client and the media server to disconnect at all times 234 if (callingPid != mClientPid && callingPid != mServicePid) { 235 ALOGW("different client - don't disconnect"); 236 return; 237 } 238 239 if (mClientPid <= 0) { 240 LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid); 241 return; 242 } 243 244 // Make sure disconnect() is done once and once only, whether it is called 245 // from the user directly, or called by the destructor. 246 if (mHardware == 0) return; 247 248 LOG1("hardware teardown"); 249 // Before destroying mHardware, we must make sure it's in the 250 // idle state. 251 // Turn off all messages. 252 disableMsgType(CAMERA_MSG_ALL_MSGS); 253 mHardware->stopPreview(); 254 mHardware->cancelPicture(); 255 // Release the hardware resources. 256 mHardware->release(); 257 258 // Release the held ANativeWindow resources. 259 if (mPreviewWindow != 0) { 260 disconnectWindow(mPreviewWindow); 261 mPreviewWindow = 0; 262 mHardware->setPreviewWindow(mPreviewWindow); 263 } 264 mHardware.clear(); 265 266 CameraService::Client::disconnect(); 267 268 LOG1("disconnect X (pid %d)", callingPid); 269 } 270 271 // ---------------------------------------------------------------------------- 272 273 status_t CameraClient::setPreviewWindow(const sp<IBinder>& binder, 274 const sp<ANativeWindow>& window) { 275 Mutex::Autolock lock(mLock); 276 status_t result = checkPidAndHardware(); 277 if (result != NO_ERROR) return result; 278 279 // return if no change in surface. 280 if (binder == mSurface) { 281 return NO_ERROR; 282 } 283 284 if (window != 0) { 285 result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA); 286 if (result != NO_ERROR) { 287 ALOGE("native_window_api_connect failed: %s (%d)", strerror(-result), 288 result); 289 return result; 290 } 291 } 292 293 // If preview has been already started, register preview buffers now. 294 if (mHardware->previewEnabled()) { 295 if (window != 0) { 296 native_window_set_scaling_mode(window.get(), 297 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 298 native_window_set_buffers_transform(window.get(), mOrientation); 299 result = mHardware->setPreviewWindow(window); 300 } 301 } 302 303 if (result == NO_ERROR) { 304 // Everything has succeeded. Disconnect the old window and remember the 305 // new window. 306 disconnectWindow(mPreviewWindow); 307 mSurface = binder; 308 mPreviewWindow = window; 309 } else { 310 // Something went wrong after we connected to the new window, so 311 // disconnect here. 312 disconnectWindow(window); 313 } 314 315 return result; 316 } 317 318 // set the buffer consumer that the preview will use 319 status_t CameraClient::setPreviewTarget( 320 const sp<IGraphicBufferProducer>& bufferProducer) { 321 LOG1("setPreviewTarget(%p) (pid %d)", bufferProducer.get(), 322 getCallingPid()); 323 324 sp<IBinder> binder; 325 sp<ANativeWindow> window; 326 if (bufferProducer != 0) { 327 binder = IInterface::asBinder(bufferProducer); 328 // Using controlledByApp flag to ensure that the buffer queue remains in 329 // async mode for the old camera API, where many applications depend 330 // on that behavior. 331 window = new Surface(bufferProducer, /*controlledByApp*/ true); 332 } 333 return setPreviewWindow(binder, window); 334 } 335 336 // set the preview callback flag to affect how the received frames from 337 // preview are handled. 338 void CameraClient::setPreviewCallbackFlag(int callback_flag) { 339 LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid()); 340 Mutex::Autolock lock(mLock); 341 if (checkPidAndHardware() != NO_ERROR) return; 342 343 mPreviewCallbackFlag = callback_flag; 344 if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { 345 enableMsgType(CAMERA_MSG_PREVIEW_FRAME); 346 } else { 347 disableMsgType(CAMERA_MSG_PREVIEW_FRAME); 348 } 349 } 350 351 status_t CameraClient::setPreviewCallbackTarget( 352 const sp<IGraphicBufferProducer>& callbackProducer) { 353 (void)callbackProducer; 354 ALOGE("%s: Unimplemented!", __FUNCTION__); 355 return INVALID_OPERATION; 356 } 357 358 // start preview mode 359 status_t CameraClient::startPreview() { 360 LOG1("startPreview (pid %d)", getCallingPid()); 361 return startCameraMode(CAMERA_PREVIEW_MODE); 362 } 363 364 // start recording mode 365 status_t CameraClient::startRecording() { 366 LOG1("startRecording (pid %d)", getCallingPid()); 367 return startCameraMode(CAMERA_RECORDING_MODE); 368 } 369 370 // start preview or recording 371 status_t CameraClient::startCameraMode(camera_mode mode) { 372 LOG1("startCameraMode(%d)", mode); 373 Mutex::Autolock lock(mLock); 374 status_t result = checkPidAndHardware(); 375 if (result != NO_ERROR) return result; 376 377 switch(mode) { 378 case CAMERA_PREVIEW_MODE: 379 if (mSurface == 0 && mPreviewWindow == 0) { 380 LOG1("mSurface is not set yet."); 381 // still able to start preview in this case. 382 } 383 return startPreviewMode(); 384 case CAMERA_RECORDING_MODE: 385 if (mSurface == 0 && mPreviewWindow == 0) { 386 ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode."); 387 return INVALID_OPERATION; 388 } 389 return startRecordingMode(); 390 default: 391 return UNKNOWN_ERROR; 392 } 393 } 394 395 status_t CameraClient::startPreviewMode() { 396 LOG1("startPreviewMode"); 397 status_t result = NO_ERROR; 398 399 // if preview has been enabled, nothing needs to be done 400 if (mHardware->previewEnabled()) { 401 return NO_ERROR; 402 } 403 404 if (mPreviewWindow != 0) { 405 native_window_set_scaling_mode(mPreviewWindow.get(), 406 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 407 native_window_set_buffers_transform(mPreviewWindow.get(), 408 mOrientation); 409 } 410 mHardware->setPreviewWindow(mPreviewWindow); 411 result = mHardware->startPreview(); 412 413 return result; 414 } 415 416 status_t CameraClient::startRecordingMode() { 417 LOG1("startRecordingMode"); 418 status_t result = NO_ERROR; 419 420 // if recording has been enabled, nothing needs to be done 421 if (mHardware->recordingEnabled()) { 422 return NO_ERROR; 423 } 424 425 // if preview has not been started, start preview first 426 if (!mHardware->previewEnabled()) { 427 result = startPreviewMode(); 428 if (result != NO_ERROR) { 429 return result; 430 } 431 } 432 433 // start recording mode 434 enableMsgType(CAMERA_MSG_VIDEO_FRAME); 435 mCameraService->playSound(CameraService::SOUND_RECORDING); 436 result = mHardware->startRecording(); 437 if (result != NO_ERROR) { 438 ALOGE("mHardware->startRecording() failed with status %d", result); 439 } 440 return result; 441 } 442 443 // stop preview mode 444 void CameraClient::stopPreview() { 445 LOG1("stopPreview (pid %d)", getCallingPid()); 446 Mutex::Autolock lock(mLock); 447 if (checkPidAndHardware() != NO_ERROR) return; 448 449 450 disableMsgType(CAMERA_MSG_PREVIEW_FRAME); 451 mHardware->stopPreview(); 452 453 mPreviewBuffer.clear(); 454 } 455 456 // stop recording mode 457 void CameraClient::stopRecording() { 458 LOG1("stopRecording (pid %d)", getCallingPid()); 459 Mutex::Autolock lock(mLock); 460 if (checkPidAndHardware() != NO_ERROR) return; 461 462 disableMsgType(CAMERA_MSG_VIDEO_FRAME); 463 mHardware->stopRecording(); 464 mCameraService->playSound(CameraService::SOUND_RECORDING); 465 466 mPreviewBuffer.clear(); 467 } 468 469 // release a recording frame 470 void CameraClient::releaseRecordingFrame(const sp<IMemory>& mem) { 471 Mutex::Autolock lock(mLock); 472 if (checkPidAndHardware() != NO_ERROR) return; 473 mHardware->releaseRecordingFrame(mem); 474 } 475 476 status_t CameraClient::storeMetaDataInBuffers(bool enabled) 477 { 478 LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false"); 479 Mutex::Autolock lock(mLock); 480 if (checkPidAndHardware() != NO_ERROR) { 481 return UNKNOWN_ERROR; 482 } 483 return mHardware->storeMetaDataInBuffers(enabled); 484 } 485 486 bool CameraClient::previewEnabled() { 487 LOG1("previewEnabled (pid %d)", getCallingPid()); 488 489 Mutex::Autolock lock(mLock); 490 if (checkPidAndHardware() != NO_ERROR) return false; 491 return mHardware->previewEnabled(); 492 } 493 494 bool CameraClient::recordingEnabled() { 495 LOG1("recordingEnabled (pid %d)", getCallingPid()); 496 497 Mutex::Autolock lock(mLock); 498 if (checkPidAndHardware() != NO_ERROR) return false; 499 return mHardware->recordingEnabled(); 500 } 501 502 status_t CameraClient::autoFocus() { 503 LOG1("autoFocus (pid %d)", getCallingPid()); 504 505 Mutex::Autolock lock(mLock); 506 status_t result = checkPidAndHardware(); 507 if (result != NO_ERROR) return result; 508 509 return mHardware->autoFocus(); 510 } 511 512 status_t CameraClient::cancelAutoFocus() { 513 LOG1("cancelAutoFocus (pid %d)", getCallingPid()); 514 515 Mutex::Autolock lock(mLock); 516 status_t result = checkPidAndHardware(); 517 if (result != NO_ERROR) return result; 518 519 return mHardware->cancelAutoFocus(); 520 } 521 522 // take a picture - image is returned in callback 523 status_t CameraClient::takePicture(int msgType) { 524 LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType); 525 526 Mutex::Autolock lock(mLock); 527 status_t result = checkPidAndHardware(); 528 if (result != NO_ERROR) return result; 529 530 if ((msgType & CAMERA_MSG_RAW_IMAGE) && 531 (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) { 532 ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY" 533 " cannot be both enabled"); 534 return BAD_VALUE; 535 } 536 537 // We only accept picture related message types 538 // and ignore other types of messages for takePicture(). 539 int picMsgType = msgType 540 & (CAMERA_MSG_SHUTTER | 541 CAMERA_MSG_POSTVIEW_FRAME | 542 CAMERA_MSG_RAW_IMAGE | 543 CAMERA_MSG_RAW_IMAGE_NOTIFY | 544 CAMERA_MSG_COMPRESSED_IMAGE); 545 546 enableMsgType(picMsgType); 547 548 return mHardware->takePicture(); 549 } 550 551 // set preview/capture parameters - key/value pairs 552 status_t CameraClient::setParameters(const String8& params) { 553 LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string()); 554 555 Mutex::Autolock lock(mLock); 556 status_t result = checkPidAndHardware(); 557 if (result != NO_ERROR) return result; 558 559 mLatestSetParameters = CameraParameters(params); 560 CameraParameters p(params); 561 return mHardware->setParameters(p); 562 } 563 564 // get preview/capture parameters - key/value pairs 565 String8 CameraClient::getParameters() const { 566 Mutex::Autolock lock(mLock); 567 // The camera service can unconditionally get the parameters at all times 568 if (getCallingPid() != mServicePid && checkPidAndHardware() != NO_ERROR) return String8(); 569 570 String8 params(mHardware->getParameters().flatten()); 571 LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string()); 572 return params; 573 } 574 575 // enable shutter sound 576 status_t CameraClient::enableShutterSound(bool enable) { 577 LOG1("enableShutterSound (pid %d)", getCallingPid()); 578 579 status_t result = checkPidAndHardware(); 580 if (result != NO_ERROR) return result; 581 582 if (enable) { 583 mPlayShutterSound = true; 584 return OK; 585 } 586 587 // the camera2 api legacy mode can unconditionally disable the shutter sound 588 if (mLegacyMode) { 589 ALOGV("%s: Disable shutter sound in legacy mode", __FUNCTION__); 590 mPlayShutterSound = false; 591 return OK; 592 } 593 594 // Disabling shutter sound may not be allowed. In that case only 595 // allow the mediaserver process to disable the sound. 596 char value[PROPERTY_VALUE_MAX]; 597 property_get("ro.camera.sound.forced", value, "0"); 598 if (strcmp(value, "0") != 0) { 599 // Disabling shutter sound is not allowed. Deny if the current 600 // process is not mediaserver. 601 if (getCallingPid() != getpid()) { 602 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid()); 603 return PERMISSION_DENIED; 604 } 605 } 606 607 mPlayShutterSound = false; 608 return OK; 609 } 610 611 status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) { 612 LOG1("sendCommand (pid %d)", getCallingPid()); 613 int orientation; 614 Mutex::Autolock lock(mLock); 615 status_t result = checkPidAndHardware(); 616 if (result != NO_ERROR) return result; 617 618 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) { 619 // Mirror the preview if the camera is front-facing. 620 orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT); 621 if (orientation == -1) return BAD_VALUE; 622 623 if (mOrientation != orientation) { 624 mOrientation = orientation; 625 if (mPreviewWindow != 0) { 626 native_window_set_buffers_transform(mPreviewWindow.get(), 627 mOrientation); 628 } 629 } 630 return OK; 631 } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) { 632 switch (arg1) { 633 case 0: 634 return enableShutterSound(false); 635 case 1: 636 return enableShutterSound(true); 637 default: 638 return BAD_VALUE; 639 } 640 return OK; 641 } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) { 642 mCameraService->playSound(CameraService::SOUND_RECORDING); 643 } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) { 644 // Silently ignore this command 645 return INVALID_OPERATION; 646 } else if (cmd == CAMERA_CMD_PING) { 647 // If mHardware is 0, checkPidAndHardware will return error. 648 return OK; 649 } 650 651 return mHardware->sendCommand(cmd, arg1, arg2); 652 } 653 654 // ---------------------------------------------------------------------------- 655 656 void CameraClient::enableMsgType(int32_t msgType) { 657 android_atomic_or(msgType, &mMsgEnabled); 658 mHardware->enableMsgType(msgType); 659 } 660 661 void CameraClient::disableMsgType(int32_t msgType) { 662 android_atomic_and(~msgType, &mMsgEnabled); 663 mHardware->disableMsgType(msgType); 664 } 665 666 #define CHECK_MESSAGE_INTERVAL 10 // 10ms 667 bool CameraClient::lockIfMessageWanted(int32_t msgType) { 668 int sleepCount = 0; 669 while (mMsgEnabled & msgType) { 670 if (mLock.tryLock() == NO_ERROR) { 671 if (sleepCount > 0) { 672 LOG1("lockIfMessageWanted(%d): waited for %d ms", 673 msgType, sleepCount * CHECK_MESSAGE_INTERVAL); 674 } 675 676 // If messages are no longer enabled after acquiring lock, release and drop message 677 if ((mMsgEnabled & msgType) == 0) { 678 mLock.unlock(); 679 break; 680 } 681 682 return true; 683 } 684 if (sleepCount++ == 0) { 685 LOG1("lockIfMessageWanted(%d): enter sleep", msgType); 686 } 687 usleep(CHECK_MESSAGE_INTERVAL * 1000); 688 } 689 ALOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType); 690 return false; 691 } 692 693 // Callback messages can be dispatched to internal handlers or pass to our 694 // client's callback functions, depending on the message type. 695 // 696 // notifyCallback: 697 // CAMERA_MSG_SHUTTER handleShutter 698 // (others) c->notifyCallback 699 // dataCallback: 700 // CAMERA_MSG_PREVIEW_FRAME handlePreviewData 701 // CAMERA_MSG_POSTVIEW_FRAME handlePostview 702 // CAMERA_MSG_RAW_IMAGE handleRawPicture 703 // CAMERA_MSG_COMPRESSED_IMAGE handleCompressedPicture 704 // (others) c->dataCallback 705 // dataCallbackTimestamp 706 // (others) c->dataCallbackTimestamp 707 708 void CameraClient::notifyCallback(int32_t msgType, int32_t ext1, 709 int32_t ext2, void* user) { 710 LOG2("notifyCallback(%d)", msgType); 711 712 sp<CameraClient> client = static_cast<CameraClient*>(getClientFromCookie(user).get()); 713 if (client.get() == nullptr) return; 714 715 if (!client->lockIfMessageWanted(msgType)) return; 716 717 switch (msgType) { 718 case CAMERA_MSG_SHUTTER: 719 // ext1 is the dimension of the yuv picture. 720 client->handleShutter(); 721 break; 722 default: 723 client->handleGenericNotify(msgType, ext1, ext2); 724 break; 725 } 726 } 727 728 void CameraClient::dataCallback(int32_t msgType, 729 const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) { 730 LOG2("dataCallback(%d)", msgType); 731 732 sp<CameraClient> client = static_cast<CameraClient*>(getClientFromCookie(user).get()); 733 if (client.get() == nullptr) return; 734 735 if (!client->lockIfMessageWanted(msgType)) return; 736 if (dataPtr == 0 && metadata == NULL) { 737 ALOGE("Null data returned in data callback"); 738 client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 739 return; 740 } 741 742 switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) { 743 case CAMERA_MSG_PREVIEW_FRAME: 744 client->handlePreviewData(msgType, dataPtr, metadata); 745 break; 746 case CAMERA_MSG_POSTVIEW_FRAME: 747 client->handlePostview(dataPtr); 748 break; 749 case CAMERA_MSG_RAW_IMAGE: 750 client->handleRawPicture(dataPtr); 751 break; 752 case CAMERA_MSG_COMPRESSED_IMAGE: 753 client->handleCompressedPicture(dataPtr); 754 break; 755 default: 756 client->handleGenericData(msgType, dataPtr, metadata); 757 break; 758 } 759 } 760 761 void CameraClient::dataCallbackTimestamp(nsecs_t timestamp, 762 int32_t msgType, const sp<IMemory>& dataPtr, void* user) { 763 LOG2("dataCallbackTimestamp(%d)", msgType); 764 765 sp<CameraClient> client = static_cast<CameraClient*>(getClientFromCookie(user).get()); 766 if (client.get() == nullptr) return; 767 768 if (!client->lockIfMessageWanted(msgType)) return; 769 770 if (dataPtr == 0) { 771 ALOGE("Null data returned in data with timestamp callback"); 772 client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 773 return; 774 } 775 776 client->handleGenericDataTimestamp(timestamp, msgType, dataPtr); 777 } 778 779 // snapshot taken callback 780 void CameraClient::handleShutter(void) { 781 if (mPlayShutterSound) { 782 mCameraService->playSound(CameraService::SOUND_SHUTTER); 783 } 784 785 sp<ICameraClient> c = mRemoteCallback; 786 if (c != 0) { 787 mLock.unlock(); 788 c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0); 789 if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return; 790 } 791 disableMsgType(CAMERA_MSG_SHUTTER); 792 793 mLock.unlock(); 794 } 795 796 // preview callback - frame buffer update 797 void CameraClient::handlePreviewData(int32_t msgType, 798 const sp<IMemory>& mem, 799 camera_frame_metadata_t *metadata) { 800 ssize_t offset; 801 size_t size; 802 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 803 804 // local copy of the callback flags 805 int flags = mPreviewCallbackFlag; 806 807 // is callback enabled? 808 if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) { 809 // If the enable bit is off, the copy-out and one-shot bits are ignored 810 LOG2("frame callback is disabled"); 811 mLock.unlock(); 812 return; 813 } 814 815 // hold a strong pointer to the client 816 sp<ICameraClient> c = mRemoteCallback; 817 818 // clear callback flags if no client or one-shot mode 819 if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) { 820 LOG2("Disable preview callback"); 821 mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK | 822 CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK | 823 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK); 824 disableMsgType(CAMERA_MSG_PREVIEW_FRAME); 825 } 826 827 if (c != 0) { 828 // Is the received frame copied out or not? 829 if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { 830 LOG2("frame is copied"); 831 copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata); 832 } else { 833 LOG2("frame is forwarded"); 834 mLock.unlock(); 835 c->dataCallback(msgType, mem, metadata); 836 } 837 } else { 838 mLock.unlock(); 839 } 840 } 841 842 // picture callback - postview image ready 843 void CameraClient::handlePostview(const sp<IMemory>& mem) { 844 disableMsgType(CAMERA_MSG_POSTVIEW_FRAME); 845 846 sp<ICameraClient> c = mRemoteCallback; 847 mLock.unlock(); 848 if (c != 0) { 849 c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL); 850 } 851 } 852 853 // picture callback - raw image ready 854 void CameraClient::handleRawPicture(const sp<IMemory>& mem) { 855 disableMsgType(CAMERA_MSG_RAW_IMAGE); 856 857 ssize_t offset; 858 size_t size; 859 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 860 861 sp<ICameraClient> c = mRemoteCallback; 862 mLock.unlock(); 863 if (c != 0) { 864 c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL); 865 } 866 } 867 868 // picture callback - compressed picture ready 869 void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) { 870 disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE); 871 872 sp<ICameraClient> c = mRemoteCallback; 873 mLock.unlock(); 874 if (c != 0) { 875 c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL); 876 } 877 } 878 879 880 void CameraClient::handleGenericNotify(int32_t msgType, 881 int32_t ext1, int32_t ext2) { 882 sp<ICameraClient> c = mRemoteCallback; 883 mLock.unlock(); 884 if (c != 0) { 885 c->notifyCallback(msgType, ext1, ext2); 886 } 887 } 888 889 void CameraClient::handleGenericData(int32_t msgType, 890 const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) { 891 sp<ICameraClient> c = mRemoteCallback; 892 mLock.unlock(); 893 if (c != 0) { 894 c->dataCallback(msgType, dataPtr, metadata); 895 } 896 } 897 898 void CameraClient::handleGenericDataTimestamp(nsecs_t timestamp, 899 int32_t msgType, const sp<IMemory>& dataPtr) { 900 sp<ICameraClient> c = mRemoteCallback; 901 mLock.unlock(); 902 if (c != 0) { 903 c->dataCallbackTimestamp(timestamp, msgType, dataPtr); 904 } 905 } 906 907 void CameraClient::copyFrameAndPostCopiedFrame( 908 int32_t msgType, const sp<ICameraClient>& client, 909 const sp<IMemoryHeap>& heap, size_t offset, size_t size, 910 camera_frame_metadata_t *metadata) { 911 LOG2("copyFrameAndPostCopiedFrame"); 912 // It is necessary to copy out of pmem before sending this to 913 // the callback. For efficiency, reuse the same MemoryHeapBase 914 // provided it's big enough. Don't allocate the memory or 915 // perform the copy if there's no callback. 916 // hold the preview lock while we grab a reference to the preview buffer 917 sp<MemoryHeapBase> previewBuffer; 918 919 if (mPreviewBuffer == 0) { 920 mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); 921 } else if (size > mPreviewBuffer->virtualSize()) { 922 mPreviewBuffer.clear(); 923 mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); 924 } 925 if (mPreviewBuffer == 0) { 926 ALOGE("failed to allocate space for preview buffer"); 927 mLock.unlock(); 928 return; 929 } 930 previewBuffer = mPreviewBuffer; 931 932 void* previewBufferBase = previewBuffer->base(); 933 void* heapBase = heap->base(); 934 935 if (heapBase == MAP_FAILED) { 936 ALOGE("%s: Failed to mmap heap for preview frame.", __FUNCTION__); 937 mLock.unlock(); 938 return; 939 } else if (previewBufferBase == MAP_FAILED) { 940 ALOGE("%s: Failed to mmap preview buffer for preview frame.", __FUNCTION__); 941 mLock.unlock(); 942 return; 943 } 944 945 memcpy(previewBufferBase, (uint8_t *) heapBase + offset, size); 946 947 sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size); 948 if (frame == 0) { 949 ALOGE("failed to allocate space for frame callback"); 950 mLock.unlock(); 951 return; 952 } 953 954 mLock.unlock(); 955 client->dataCallback(msgType, frame, metadata); 956 } 957 958 int CameraClient::getOrientation(int degrees, bool mirror) { 959 if (!mirror) { 960 if (degrees == 0) return 0; 961 else if (degrees == 90) return HAL_TRANSFORM_ROT_90; 962 else if (degrees == 180) return HAL_TRANSFORM_ROT_180; 963 else if (degrees == 270) return HAL_TRANSFORM_ROT_270; 964 } else { // Do mirror (horizontal flip) 965 if (degrees == 0) { // FLIP_H and ROT_0 966 return HAL_TRANSFORM_FLIP_H; 967 } else if (degrees == 90) { // FLIP_H and ROT_90 968 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90; 969 } else if (degrees == 180) { // FLIP_H and ROT_180 970 return HAL_TRANSFORM_FLIP_V; 971 } else if (degrees == 270) { // FLIP_H and ROT_270 972 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90; 973 } 974 } 975 ALOGE("Invalid setDisplayOrientation degrees=%d", degrees); 976 return -1; 977 } 978 979 }; // namespace android 980