CameraDeviceClient.cpp revision f1e98d857ec377f2c9b916073d40732e6ebb7ced
1/* 2 * Copyright (C) 2013 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 "CameraDeviceClient" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19// #define LOG_NDEBUG 0 20 21#include <cutils/properties.h> 22#include <utils/Log.h> 23#include <utils/Trace.h> 24#include <gui/Surface.h> 25#include <camera/camera2/CaptureRequest.h> 26 27#include "common/CameraDeviceBase.h" 28#include "api2/CameraDeviceClient.h" 29 30 31 32namespace android { 33using namespace camera2; 34 35CameraDeviceClientBase::CameraDeviceClientBase( 36 const sp<CameraService>& cameraService, 37 const sp<ICameraDeviceCallbacks>& remoteCallback, 38 const String16& clientPackageName, 39 int cameraId, 40 int cameraFacing, 41 int clientPid, 42 uid_t clientUid, 43 int servicePid) : 44 BasicClient(cameraService, remoteCallback->asBinder(), clientPackageName, 45 cameraId, cameraFacing, clientPid, clientUid, servicePid), 46 mRemoteCallback(remoteCallback) { 47} 48 49// Interface used by CameraService 50 51CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService, 52 const sp<ICameraDeviceCallbacks>& remoteCallback, 53 const String16& clientPackageName, 54 int cameraId, 55 int cameraFacing, 56 int clientPid, 57 uid_t clientUid, 58 int servicePid) : 59 Camera2ClientBase(cameraService, remoteCallback, clientPackageName, 60 cameraId, cameraFacing, clientPid, clientUid, servicePid), 61 mRequestIdCounter(0) { 62 63 ATRACE_CALL(); 64 ALOGI("CameraDeviceClient %d: Opened", cameraId); 65} 66 67status_t CameraDeviceClient::initialize(camera_module_t *module) 68{ 69 ATRACE_CALL(); 70 status_t res; 71 72 res = Camera2ClientBase::initialize(module); 73 if (res != OK) { 74 return res; 75 } 76 77 String8 threadName; 78 mFrameProcessor = new FrameProcessorBase(mDevice); 79 threadName = String8::format("CDU-%d-FrameProc", mCameraId); 80 mFrameProcessor->run(threadName.string()); 81 82 mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID, 83 FRAME_PROCESSOR_LISTENER_MAX_ID, 84 /*listener*/this); 85 86 return OK; 87} 88 89CameraDeviceClient::~CameraDeviceClient() { 90} 91 92status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request, 93 bool streaming) { 94 ATRACE_CALL(); 95 ALOGV("%s", __FUNCTION__); 96 97 status_t res; 98 99 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 100 101 Mutex::Autolock icl(mBinderSerializationLock); 102 103 if (!mDevice.get()) return DEAD_OBJECT; 104 105 if (request == 0) { 106 ALOGE("%s: Camera %d: Sent null request. Rejecting request.", 107 __FUNCTION__, mCameraId); 108 return BAD_VALUE; 109 } 110 111 CameraMetadata metadata(request->mMetadata); 112 113 if (metadata.isEmpty()) { 114 ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.", 115 __FUNCTION__, mCameraId); 116 return BAD_VALUE; 117 } else if (request->mSurfaceList.size() == 0) { 118 ALOGE("%s: Camera %d: Requests must have at least one surface target. " 119 "Rejecting request.", __FUNCTION__, mCameraId); 120 return BAD_VALUE; 121 } 122 123 if (!enforceRequestPermissions(metadata)) { 124 // Callee logs 125 return PERMISSION_DENIED; 126 } 127 128 /** 129 * Write in the output stream IDs which we calculate from 130 * the capture request's list of surface targets 131 */ 132 Vector<int32_t> outputStreamIds; 133 outputStreamIds.setCapacity(request->mSurfaceList.size()); 134 for (size_t i = 0; i < request->mSurfaceList.size(); ++i) { 135 sp<Surface> surface = request->mSurfaceList[i]; 136 137 if (surface == 0) continue; 138 139 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer(); 140 int idx = mStreamMap.indexOfKey(gbp->asBinder()); 141 142 // Trying to submit request with surface that wasn't created 143 if (idx == NAME_NOT_FOUND) { 144 ALOGE("%s: Camera %d: Tried to submit a request with a surface that" 145 " we have not called createStream on", 146 __FUNCTION__, mCameraId); 147 return BAD_VALUE; 148 } 149 150 int streamId = mStreamMap.valueAt(idx); 151 outputStreamIds.push_back(streamId); 152 ALOGV("%s: Camera %d: Appending output stream %d to request", 153 __FUNCTION__, mCameraId, streamId); 154 } 155 156 metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0], 157 outputStreamIds.size()); 158 159 int32_t requestId = mRequestIdCounter++; 160 metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1); 161 ALOGV("%s: Camera %d: Submitting request with ID %d", 162 __FUNCTION__, mCameraId, requestId); 163 164 if (streaming) { 165 res = mDevice->setStreamingRequest(metadata); 166 if (res != OK) { 167 ALOGE("%s: Camera %d: Got error %d after trying to set streaming " 168 "request", __FUNCTION__, mCameraId, res); 169 } else { 170 mStreamingRequestList.push_back(requestId); 171 } 172 } else { 173 res = mDevice->capture(metadata); 174 if (res != OK) { 175 ALOGE("%s: Camera %d: Got error %d after trying to set capture", 176 __FUNCTION__, mCameraId, res); 177 } 178 } 179 180 ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId); 181 if (res == OK) { 182 return requestId; 183 } 184 185 return res; 186} 187 188status_t CameraDeviceClient::cancelRequest(int requestId) { 189 ATRACE_CALL(); 190 ALOGV("%s, requestId = %d", __FUNCTION__, requestId); 191 192 status_t res; 193 194 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 195 196 Mutex::Autolock icl(mBinderSerializationLock); 197 198 if (!mDevice.get()) return DEAD_OBJECT; 199 200 Vector<int>::iterator it, end; 201 for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end(); 202 it != end; ++it) { 203 if (*it == requestId) { 204 break; 205 } 206 } 207 208 if (it == end) { 209 ALOGE("%s: Camera%d: Did not find request id %d in list of streaming " 210 "requests", __FUNCTION__, mCameraId, requestId); 211 return BAD_VALUE; 212 } 213 214 res = mDevice->clearStreamingRequest(); 215 216 if (res == OK) { 217 ALOGV("%s: Camera %d: Successfully cleared streaming request", 218 __FUNCTION__, mCameraId); 219 mStreamingRequestList.erase(it); 220 } 221 222 return res; 223} 224 225status_t CameraDeviceClient::deleteStream(int streamId) { 226 ATRACE_CALL(); 227 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId); 228 229 status_t res; 230 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 231 232 Mutex::Autolock icl(mBinderSerializationLock); 233 234 if (!mDevice.get()) return DEAD_OBJECT; 235 236 // Guard against trying to delete non-created streams 237 ssize_t index = NAME_NOT_FOUND; 238 for (size_t i = 0; i < mStreamMap.size(); ++i) { 239 if (streamId == mStreamMap.valueAt(i)) { 240 index = i; 241 break; 242 } 243 } 244 245 if (index == NAME_NOT_FOUND) { 246 ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream " 247 "created yet", __FUNCTION__, mCameraId, streamId); 248 return BAD_VALUE; 249 } 250 251 // Also returns BAD_VALUE if stream ID was not valid 252 res = mDevice->deleteStream(streamId); 253 254 if (res == BAD_VALUE) { 255 ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we" 256 " already checked and the stream ID (%d) should be valid.", 257 __FUNCTION__, mCameraId, streamId); 258 } else if (res == OK) { 259 mStreamMap.removeItemsAt(index); 260 261 ALOGV("%s: Camera %d: Successfully deleted stream ID (%d)", 262 __FUNCTION__, mCameraId, streamId); 263 } 264 265 return res; 266} 267 268status_t CameraDeviceClient::createStream(int width, int height, int format, 269 const sp<IGraphicBufferProducer>& bufferProducer) 270{ 271 ATRACE_CALL(); 272 ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format); 273 274 status_t res; 275 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 276 277 Mutex::Autolock icl(mBinderSerializationLock); 278 279 if (!mDevice.get()) return DEAD_OBJECT; 280 281 // Don't create multiple streams for the same target surface 282 { 283 ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder()); 284 if (index != NAME_NOT_FOUND) { 285 ALOGW("%s: Camera %d: Buffer producer already has a stream for it " 286 "(ID %d)", 287 __FUNCTION__, mCameraId, index); 288 return ALREADY_EXISTS; 289 } 290 } 291 292 // HACK b/10949105 293 // Query consumer usage bits to set async operation mode for 294 // GLConsumer using controlledByApp parameter. 295 bool useAsync = false; 296 int32_t consumerUsage; 297 if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, 298 &consumerUsage)) != OK) { 299 ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__, 300 mCameraId); 301 return res; 302 } 303 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) { 304 ALOGW("%s: Camera %d: Forcing asynchronous mode for stream", 305 __FUNCTION__, mCameraId); 306 useAsync = true; 307 } 308 309 sp<IBinder> binder; 310 sp<ANativeWindow> anw; 311 if (bufferProducer != 0) { 312 binder = bufferProducer->asBinder(); 313 anw = new Surface(bufferProducer, useAsync); 314 } 315 316 // TODO: remove w,h,f since we are ignoring them 317 318 if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) { 319 ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__, 320 mCameraId); 321 return res; 322 } 323 if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) { 324 ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__, 325 mCameraId); 326 return res; 327 } 328 if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) { 329 ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__, 330 mCameraId); 331 return res; 332 } 333 334 // FIXME: remove this override since the default format should be 335 // IMPLEMENTATION_DEFINED. b/9487482 336 if (format >= HAL_PIXEL_FORMAT_RGBA_8888 && 337 format <= HAL_PIXEL_FORMAT_BGRA_8888) { 338 ALOGW("%s: Camera %d: Overriding format 0x%x to IMPLEMENTATION_DEFINED", 339 __FUNCTION__, mCameraId, format); 340 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 341 } 342 343 // TODO: add startConfigure/stopConfigure call to CameraDeviceBase 344 // this will make it so Camera3Device doesn't call configure_streams 345 // after each call, but only once we are done with all. 346 347 int streamId = -1; 348 if (format == HAL_PIXEL_FORMAT_BLOB) { 349 // JPEG buffers need to be sized for maximum possible compressed size 350 CameraMetadata staticInfo = mDevice->info(); 351 camera_metadata_entry_t entry = staticInfo.find(ANDROID_JPEG_MAX_SIZE); 352 if (entry.count == 0) { 353 ALOGE("%s: Camera %d: Can't find maximum JPEG size in " 354 "static metadata!", __FUNCTION__, mCameraId); 355 return INVALID_OPERATION; 356 } 357 int32_t maxJpegSize = entry.data.i32[0]; 358 res = mDevice->createStream(anw, width, height, format, maxJpegSize, 359 &streamId); 360 } else { 361 // All other streams are a known size 362 res = mDevice->createStream(anw, width, height, format, /*size*/0, 363 &streamId); 364 } 365 366 if (res == OK) { 367 mStreamMap.add(bufferProducer->asBinder(), streamId); 368 369 ALOGV("%s: Camera %d: Successfully created a new stream ID %d", 370 __FUNCTION__, mCameraId, streamId); 371 372 /** 373 * Set the stream transform flags to automatically 374 * rotate the camera stream for preview use cases. 375 */ 376 int32_t transform = 0; 377 res = getRotationTransformLocked(&transform); 378 379 if (res != OK) { 380 // Error logged by getRotationTransformLocked. 381 return res; 382 } 383 384 res = mDevice->setStreamTransform(streamId, transform); 385 if (res != OK) { 386 ALOGE("%s: Failed to set stream transform (stream id %d)", 387 __FUNCTION__, streamId); 388 return res; 389 } 390 391 return streamId; 392 } 393 394 return res; 395} 396 397// Create a request object from a template. 398status_t CameraDeviceClient::createDefaultRequest(int templateId, 399 /*out*/ 400 CameraMetadata* request) 401{ 402 ATRACE_CALL(); 403 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId); 404 405 status_t res; 406 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 407 408 Mutex::Autolock icl(mBinderSerializationLock); 409 410 if (!mDevice.get()) return DEAD_OBJECT; 411 412 CameraMetadata metadata; 413 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK && 414 request != NULL) { 415 416 request->swap(metadata); 417 } 418 419 return res; 420} 421 422status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info) 423{ 424 ATRACE_CALL(); 425 ALOGV("%s", __FUNCTION__); 426 427 status_t res = OK; 428 429 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 430 431 Mutex::Autolock icl(mBinderSerializationLock); 432 433 if (!mDevice.get()) return DEAD_OBJECT; 434 435 if (info != NULL) { 436 *info = mDevice->info(); // static camera metadata 437 // TODO: merge with device-specific camera metadata 438 } 439 440 return res; 441} 442 443status_t CameraDeviceClient::waitUntilIdle() 444{ 445 ATRACE_CALL(); 446 ALOGV("%s", __FUNCTION__); 447 448 status_t res = OK; 449 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 450 451 Mutex::Autolock icl(mBinderSerializationLock); 452 453 if (!mDevice.get()) return DEAD_OBJECT; 454 455 // FIXME: Also need check repeating burst. 456 if (!mStreamingRequestList.isEmpty()) { 457 ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests", 458 __FUNCTION__, mCameraId); 459 return INVALID_OPERATION; 460 } 461 res = mDevice->waitUntilDrained(); 462 ALOGV("%s Done", __FUNCTION__); 463 464 return res; 465} 466 467status_t CameraDeviceClient::flush() { 468 ATRACE_CALL(); 469 ALOGV("%s", __FUNCTION__); 470 471 status_t res = OK; 472 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 473 474 Mutex::Autolock icl(mBinderSerializationLock); 475 476 if (!mDevice.get()) return DEAD_OBJECT; 477 478 return mDevice->flush(); 479} 480 481status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) { 482 String8 result; 483 result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n", 484 mCameraId, 485 getRemoteCallback()->asBinder().get(), 486 mClientPid); 487 result.append(" State: "); 488 489 // TODO: print dynamic/request section from most recent requests 490 mFrameProcessor->dump(fd, args); 491 492 return dumpDevice(fd, args); 493} 494 495 496void CameraDeviceClient::notifyError() { 497 // Thread safe. Don't bother locking. 498 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); 499 500 if (remoteCb != 0) { 501 remoteCb->onDeviceError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE); 502 } 503} 504 505void CameraDeviceClient::notifyIdle() { 506 // Thread safe. Don't bother locking. 507 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); 508 509 if (remoteCb != 0) { 510 remoteCb->onDeviceIdle(); 511 } 512} 513 514void CameraDeviceClient::notifyShutter(int requestId, 515 nsecs_t timestamp) { 516 // Thread safe. Don't bother locking. 517 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); 518 if (remoteCb != 0) { 519 remoteCb->onCaptureStarted(requestId, timestamp); 520 } 521} 522 523// TODO: refactor the code below this with IProCameraUser. 524// it's 100% copy-pasted, so lets not change it right now to make it easier. 525 526void CameraDeviceClient::detachDevice() { 527 if (mDevice == 0) return; 528 529 ALOGV("Camera %d: Stopping processors", mCameraId); 530 531 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID, 532 FRAME_PROCESSOR_LISTENER_MAX_ID, 533 /*listener*/this); 534 mFrameProcessor->requestExit(); 535 ALOGV("Camera %d: Waiting for threads", mCameraId); 536 mFrameProcessor->join(); 537 ALOGV("Camera %d: Disconnecting device", mCameraId); 538 539 // WORKAROUND: HAL refuses to disconnect while there's streams in flight 540 { 541 mDevice->clearStreamingRequest(); 542 543 status_t code; 544 if ((code = mDevice->waitUntilDrained()) != OK) { 545 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, 546 code); 547 } 548 } 549 550 Camera2ClientBase::detachDevice(); 551} 552 553/** Device-related methods */ 554void CameraDeviceClient::onFrameAvailable(int32_t requestId, 555 const CameraMetadata& frame) { 556 ATRACE_CALL(); 557 ALOGV("%s", __FUNCTION__); 558 559 // Thread-safe. No lock necessary. 560 sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback; 561 if (remoteCb != NULL) { 562 ALOGV("%s: frame = %p ", __FUNCTION__, &frame); 563 remoteCb->onResultReceived(requestId, frame); 564 } 565} 566 567// TODO: move to Camera2ClientBase 568bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) { 569 570 const int pid = IPCThreadState::self()->getCallingPid(); 571 const int selfPid = getpid(); 572 camera_metadata_entry_t entry; 573 574 /** 575 * Mixin default important security values 576 * - android.led.transmit = defaulted ON 577 */ 578 CameraMetadata staticInfo = mDevice->info(); 579 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS); 580 for(size_t i = 0; i < entry.count; ++i) { 581 uint8_t led = entry.data.u8[i]; 582 583 switch(led) { 584 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: { 585 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON; 586 if (!metadata.exists(ANDROID_LED_TRANSMIT)) { 587 metadata.update(ANDROID_LED_TRANSMIT, 588 &transmitDefault, 1); 589 } 590 break; 591 } 592 } 593 } 594 595 // We can do anything! 596 if (pid == selfPid) { 597 return true; 598 } 599 600 /** 601 * Permission check special fields in the request 602 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT 603 */ 604 entry = metadata.find(ANDROID_LED_TRANSMIT); 605 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) { 606 String16 permissionString = 607 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED"); 608 if (!checkCallingPermission(permissionString)) { 609 const int uid = IPCThreadState::self()->getCallingUid(); 610 ALOGE("Permission Denial: " 611 "can't disable transmit LED pid=%d, uid=%d", pid, uid); 612 return false; 613 } 614 } 615 616 return true; 617} 618 619status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) { 620 ALOGV("%s: begin", __FUNCTION__); 621 622 if (transform == NULL) { 623 ALOGW("%s: null transform", __FUNCTION__); 624 return BAD_VALUE; 625 } 626 627 *transform = 0; 628 629 const CameraMetadata& staticInfo = mDevice->info(); 630 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION); 631 if (entry.count == 0) { 632 ALOGE("%s: Camera %d: Can't find android.sensor.orientation in " 633 "static metadata!", __FUNCTION__, mCameraId); 634 return INVALID_OPERATION; 635 } 636 637 int32_t& flags = *transform; 638 639 int orientation = entry.data.i32[0]; 640 switch (orientation) { 641 case 0: 642 flags = 0; 643 break; 644 case 90: 645 flags = NATIVE_WINDOW_TRANSFORM_ROT_90; 646 break; 647 case 180: 648 flags = NATIVE_WINDOW_TRANSFORM_ROT_180; 649 break; 650 case 270: 651 flags = NATIVE_WINDOW_TRANSFORM_ROT_270; 652 break; 653 default: 654 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d", 655 __FUNCTION__, orientation); 656 return INVALID_OPERATION; 657 } 658 659 /** 660 * This magic flag makes surfaceflinger un-rotate the buffers 661 * to counter the extra global device UI rotation whenever the user 662 * physically rotates the device. 663 * 664 * By doing this, the camera buffer always ends up aligned 665 * with the physical camera for a "see through" effect. 666 * 667 * In essence, the buffer only gets rotated during preview use-cases. 668 * The user is still responsible to re-create streams of the proper 669 * aspect ratio, or the preview will end up looking non-uniformly 670 * stretched. 671 */ 672 flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; 673 674 ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags); 675 676 return OK; 677} 678 679} // namespace android 680