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