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
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
233status_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
270status_t CameraDeviceClient::beginConfigure() {
271    // TODO: Implement this.
272    ALOGV("%s: Not implemented yet.", __FUNCTION__);
273    return OK;
274}
275
276status_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
310status_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
360status_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
497status_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
534status_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
549bool 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
600int64_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.
607status_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
631status_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
652status_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
676status_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
691status_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
722status_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
754status_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
785void 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
795void 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
804void 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
813void 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
821void 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 */
849void 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
861bool 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
912status_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