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