CameraDeviceClient.cpp revision 9efdf956cc2eef63fef609375901d6c8df6351b6
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#include <camera/CameraUtils.h> 27 28#include "common/CameraDeviceBase.h" 29#include "api2/CameraDeviceClient.h" 30 31 32 33namespace android { 34using namespace camera2; 35 36CameraDeviceClientBase::CameraDeviceClientBase( 37 const sp<CameraService>& cameraService, 38 const sp<ICameraDeviceCallbacks>& remoteCallback, 39 const String16& clientPackageName, 40 int cameraId, 41 int cameraFacing, 42 int clientPid, 43 uid_t clientUid, 44 int servicePid) : 45 BasicClient(cameraService, 46 IInterface::asBinder(remoteCallback), 47 clientPackageName, 48 cameraId, 49 cameraFacing, 50 clientPid, 51 clientUid, 52 servicePid), 53 mRemoteCallback(remoteCallback) { 54} 55 56// Interface used by CameraService 57 58CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService, 59 const sp<ICameraDeviceCallbacks>& remoteCallback, 60 const String16& clientPackageName, 61 int cameraId, 62 int cameraFacing, 63 int clientPid, 64 uid_t clientUid, 65 int servicePid) : 66 Camera2ClientBase(cameraService, remoteCallback, clientPackageName, 67 cameraId, cameraFacing, clientPid, clientUid, servicePid), 68 mRequestIdCounter(0) { 69 70 ATRACE_CALL(); 71 ALOGI("CameraDeviceClient %d: Opened", cameraId); 72} 73 74status_t CameraDeviceClient::initialize(CameraModule *module) 75{ 76 ATRACE_CALL(); 77 status_t res; 78 79 res = Camera2ClientBase::initialize(module); 80 if (res != OK) { 81 return res; 82 } 83 84 String8 threadName; 85 mFrameProcessor = new FrameProcessorBase(mDevice); 86 threadName = String8::format("CDU-%d-FrameProc", mCameraId); 87 mFrameProcessor->run(threadName.string()); 88 89 mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID, 90 FRAME_PROCESSOR_LISTENER_MAX_ID, 91 /*listener*/this, 92 /*sendPartials*/true); 93 94 return OK; 95} 96 97CameraDeviceClient::~CameraDeviceClient() { 98} 99 100status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request, 101 bool streaming, 102 /*out*/ 103 int64_t* lastFrameNumber) { 104 List<sp<CaptureRequest> > requestList; 105 requestList.push_back(request); 106 return submitRequestList(requestList, streaming, lastFrameNumber); 107} 108 109status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests, 110 bool streaming, int64_t* lastFrameNumber) { 111 ATRACE_CALL(); 112 ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size()); 113 114 status_t res; 115 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 116 117 Mutex::Autolock icl(mBinderSerializationLock); 118 119 if (!mDevice.get()) return DEAD_OBJECT; 120 121 if (requests.empty()) { 122 ALOGE("%s: Camera %d: Sent null request. Rejecting request.", 123 __FUNCTION__, mCameraId); 124 return BAD_VALUE; 125 } 126 127 List<const CameraMetadata> metadataRequestList; 128 int32_t requestId = mRequestIdCounter; 129 uint32_t loopCounter = 0; 130 131 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) { 132 sp<CaptureRequest> request = *it; 133 if (request == 0) { 134 ALOGE("%s: Camera %d: Sent null request.", 135 __FUNCTION__, mCameraId); 136 return BAD_VALUE; 137 } 138 139 CameraMetadata metadata(request->mMetadata); 140 if (metadata.isEmpty()) { 141 ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.", 142 __FUNCTION__, mCameraId); 143 return BAD_VALUE; 144 } else if (request->mSurfaceList.isEmpty()) { 145 ALOGE("%s: Camera %d: Requests must have at least one surface target. " 146 "Rejecting request.", __FUNCTION__, mCameraId); 147 return BAD_VALUE; 148 } 149 150 if (!enforceRequestPermissions(metadata)) { 151 // Callee logs 152 return PERMISSION_DENIED; 153 } 154 155 /** 156 * Write in the output stream IDs which we calculate from 157 * the capture request's list of surface targets 158 */ 159 Vector<int32_t> outputStreamIds; 160 outputStreamIds.setCapacity(request->mSurfaceList.size()); 161 for (size_t i = 0; i < request->mSurfaceList.size(); ++i) { 162 sp<Surface> surface = request->mSurfaceList[i]; 163 if (surface == 0) continue; 164 165 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer(); 166 int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp)); 167 168 // Trying to submit request with surface that wasn't created 169 if (idx == NAME_NOT_FOUND) { 170 ALOGE("%s: Camera %d: Tried to submit a request with a surface that" 171 " we have not called createStream on", 172 __FUNCTION__, mCameraId); 173 return BAD_VALUE; 174 } 175 176 int streamId = mStreamMap.valueAt(idx); 177 outputStreamIds.push_back(streamId); 178 ALOGV("%s: Camera %d: Appending output stream %d to request", 179 __FUNCTION__, mCameraId, streamId); 180 } 181 182 metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0], 183 outputStreamIds.size()); 184 185 metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1); 186 loopCounter++; // loopCounter starts from 1 187 ALOGV("%s: Camera %d: Creating request with ID %d (%d of %zu)", 188 __FUNCTION__, mCameraId, requestId, loopCounter, requests.size()); 189 190 metadataRequestList.push_back(metadata); 191 } 192 mRequestIdCounter++; 193 194 if (streaming) { 195 res = mDevice->setStreamingRequestList(metadataRequestList, lastFrameNumber); 196 if (res != OK) { 197 ALOGE("%s: Camera %d: Got error %d after trying to set streaming " 198 "request", __FUNCTION__, mCameraId, res); 199 } else { 200 mStreamingRequestList.push_back(requestId); 201 } 202 } else { 203 res = mDevice->captureList(metadataRequestList, lastFrameNumber); 204 if (res != OK) { 205 ALOGE("%s: Camera %d: Got error %d after trying to set capture", 206 __FUNCTION__, mCameraId, res); 207 } 208 ALOGV("%s: requestId = %d ", __FUNCTION__, requestId); 209 } 210 211 ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId); 212 if (res == OK) { 213 return requestId; 214 } 215 216 return res; 217} 218 219status_t CameraDeviceClient::cancelRequest(int requestId, int64_t* lastFrameNumber) { 220 ATRACE_CALL(); 221 ALOGV("%s, requestId = %d", __FUNCTION__, requestId); 222 223 status_t res; 224 225 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 226 227 Mutex::Autolock icl(mBinderSerializationLock); 228 229 if (!mDevice.get()) return DEAD_OBJECT; 230 231 Vector<int>::iterator it, end; 232 for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end(); 233 it != end; ++it) { 234 if (*it == requestId) { 235 break; 236 } 237 } 238 239 if (it == end) { 240 ALOGE("%s: Camera%d: Did not find request id %d in list of streaming " 241 "requests", __FUNCTION__, mCameraId, requestId); 242 return BAD_VALUE; 243 } 244 245 res = mDevice->clearStreamingRequest(lastFrameNumber); 246 247 if (res == OK) { 248 ALOGV("%s: Camera %d: Successfully cleared streaming request", 249 __FUNCTION__, mCameraId); 250 mStreamingRequestList.erase(it); 251 } 252 253 return res; 254} 255 256status_t CameraDeviceClient::beginConfigure() { 257 // TODO: Implement this. 258 ALOGE("%s: Not implemented yet.", __FUNCTION__); 259 return OK; 260} 261 262status_t CameraDeviceClient::endConfigure() { 263 ALOGV("%s: ending configure (%zu streams)", 264 __FUNCTION__, mStreamMap.size()); 265 266 status_t res; 267 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 268 269 Mutex::Autolock icl(mBinderSerializationLock); 270 271 if (!mDevice.get()) return DEAD_OBJECT; 272 273 return mDevice->configureStreams(); 274} 275 276status_t CameraDeviceClient::deleteStream(int streamId) { 277 ATRACE_CALL(); 278 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId); 279 280 status_t res; 281 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 282 283 Mutex::Autolock icl(mBinderSerializationLock); 284 285 if (!mDevice.get()) return DEAD_OBJECT; 286 287 // Guard against trying to delete non-created streams 288 ssize_t index = NAME_NOT_FOUND; 289 for (size_t i = 0; i < mStreamMap.size(); ++i) { 290 if (streamId == mStreamMap.valueAt(i)) { 291 index = i; 292 break; 293 } 294 } 295 296 if (index == NAME_NOT_FOUND) { 297 ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream " 298 "created yet", __FUNCTION__, mCameraId, streamId); 299 return BAD_VALUE; 300 } 301 302 // Also returns BAD_VALUE if stream ID was not valid 303 res = mDevice->deleteStream(streamId); 304 305 if (res == BAD_VALUE) { 306 ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we" 307 " already checked and the stream ID (%d) should be valid.", 308 __FUNCTION__, mCameraId, streamId); 309 } else if (res == OK) { 310 mStreamMap.removeItemsAt(index); 311 312 } 313 314 return res; 315} 316 317status_t CameraDeviceClient::createStream(const OutputConfiguration &outputConfiguration) 318{ 319 ATRACE_CALL(); 320 321 status_t res; 322 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 323 324 Mutex::Autolock icl(mBinderSerializationLock); 325 326 327 sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer(); 328 if (bufferProducer == NULL) { 329 ALOGE("%s: bufferProducer must not be null", __FUNCTION__); 330 return BAD_VALUE; 331 } 332 if (!mDevice.get()) return DEAD_OBJECT; 333 334 // Don't create multiple streams for the same target surface 335 { 336 ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer)); 337 if (index != NAME_NOT_FOUND) { 338 ALOGW("%s: Camera %d: Buffer producer already has a stream for it " 339 "(ID %zd)", 340 __FUNCTION__, mCameraId, index); 341 return ALREADY_EXISTS; 342 } 343 } 344 345 // HACK b/10949105 346 // Query consumer usage bits to set async operation mode for 347 // GLConsumer using controlledByApp parameter. 348 bool useAsync = false; 349 int32_t consumerUsage; 350 if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, 351 &consumerUsage)) != OK) { 352 ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__, 353 mCameraId); 354 return res; 355 } 356 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) { 357 ALOGW("%s: Camera %d: Forcing asynchronous mode for stream", 358 __FUNCTION__, mCameraId); 359 useAsync = true; 360 } 361 362 int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER | 363 GRALLOC_USAGE_RENDERSCRIPT; 364 int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK | 365 GraphicBuffer::USAGE_HW_TEXTURE | 366 GraphicBuffer::USAGE_HW_COMPOSER; 367 bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 && 368 (consumerUsage & allowedFlags) != 0; 369 370 sp<IBinder> binder = IInterface::asBinder(bufferProducer); 371 sp<ANativeWindow> anw = new Surface(bufferProducer, useAsync); 372 373 int width, height, format; 374 android_dataspace dataSpace; 375 376 if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) { 377 ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__, 378 mCameraId); 379 return res; 380 } 381 if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) { 382 ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__, 383 mCameraId); 384 return res; 385 } 386 if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) { 387 ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__, 388 mCameraId); 389 return res; 390 } 391 if ((res = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, 392 reinterpret_cast<int*>(&dataSpace))) != OK) { 393 ALOGE("%s: Camera %d: Failed to query Surface dataSpace", __FUNCTION__, 394 mCameraId); 395 return res; 396 } 397 398 // FIXME: remove this override since the default format should be 399 // IMPLEMENTATION_DEFINED. b/9487482 400 if (format >= HAL_PIXEL_FORMAT_RGBA_8888 && 401 format <= HAL_PIXEL_FORMAT_BGRA_8888) { 402 ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED", 403 __FUNCTION__, mCameraId, format); 404 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 405 } 406 407 // Round dimensions to the nearest dimensions available for this format 408 if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height, 409 format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) { 410 ALOGE("%s: No stream configurations with the format %#x defined, failed to create stream.", 411 __FUNCTION__, format); 412 return BAD_VALUE; 413 } 414 415 int streamId = -1; 416 res = mDevice->createStream(anw, width, height, format, dataSpace, 417 static_cast<camera3_stream_rotation_t> 418 (outputConfiguration.getRotation()), 419 &streamId); 420 421 if (res == OK) { 422 mStreamMap.add(binder, streamId); 423 424 ALOGV("%s: Camera %d: Successfully created a new stream ID %d", 425 __FUNCTION__, mCameraId, streamId); 426 427 /** 428 * Set the stream transform flags to automatically 429 * rotate the camera stream for preview use cases. 430 */ 431 int32_t transform = 0; 432 res = getRotationTransformLocked(&transform); 433 434 if (res != OK) { 435 // Error logged by getRotationTransformLocked. 436 return res; 437 } 438 439 res = mDevice->setStreamTransform(streamId, transform); 440 if (res != OK) { 441 ALOGE("%s: Failed to set stream transform (stream id %d)", 442 __FUNCTION__, streamId); 443 return res; 444 } 445 446 return streamId; 447 } 448 449 return res; 450} 451 452 453bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height, 454 int32_t format, android_dataspace dataSpace, const CameraMetadata& info, 455 /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) { 456 457 camera_metadata_ro_entry streamConfigs = 458 (dataSpace == HAL_DATASPACE_DEPTH) ? 459 info.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS) : 460 info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); 461 462 int32_t bestWidth = -1; 463 int32_t bestHeight = -1; 464 465 // Iterate through listed stream configurations and find the one with the smallest euclidean 466 // distance from the given dimensions for the given format. 467 for (size_t i = 0; i < streamConfigs.count; i += 4) { 468 int32_t fmt = streamConfigs.data.i32[i]; 469 int32_t w = streamConfigs.data.i32[i + 1]; 470 int32_t h = streamConfigs.data.i32[i + 2]; 471 472 // Ignore input/output type for now 473 if (fmt == format) { 474 if (w == width && h == height) { 475 bestWidth = width; 476 bestHeight = height; 477 break; 478 } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 || 479 CameraDeviceClient::euclidDistSquare(w, h, width, height) < 480 CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) { 481 bestWidth = w; 482 bestHeight = h; 483 } 484 } 485 } 486 487 if (bestWidth == -1) { 488 // Return false if no configurations for this format were listed 489 return false; 490 } 491 492 // Set the outputs to the closet width/height 493 if (outWidth != NULL) { 494 *outWidth = bestWidth; 495 } 496 if (outHeight != NULL) { 497 *outHeight = bestHeight; 498 } 499 500 // Return true if at least one configuration for this format was listed 501 return true; 502} 503 504int64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) { 505 int64_t d0 = x0 - x1; 506 int64_t d1 = y0 - y1; 507 return d0 * d0 + d1 * d1; 508} 509 510// Create a request object from a template. 511status_t CameraDeviceClient::createDefaultRequest(int templateId, 512 /*out*/ 513 CameraMetadata* request) 514{ 515 ATRACE_CALL(); 516 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId); 517 518 status_t res; 519 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 520 521 Mutex::Autolock icl(mBinderSerializationLock); 522 523 if (!mDevice.get()) return DEAD_OBJECT; 524 525 CameraMetadata metadata; 526 if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK && 527 request != NULL) { 528 529 request->swap(metadata); 530 } 531 532 return res; 533} 534 535status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info) 536{ 537 ATRACE_CALL(); 538 ALOGV("%s", __FUNCTION__); 539 540 status_t res = OK; 541 542 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 543 544 Mutex::Autolock icl(mBinderSerializationLock); 545 546 if (!mDevice.get()) return DEAD_OBJECT; 547 548 if (info != NULL) { 549 *info = mDevice->info(); // static camera metadata 550 // TODO: merge with device-specific camera metadata 551 } 552 553 return res; 554} 555 556status_t CameraDeviceClient::waitUntilIdle() 557{ 558 ATRACE_CALL(); 559 ALOGV("%s", __FUNCTION__); 560 561 status_t res = OK; 562 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 563 564 Mutex::Autolock icl(mBinderSerializationLock); 565 566 if (!mDevice.get()) return DEAD_OBJECT; 567 568 // FIXME: Also need check repeating burst. 569 if (!mStreamingRequestList.isEmpty()) { 570 ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests", 571 __FUNCTION__, mCameraId); 572 return INVALID_OPERATION; 573 } 574 res = mDevice->waitUntilDrained(); 575 ALOGV("%s Done", __FUNCTION__); 576 577 return res; 578} 579 580status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) { 581 ATRACE_CALL(); 582 ALOGV("%s", __FUNCTION__); 583 584 status_t res = OK; 585 if ( (res = checkPid(__FUNCTION__) ) != OK) return res; 586 587 Mutex::Autolock icl(mBinderSerializationLock); 588 589 if (!mDevice.get()) return DEAD_OBJECT; 590 591 mStreamingRequestList.clear(); 592 return mDevice->flush(lastFrameNumber); 593} 594 595status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) { 596 String8 result; 597 result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n", 598 mCameraId, 599 (getRemoteCallback() != NULL ? 600 IInterface::asBinder(getRemoteCallback()).get() : NULL) ); 601 result.appendFormat(" Current client UID %u\n", mClientUid); 602 603 result.append(" State:\n"); 604 result.appendFormat(" Request ID counter: %d\n", mRequestIdCounter); 605 if (!mStreamMap.isEmpty()) { 606 result.append(" Current stream IDs:\n"); 607 for (size_t i = 0; i < mStreamMap.size(); i++) { 608 result.appendFormat(" Stream %d\n", mStreamMap.valueAt(i)); 609 } 610 } else { 611 result.append(" No streams configured.\n"); 612 } 613 write(fd, result.string(), result.size()); 614 // TODO: print dynamic/request section from most recent requests 615 mFrameProcessor->dump(fd, args); 616 617 return dumpDevice(fd, args); 618} 619 620void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, 621 const CaptureResultExtras& resultExtras) { 622 // Thread safe. Don't bother locking. 623 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); 624 625 if (remoteCb != 0) { 626 remoteCb->onDeviceError(errorCode, resultExtras); 627 } 628} 629 630void CameraDeviceClient::notifyIdle() { 631 // Thread safe. Don't bother locking. 632 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); 633 634 if (remoteCb != 0) { 635 remoteCb->onDeviceIdle(); 636 } 637} 638 639void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras, 640 nsecs_t timestamp) { 641 // Thread safe. Don't bother locking. 642 sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); 643 if (remoteCb != 0) { 644 remoteCb->onCaptureStarted(resultExtras, timestamp); 645 } 646} 647 648void CameraDeviceClient::detachDevice() { 649 if (mDevice == 0) return; 650 651 ALOGV("Camera %d: Stopping processors", mCameraId); 652 653 mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID, 654 FRAME_PROCESSOR_LISTENER_MAX_ID, 655 /*listener*/this); 656 mFrameProcessor->requestExit(); 657 ALOGV("Camera %d: Waiting for threads", mCameraId); 658 mFrameProcessor->join(); 659 ALOGV("Camera %d: Disconnecting device", mCameraId); 660 661 // WORKAROUND: HAL refuses to disconnect while there's streams in flight 662 { 663 mDevice->clearStreamingRequest(); 664 665 status_t code; 666 if ((code = mDevice->waitUntilDrained()) != OK) { 667 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, 668 code); 669 } 670 } 671 672 Camera2ClientBase::detachDevice(); 673} 674 675/** Device-related methods */ 676void CameraDeviceClient::onResultAvailable(const CaptureResult& result) { 677 ATRACE_CALL(); 678 ALOGV("%s", __FUNCTION__); 679 680 // Thread-safe. No lock necessary. 681 sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback; 682 if (remoteCb != NULL) { 683 remoteCb->onResultReceived(result.mMetadata, result.mResultExtras); 684 } 685} 686 687// TODO: move to Camera2ClientBase 688bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) { 689 690 const int pid = IPCThreadState::self()->getCallingPid(); 691 const int selfPid = getpid(); 692 camera_metadata_entry_t entry; 693 694 /** 695 * Mixin default important security values 696 * - android.led.transmit = defaulted ON 697 */ 698 CameraMetadata staticInfo = mDevice->info(); 699 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS); 700 for(size_t i = 0; i < entry.count; ++i) { 701 uint8_t led = entry.data.u8[i]; 702 703 switch(led) { 704 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: { 705 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON; 706 if (!metadata.exists(ANDROID_LED_TRANSMIT)) { 707 metadata.update(ANDROID_LED_TRANSMIT, 708 &transmitDefault, 1); 709 } 710 break; 711 } 712 } 713 } 714 715 // We can do anything! 716 if (pid == selfPid) { 717 return true; 718 } 719 720 /** 721 * Permission check special fields in the request 722 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT 723 */ 724 entry = metadata.find(ANDROID_LED_TRANSMIT); 725 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) { 726 String16 permissionString = 727 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED"); 728 if (!checkCallingPermission(permissionString)) { 729 const int uid = IPCThreadState::self()->getCallingUid(); 730 ALOGE("Permission Denial: " 731 "can't disable transmit LED pid=%d, uid=%d", pid, uid); 732 return false; 733 } 734 } 735 736 return true; 737} 738 739status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) { 740 ALOGV("%s: begin", __FUNCTION__); 741 742 const CameraMetadata& staticInfo = mDevice->info(); 743 return CameraUtils::getRotationTransform(staticInfo, transform); 744} 745 746} // namespace android 747