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