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, remoteCallback->asBinder(), clientPackageName,
46                 cameraId, cameraFacing, clientPid, clientUid, servicePid),
47     mRemoteCallback(remoteCallback) {
48 }
49 
50 // Interface used by CameraService
51 
CameraDeviceClient(const sp<CameraService> & cameraService,const sp<ICameraDeviceCallbacks> & remoteCallback,const String16 & clientPackageName,int cameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid)52 CameraDeviceClient::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 
initialize(camera_module_t * module)68 status_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 
~CameraDeviceClient()91 CameraDeviceClient::~CameraDeviceClient() {
92 }
93 
submitRequest(sp<CaptureRequest> request,bool streaming,int64_t * lastFrameNumber)94 status_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 
submitRequestList(List<sp<CaptureRequest>> requests,bool streaming,int64_t * lastFrameNumber)103 status_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 
cancelRequest(int requestId,int64_t * lastFrameNumber)213 status_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 
beginConfigure()250 status_t CameraDeviceClient::beginConfigure() {
251     // TODO: Implement this.
252     ALOGE("%s: Not implemented yet.", __FUNCTION__);
253     return OK;
254 }
255 
endConfigure()256 status_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 
deleteStream(int streamId)270 status_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 
createStream(int width,int height,int format,const sp<IGraphicBufferProducer> & bufferProducer)311 status_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 
roundBufferDimensionNearest(int32_t width,int32_t height,int32_t format,const CameraMetadata & info,int32_t * outWidth,int32_t * outHeight)441 bool 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 
euclidDistSquare(int32_t x0,int32_t y0,int32_t x1,int32_t y1)490 int64_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.
createDefaultRequest(int templateId,CameraMetadata * request)497 status_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 
getCameraInfo(CameraMetadata * info)521 status_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 
waitUntilIdle()542 status_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 
flush(int64_t * lastFrameNumber)566 status_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 
dump(int fd,const Vector<String16> & args)581 status_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 
notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,const CaptureResultExtras & resultExtras)607 void 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 
notifyIdle()617 void 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 
notifyShutter(const CaptureResultExtras & resultExtras,nsecs_t timestamp)626 void 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 
detachDevice()638 void 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 */
onResultAvailable(const CaptureResult & result)666 void 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
enforceRequestPermissions(CameraMetadata & metadata)678 bool 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 
getRotationTransformLocked(int32_t * transform)729 status_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