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