CameraDeviceClient.cpp revision 125684aba1a11b7adbf5f9d607ee2bcc9449081c
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    // TODO: Hookup the stream set id with upper layer.
460    int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
461    res = mDevice->createStream(surface, width, height, format, dataSpace,
462                                static_cast<camera3_stream_rotation_t>
463                                        (outputConfiguration.getRotation()),
464                                &streamId);
465
466    if (res == OK) {
467        mStreamMap.add(binder, streamId);
468
469        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
470              __FUNCTION__, mCameraId, streamId);
471
472        /**
473         * Set the stream transform flags to automatically
474         * rotate the camera stream for preview use cases.
475         */
476        int32_t transform = 0;
477        res = getRotationTransformLocked(&transform);
478
479        if (res != OK) {
480            // Error logged by getRotationTransformLocked.
481            return res;
482        }
483
484        res = mDevice->setStreamTransform(streamId, transform);
485        if (res != OK) {
486            ALOGE("%s: Failed to set stream transform (stream id %d)",
487                  __FUNCTION__, streamId);
488            return res;
489        }
490
491        return streamId;
492    }
493
494    return res;
495}
496
497
498status_t CameraDeviceClient::createInputStream(int width, int height,
499        int format) {
500
501    ATRACE_CALL();
502    ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
503
504    status_t res;
505    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
506
507    Mutex::Autolock icl(mBinderSerializationLock);
508    if (!mDevice.get()) return DEAD_OBJECT;
509
510    if (mInputStream.configured) {
511        ALOGE("%s: Camera %d: Already has an input stream "
512                " configuration. (ID %zd)", __FUNCTION__, mCameraId,
513                mInputStream.id);
514        return ALREADY_EXISTS;
515    }
516
517    int streamId = -1;
518    res = mDevice->createInputStream(width, height, format, &streamId);
519    if (res == OK) {
520        mInputStream.configured = true;
521        mInputStream.width = width;
522        mInputStream.height = height;
523        mInputStream.format = format;
524        mInputStream.id = streamId;
525
526        ALOGV("%s: Camera %d: Successfully created a new input stream ID %d",
527              __FUNCTION__, mCameraId, streamId);
528
529        return streamId;
530    }
531
532    return res;
533}
534
535status_t CameraDeviceClient::getInputBufferProducer(
536        /*out*/sp<IGraphicBufferProducer> *producer) {
537    status_t res;
538    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
539
540    if (producer == NULL) {
541        return BAD_VALUE;
542    }
543
544    Mutex::Autolock icl(mBinderSerializationLock);
545    if (!mDevice.get()) return DEAD_OBJECT;
546
547    return mDevice->getInputBufferProducer(producer);
548}
549
550bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
551        int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
552        /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
553
554    camera_metadata_ro_entry streamConfigs =
555            (dataSpace == HAL_DATASPACE_DEPTH) ?
556            info.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS) :
557            info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
558
559    int32_t bestWidth = -1;
560    int32_t bestHeight = -1;
561
562    // Iterate through listed stream configurations and find the one with the smallest euclidean
563    // distance from the given dimensions for the given format.
564    for (size_t i = 0; i < streamConfigs.count; i += 4) {
565        int32_t fmt = streamConfigs.data.i32[i];
566        int32_t w = streamConfigs.data.i32[i + 1];
567        int32_t h = streamConfigs.data.i32[i + 2];
568
569        // Ignore input/output type for now
570        if (fmt == format) {
571            if (w == width && h == height) {
572                bestWidth = width;
573                bestHeight = height;
574                break;
575            } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
576                    CameraDeviceClient::euclidDistSquare(w, h, width, height) <
577                    CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) {
578                bestWidth = w;
579                bestHeight = h;
580            }
581        }
582    }
583
584    if (bestWidth == -1) {
585        // Return false if no configurations for this format were listed
586        return false;
587    }
588
589    // Set the outputs to the closet width/height
590    if (outWidth != NULL) {
591        *outWidth = bestWidth;
592    }
593    if (outHeight != NULL) {
594        *outHeight = bestHeight;
595    }
596
597    // Return true if at least one configuration for this format was listed
598    return true;
599}
600
601int64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
602    int64_t d0 = x0 - x1;
603    int64_t d1 = y0 - y1;
604    return d0 * d0 + d1 * d1;
605}
606
607// Create a request object from a template.
608status_t CameraDeviceClient::createDefaultRequest(int templateId,
609                                                  /*out*/
610                                                  CameraMetadata* request)
611{
612    ATRACE_CALL();
613    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
614
615    status_t res;
616    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
617
618    Mutex::Autolock icl(mBinderSerializationLock);
619
620    if (!mDevice.get()) return DEAD_OBJECT;
621
622    CameraMetadata metadata;
623    if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
624        request != NULL) {
625
626        request->swap(metadata);
627    }
628
629    return res;
630}
631
632status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
633{
634    ATRACE_CALL();
635    ALOGV("%s", __FUNCTION__);
636
637    status_t res = OK;
638
639    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
640
641    Mutex::Autolock icl(mBinderSerializationLock);
642
643    if (!mDevice.get()) return DEAD_OBJECT;
644
645    if (info != NULL) {
646        *info = mDevice->info(); // static camera metadata
647        // TODO: merge with device-specific camera metadata
648    }
649
650    return res;
651}
652
653status_t CameraDeviceClient::waitUntilIdle()
654{
655    ATRACE_CALL();
656    ALOGV("%s", __FUNCTION__);
657
658    status_t res = OK;
659    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
660
661    Mutex::Autolock icl(mBinderSerializationLock);
662
663    if (!mDevice.get()) return DEAD_OBJECT;
664
665    // FIXME: Also need check repeating burst.
666    if (!mStreamingRequestList.isEmpty()) {
667        ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
668              __FUNCTION__, mCameraId);
669        return INVALID_OPERATION;
670    }
671    res = mDevice->waitUntilDrained();
672    ALOGV("%s Done", __FUNCTION__);
673
674    return res;
675}
676
677status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) {
678    ATRACE_CALL();
679    ALOGV("%s", __FUNCTION__);
680
681    status_t res = OK;
682    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
683
684    Mutex::Autolock icl(mBinderSerializationLock);
685
686    if (!mDevice.get()) return DEAD_OBJECT;
687
688    mStreamingRequestList.clear();
689    return mDevice->flush(lastFrameNumber);
690}
691
692status_t CameraDeviceClient::prepare(int streamId) {
693    ATRACE_CALL();
694    ALOGV("%s", __FUNCTION__);
695
696    status_t res = OK;
697    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
698
699    Mutex::Autolock icl(mBinderSerializationLock);
700
701    // Guard against trying to prepare non-created streams
702    ssize_t index = NAME_NOT_FOUND;
703    for (size_t i = 0; i < mStreamMap.size(); ++i) {
704        if (streamId == mStreamMap.valueAt(i)) {
705            index = i;
706            break;
707        }
708    }
709
710    if (index == NAME_NOT_FOUND) {
711        ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
712              "created yet", __FUNCTION__, mCameraId, streamId);
713        return BAD_VALUE;
714    }
715
716    // Also returns BAD_VALUE if stream ID was not valid, or stream already
717    // has been used
718    res = mDevice->prepare(streamId);
719
720    return res;
721}
722
723status_t CameraDeviceClient::prepare2(int maxCount, int streamId) {
724    ATRACE_CALL();
725    ALOGV("%s", __FUNCTION__);
726
727    status_t res = OK;
728    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
729
730    Mutex::Autolock icl(mBinderSerializationLock);
731
732    // Guard against trying to prepare non-created streams
733    ssize_t index = NAME_NOT_FOUND;
734    for (size_t i = 0; i < mStreamMap.size(); ++i) {
735        if (streamId == mStreamMap.valueAt(i)) {
736            index = i;
737            break;
738        }
739    }
740
741    if (index == NAME_NOT_FOUND) {
742        ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream created yet",
743                __FUNCTION__, mCameraId, streamId);
744        return BAD_VALUE;
745    }
746
747    if (maxCount <= 0) {
748        ALOGE("%s: Camera %d: Invalid maxCount (%d) specified, must be greater than 0.",
749                __FUNCTION__, mCameraId, maxCount);
750        return BAD_VALUE;
751    }
752
753    // Also returns BAD_VALUE if stream ID was not valid, or stream already
754    // has been used
755    res = mDevice->prepare(maxCount, streamId);
756
757    return res;
758}
759
760status_t CameraDeviceClient::tearDown(int streamId) {
761    ATRACE_CALL();
762    ALOGV("%s", __FUNCTION__);
763
764    status_t res = OK;
765    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
766
767    Mutex::Autolock icl(mBinderSerializationLock);
768
769    // Guard against trying to prepare non-created streams
770    ssize_t index = NAME_NOT_FOUND;
771    for (size_t i = 0; i < mStreamMap.size(); ++i) {
772        if (streamId == mStreamMap.valueAt(i)) {
773            index = i;
774            break;
775        }
776    }
777
778    if (index == NAME_NOT_FOUND) {
779        ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
780              "created yet", __FUNCTION__, mCameraId, streamId);
781        return BAD_VALUE;
782    }
783
784    // Also returns BAD_VALUE if stream ID was not valid or if the stream is in
785    // use
786    res = mDevice->tearDown(streamId);
787
788    return res;
789}
790
791status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
792    return BasicClient::dump(fd, args);
793}
794
795status_t CameraDeviceClient::dumpClient(int fd, const Vector<String16>& args) {
796    String8 result;
797    result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n",
798            mCameraId,
799            (getRemoteCallback() != NULL ?
800                    IInterface::asBinder(getRemoteCallback()).get() : NULL) );
801    result.appendFormat("  Current client UID %u\n", mClientUid);
802
803    result.append("  State:\n");
804    result.appendFormat("    Request ID counter: %d\n", mRequestIdCounter);
805    if (mInputStream.configured) {
806        result.appendFormat("    Current input stream ID: %d\n",
807                    mInputStream.id);
808    } else {
809        result.append("    No input stream configured.\n");
810    }
811    if (!mStreamMap.isEmpty()) {
812        result.append("    Current output stream IDs:\n");
813        for (size_t i = 0; i < mStreamMap.size(); i++) {
814            result.appendFormat("      Stream %d\n", mStreamMap.valueAt(i));
815        }
816    } else {
817        result.append("    No output streams configured.\n");
818    }
819    write(fd, result.string(), result.size());
820    // TODO: print dynamic/request section from most recent requests
821    mFrameProcessor->dump(fd, args);
822
823    return dumpDevice(fd, args);
824}
825
826void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
827                                     const CaptureResultExtras& resultExtras) {
828    // Thread safe. Don't bother locking.
829    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
830
831    if (remoteCb != 0) {
832        remoteCb->onDeviceError(errorCode, resultExtras);
833    }
834}
835
836void CameraDeviceClient::notifyIdle() {
837    // Thread safe. Don't bother locking.
838    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
839
840    if (remoteCb != 0) {
841        remoteCb->onDeviceIdle();
842    }
843    Camera2ClientBase::notifyIdle();
844}
845
846void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
847        nsecs_t timestamp) {
848    // Thread safe. Don't bother locking.
849    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
850    if (remoteCb != 0) {
851        remoteCb->onCaptureStarted(resultExtras, timestamp);
852    }
853    Camera2ClientBase::notifyShutter(resultExtras, timestamp);
854}
855
856void CameraDeviceClient::notifyPrepared(int streamId) {
857    // Thread safe. Don't bother locking.
858    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
859    if (remoteCb != 0) {
860        remoteCb->onPrepared(streamId);
861    }
862}
863
864void CameraDeviceClient::detachDevice() {
865    if (mDevice == 0) return;
866
867    ALOGV("Camera %d: Stopping processors", mCameraId);
868
869    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
870                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
871                                    /*listener*/this);
872    mFrameProcessor->requestExit();
873    ALOGV("Camera %d: Waiting for threads", mCameraId);
874    mFrameProcessor->join();
875    ALOGV("Camera %d: Disconnecting device", mCameraId);
876
877    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
878    {
879        mDevice->clearStreamingRequest();
880
881        status_t code;
882        if ((code = mDevice->waitUntilDrained()) != OK) {
883            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
884                  code);
885        }
886    }
887
888    Camera2ClientBase::detachDevice();
889}
890
891/** Device-related methods */
892void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
893    ATRACE_CALL();
894    ALOGV("%s", __FUNCTION__);
895
896    // Thread-safe. No lock necessary.
897    sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
898    if (remoteCb != NULL) {
899        remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
900    }
901}
902
903// TODO: move to Camera2ClientBase
904bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
905
906    const int pid = IPCThreadState::self()->getCallingPid();
907    const int selfPid = getpid();
908    camera_metadata_entry_t entry;
909
910    /**
911     * Mixin default important security values
912     * - android.led.transmit = defaulted ON
913     */
914    CameraMetadata staticInfo = mDevice->info();
915    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
916    for(size_t i = 0; i < entry.count; ++i) {
917        uint8_t led = entry.data.u8[i];
918
919        switch(led) {
920            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
921                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
922                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
923                    metadata.update(ANDROID_LED_TRANSMIT,
924                                    &transmitDefault, 1);
925                }
926                break;
927            }
928        }
929    }
930
931    // We can do anything!
932    if (pid == selfPid) {
933        return true;
934    }
935
936    /**
937     * Permission check special fields in the request
938     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
939     */
940    entry = metadata.find(ANDROID_LED_TRANSMIT);
941    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
942        String16 permissionString =
943            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
944        if (!checkCallingPermission(permissionString)) {
945            const int uid = IPCThreadState::self()->getCallingUid();
946            ALOGE("Permission Denial: "
947                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
948            return false;
949        }
950    }
951
952    return true;
953}
954
955status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
956    ALOGV("%s: begin", __FUNCTION__);
957
958    const CameraMetadata& staticInfo = mDevice->info();
959    return CameraUtils::getRotationTransform(staticInfo, transform);
960}
961
962} // namespace android
963