CameraDeviceClient.cpp revision d56db1d2bee182d1851097a9c712712fc094d117
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// Convenience methods for constructing binder::Status objects for error returns
32
33#define STRINGIZE_IMPL(x) #x
34#define STRINGIZE(x) STRINGIZE_IMPL(x)
35
36#define STATUS_ERROR(errorCode, errorString) \
37    binder::Status::fromServiceSpecificError(errorCode, \
38            String8(STRINGIZE(__FUNCTION__) ":" STRINGIZE(__LINE__) ":" # errorString))
39
40#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
41    binder::Status::fromServiceSpecificError(errorCode, \
42            String8::format(STRINGIZE(__FUNCTION__) ":" STRINGIZE(__LINE__) ":" # errorString, \
43                    __VA_ARGS__))
44
45namespace android {
46using namespace camera2;
47
48CameraDeviceClientBase::CameraDeviceClientBase(
49        const sp<CameraService>& cameraService,
50        const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
51        const String16& clientPackageName,
52        int cameraId,
53        int cameraFacing,
54        int clientPid,
55        uid_t clientUid,
56        int servicePid) :
57    BasicClient(cameraService,
58            IInterface::asBinder(remoteCallback),
59            clientPackageName,
60            cameraId,
61            cameraFacing,
62            clientPid,
63            clientUid,
64            servicePid),
65    mRemoteCallback(remoteCallback) {
66}
67
68// Interface used by CameraService
69
70CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
71        const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
72        const String16& clientPackageName,
73        int cameraId,
74        int cameraFacing,
75        int clientPid,
76        uid_t clientUid,
77        int servicePid) :
78    Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
79                cameraId, cameraFacing, clientPid, clientUid, servicePid),
80    mInputStream(),
81    mRequestIdCounter(0) {
82
83    ATRACE_CALL();
84    ALOGI("CameraDeviceClient %d: Opened", cameraId);
85}
86
87status_t CameraDeviceClient::initialize(CameraModule *module)
88{
89    ATRACE_CALL();
90    status_t res;
91
92    res = Camera2ClientBase::initialize(module);
93    if (res != OK) {
94        return res;
95    }
96
97    String8 threadName;
98    mFrameProcessor = new FrameProcessorBase(mDevice);
99    threadName = String8::format("CDU-%d-FrameProc", mCameraId);
100    mFrameProcessor->run(threadName.string());
101
102    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
103                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
104                                      /*listener*/this,
105                                      /*sendPartials*/true);
106
107    return OK;
108}
109
110CameraDeviceClient::~CameraDeviceClient() {
111}
112
113binder::Status CameraDeviceClient::submitRequest(
114        const hardware::camera2::CaptureRequest& request,
115        bool streaming,
116        /*out*/
117        hardware::camera2::utils::SubmitInfo *submitInfo) {
118    std::vector<hardware::camera2::CaptureRequest> requestList = { request };
119    return submitRequestList(requestList, streaming, submitInfo);
120}
121
122binder::Status CameraDeviceClient::submitRequestList(
123        const std::vector<hardware::camera2::CaptureRequest>& requests,
124        bool streaming,
125        /*out*/
126        hardware::camera2::utils::SubmitInfo *submitInfo) {
127    ATRACE_CALL();
128    ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
129
130    binder::Status res = binder::Status::ok();
131    status_t err;
132    if ( !(res = checkPidStatus(__FUNCTION__) ).isOk()) {
133        return res;
134    }
135
136    Mutex::Autolock icl(mBinderSerializationLock);
137
138    if (!mDevice.get()) {
139        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
140    }
141
142    if (requests.empty()) {
143        ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
144              __FUNCTION__, mCameraId);
145        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Empty request list");
146    }
147
148    List<const CameraMetadata> metadataRequestList;
149    submitInfo->mRequestId = mRequestIdCounter;
150    uint32_t loopCounter = 0;
151
152    for (auto&& request: requests) {
153        if (request.mIsReprocess) {
154            if (!mInputStream.configured) {
155                ALOGE("%s: Camera %d: no input stream is configured.", __FUNCTION__, mCameraId);
156                return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
157                        "No input configured for camera %d but request is for reprocessing",
158                        mCameraId);
159            } else if (streaming) {
160                ALOGE("%s: Camera %d: streaming reprocess requests not supported.", __FUNCTION__,
161                        mCameraId);
162                return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
163                        "Repeating reprocess requests not supported");
164            }
165        }
166
167        CameraMetadata metadata(request.mMetadata);
168        if (metadata.isEmpty()) {
169            ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
170                   __FUNCTION__, mCameraId);
171            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
172                    "Request settings are empty");
173        } else if (request.mSurfaceList.isEmpty()) {
174            ALOGE("%s: Camera %d: Requests must have at least one surface target. "
175                    "Rejecting request.", __FUNCTION__, mCameraId);
176            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
177                    "Request has no output targets");
178        }
179
180        if (!enforceRequestPermissions(metadata)) {
181            // Callee logs
182            return STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
183                    "Caller does not have permission to change restricted controls");
184        }
185
186        /**
187         * Write in the output stream IDs which we calculate from
188         * the capture request's list of surface targets
189         */
190        Vector<int32_t> outputStreamIds;
191        outputStreamIds.setCapacity(request.mSurfaceList.size());
192        for (sp<Surface> surface : request.mSurfaceList) {
193            if (surface == 0) continue;
194
195            sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
196            int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
197
198            // Trying to submit request with surface that wasn't created
199            if (idx == NAME_NOT_FOUND) {
200                ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
201                        " we have not called createStream on",
202                        __FUNCTION__, mCameraId);
203                return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
204                        "Request targets Surface that is not part of current capture session");
205            }
206
207            int streamId = mStreamMap.valueAt(idx);
208            outputStreamIds.push_back(streamId);
209            ALOGV("%s: Camera %d: Appending output stream %d to request",
210                    __FUNCTION__, mCameraId, streamId);
211        }
212
213        metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
214                        outputStreamIds.size());
215
216        if (request.mIsReprocess) {
217            metadata.update(ANDROID_REQUEST_INPUT_STREAMS, &mInputStream.id, 1);
218        }
219
220        metadata.update(ANDROID_REQUEST_ID, &(submitInfo->mRequestId), /*size*/1);
221        loopCounter++; // loopCounter starts from 1
222        ALOGV("%s: Camera %d: Creating request with ID %d (%d of %zu)",
223              __FUNCTION__, mCameraId, submitInfo->mRequestId, loopCounter, requests.size());
224
225        metadataRequestList.push_back(metadata);
226    }
227    mRequestIdCounter++;
228
229    if (streaming) {
230        err = mDevice->setStreamingRequestList(metadataRequestList, &(submitInfo->mLastFrameNumber));
231        if (err != OK) {
232            String8 msg = String8::format(
233                "Camera %d:  Got error %s (%d) after trying to set streaming request",
234                mCameraId, strerror(-err), err);
235            ALOGE("%s: %s", __FUNCTION__, msg.string());
236            res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
237                    msg.string());
238        } else {
239            mStreamingRequestList.push_back(submitInfo->mRequestId);
240        }
241    } else {
242        err = mDevice->captureList(metadataRequestList, &(submitInfo->mLastFrameNumber));
243        if (err != OK) {
244            String8 msg = String8::format(
245                "Camera %d: Got error %s (%d) after trying to submit capture request",
246                mCameraId, strerror(-err), err);
247            ALOGE("%s: %s", __FUNCTION__, msg.string());
248            res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
249                    msg.string());
250        }
251        ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId);
252    }
253
254    ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
255    return res;
256}
257
258binder::Status CameraDeviceClient::cancelRequest(
259        int requestId,
260        /*out*/
261        int64_t* lastFrameNumber) {
262    ATRACE_CALL();
263    ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
264
265    status_t err;
266    binder::Status res;
267
268    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
269
270    Mutex::Autolock icl(mBinderSerializationLock);
271
272    if (!mDevice.get()) {
273        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
274    }
275
276    Vector<int>::iterator it, end;
277    for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
278         it != end; ++it) {
279        if (*it == requestId) {
280            break;
281        }
282    }
283
284    if (it == end) {
285        String8 msg = String8::format("Camera %d: Did not find request ID %d in list of "
286                "streaming requests", mCameraId, requestId);
287        ALOGE("%s: %s", __FUNCTION__, msg.string());
288        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
289    }
290
291    err = mDevice->clearStreamingRequest(lastFrameNumber);
292
293    if (err == OK) {
294        ALOGV("%s: Camera %d: Successfully cleared streaming request",
295              __FUNCTION__, mCameraId);
296        mStreamingRequestList.erase(it);
297    } else {
298        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
299                "Camera %d: Error clearing streaming request: %s (%d)",
300                mCameraId, strerror(-err), err);
301    }
302
303    return res;
304}
305
306binder::Status CameraDeviceClient::beginConfigure() {
307    // TODO: Implement this.
308    ALOGV("%s: Not implemented yet.", __FUNCTION__);
309    return binder::Status::ok();
310}
311
312binder::Status CameraDeviceClient::endConfigure(bool isConstrainedHighSpeed) {
313    ALOGV("%s: ending configure (%d input stream, %zu output streams)",
314            __FUNCTION__, mInputStream.configured ? 1 : 0, mStreamMap.size());
315
316    // Sanitize the high speed session against necessary capability bit.
317    if (isConstrainedHighSpeed) {
318        CameraMetadata staticInfo = mDevice->info();
319        camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
320        bool isConstrainedHighSpeedSupported = false;
321        for(size_t i = 0; i < entry.count; ++i) {
322            uint8_t capability = entry.data.u8[i];
323            if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
324                isConstrainedHighSpeedSupported = true;
325                break;
326            }
327        }
328        if (!isConstrainedHighSpeedSupported) {
329            String8 msg = String8::format(
330                "Camera %d: Try to create a constrained high speed configuration on a device"
331                " that doesn't support it.", mCameraId);
332            ALOGE("%s: %s", __FUNCTION__, msg.string());
333            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
334                    msg.string());
335        }
336    }
337
338    binder::Status res;
339    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
340
341    Mutex::Autolock icl(mBinderSerializationLock);
342
343    if (!mDevice.get()) {
344        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
345    }
346
347    status_t err = mDevice->configureStreams(isConstrainedHighSpeed);
348    if (err != OK) {
349        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
350                "Camera %d: Error configuring streams: %s (%d)",
351                mCameraId, strerror(-err), err);
352    }
353
354    return res;
355}
356
357binder::Status CameraDeviceClient::deleteStream(int streamId) {
358    ATRACE_CALL();
359    ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
360
361    binder::Status res;
362    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
363
364    Mutex::Autolock icl(mBinderSerializationLock);
365
366    if (!mDevice.get()) {
367        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
368    }
369
370    bool isInput = false;
371    ssize_t index = NAME_NOT_FOUND;
372
373    if (mInputStream.configured && mInputStream.id == streamId) {
374        isInput = true;
375    } else {
376        // Guard against trying to delete non-created streams
377        for (size_t i = 0; i < mStreamMap.size(); ++i) {
378            if (streamId == mStreamMap.valueAt(i)) {
379                index = i;
380                break;
381            }
382        }
383
384        if (index == NAME_NOT_FOUND) {
385            String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no such "
386                    "stream created yet", mCameraId, streamId);
387            ALOGW("%s: %s", __FUNCTION__, msg.string());
388            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
389        }
390    }
391
392    // Also returns BAD_VALUE if stream ID was not valid
393    status_t err = mDevice->deleteStream(streamId);
394
395    if (err != OK) {
396        String8 msg = String8::format("Camera %d: Unexpected error %s (%d) when deleting stream %d",
397                mCameraId, strerror(-err), err, streamId);
398        ALOGE("%s: %s", __FUNCTION__, msg.string());
399        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
400    } else {
401        if (isInput) {
402            mInputStream.configured = false;
403        } else {
404            mStreamMap.removeItemsAt(index);
405        }
406    }
407
408    return res;
409}
410
411binder::Status CameraDeviceClient::createStream(
412        const hardware::camera2::params::OutputConfiguration &outputConfiguration,
413        /*out*/
414        int32_t* newStreamId) {
415    ATRACE_CALL();
416
417    binder::Status res;
418    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
419
420    Mutex::Autolock icl(mBinderSerializationLock);
421
422    sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer();
423    if (bufferProducer == NULL) {
424        ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
425        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
426    }
427    if (!mDevice.get()) {
428        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
429    }
430
431    // Don't create multiple streams for the same target surface
432    {
433        ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
434        if (index != NAME_NOT_FOUND) {
435            String8 msg = String8::format("Camera %d: Surface already has a stream created for it "
436                    "(ID %zd)", mCameraId, index);
437            ALOGW("%s: %s", __FUNCTION__, msg.string());
438            return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
439        }
440    }
441
442    status_t err;
443
444    // HACK b/10949105
445    // Query consumer usage bits to set async operation mode for
446    // GLConsumer using controlledByApp parameter.
447    bool useAsync = false;
448    int32_t consumerUsage;
449    if ((err = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
450            &consumerUsage)) != OK) {
451        String8 msg = String8::format("Camera %d: Failed to query Surface consumer usage: %s (%d)",
452                mCameraId, strerror(-err), err);
453        ALOGE("%s: %s", __FUNCTION__, msg.string());
454        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
455    }
456    if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
457        ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
458                __FUNCTION__, mCameraId);
459        useAsync = true;
460    }
461
462    int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
463                              GRALLOC_USAGE_RENDERSCRIPT;
464    int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
465                           GraphicBuffer::USAGE_HW_TEXTURE |
466                           GraphicBuffer::USAGE_HW_COMPOSER;
467    bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
468            (consumerUsage & allowedFlags) != 0;
469
470    sp<IBinder> binder = IInterface::asBinder(bufferProducer);
471    sp<Surface> surface = new Surface(bufferProducer, useAsync);
472    ANativeWindow *anw = surface.get();
473
474    int width, height, format;
475    android_dataspace dataSpace;
476
477    if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
478        String8 msg = String8::format("Camera %d: Failed to query Surface width: %s (%d)",
479                mCameraId, strerror(-err), err);
480        ALOGE("%s: %s", __FUNCTION__, msg.string());
481        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
482    }
483    if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
484        String8 msg = String8::format("Camera %d: Failed to query Surface height: %s (%d)",
485                mCameraId, strerror(-err), err);
486        ALOGE("%s: %s", __FUNCTION__, msg.string());
487        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
488    }
489    if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
490        String8 msg = String8::format("Camera %d: Failed to query Surface format: %s (%d)",
491                mCameraId, strerror(-err), err);
492        ALOGE("%s: %s", __FUNCTION__, msg.string());
493        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
494    }
495    if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
496                            reinterpret_cast<int*>(&dataSpace))) != OK) {
497        String8 msg = String8::format("Camera %d: Failed to query Surface dataspace: %s (%d)",
498                mCameraId, strerror(-err), err);
499        ALOGE("%s: %s", __FUNCTION__, msg.string());
500        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
501    }
502
503    // FIXME: remove this override since the default format should be
504    //       IMPLEMENTATION_DEFINED. b/9487482
505    if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
506        format <= HAL_PIXEL_FORMAT_BGRA_8888) {
507        ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED",
508              __FUNCTION__, mCameraId, format);
509        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
510    }
511
512    // Round dimensions to the nearest dimensions available for this format
513    if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height,
514            format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) {
515        String8 msg = String8::format("Camera %d: No supported stream configurations with "
516                "format %#x defined, failed to create output stream", mCameraId, format);
517        ALOGE("%s: %s", __FUNCTION__, msg.string());
518        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
519    }
520
521    int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
522    err = mDevice->createStream(surface, width, height, format, dataSpace,
523            static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
524            &streamId, outputConfiguration.getSurfaceSetID());
525
526    if (err != OK) {
527        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
528                "Camera %d: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
529                mCameraId, width, height, format, dataSpace, strerror(-err), err);
530    } else {
531        mStreamMap.add(binder, streamId);
532
533        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
534              __FUNCTION__, mCameraId, streamId);
535
536        /**
537         * Set the stream transform flags to automatically
538         * rotate the camera stream for preview use cases.
539         */
540        int32_t transform = 0;
541        err = getRotationTransformLocked(&transform);
542
543        if (err != OK) {
544            // Error logged by getRotationTransformLocked.
545            return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
546                    "Unable to calculate rotation transform for new stream");
547        }
548
549        err = mDevice->setStreamTransform(streamId, transform);
550        if (err != OK) {
551            String8 msg = String8::format("Failed to set stream transform (stream id %d)",
552                    streamId);
553            ALOGE("%s: %s", __FUNCTION__, msg.string());
554            return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
555        }
556
557        *newStreamId = streamId;
558    }
559
560    return res;
561}
562
563
564binder::Status CameraDeviceClient::createInputStream(
565        int width, int height, int format,
566        /*out*/
567        int32_t* newStreamId) {
568
569    ATRACE_CALL();
570    ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
571
572    binder::Status res;
573    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
574
575    Mutex::Autolock icl(mBinderSerializationLock);
576
577    if (!mDevice.get()) {
578        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
579    }
580
581    if (mInputStream.configured) {
582        String8 msg = String8::format("Camera %d: Already has an input stream "
583                "configured (ID %zd)", mCameraId, mInputStream.id);
584        ALOGE("%s: %s", __FUNCTION__, msg.string() );
585        return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
586    }
587
588    int streamId = -1;
589    status_t err = mDevice->createInputStream(width, height, format, &streamId);
590    if (err == OK) {
591        mInputStream.configured = true;
592        mInputStream.width = width;
593        mInputStream.height = height;
594        mInputStream.format = format;
595        mInputStream.id = streamId;
596
597        ALOGV("%s: Camera %d: Successfully created a new input stream ID %d",
598                __FUNCTION__, mCameraId, streamId);
599
600        *newStreamId = streamId;
601    } else {
602        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
603                "Camera %d: Error creating new input stream: %s (%d)", mCameraId,
604                strerror(-err), err);
605    }
606
607    return res;
608}
609
610binder::Status CameraDeviceClient::getInputSurface(/*out*/ view::Surface *inputSurface) {
611
612    binder::Status res;
613    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
614
615    if (inputSurface == NULL) {
616        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Null input surface");
617    }
618
619    Mutex::Autolock icl(mBinderSerializationLock);
620    if (!mDevice.get()) {
621        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
622    }
623    sp<IGraphicBufferProducer> producer;
624    status_t err = mDevice->getInputBufferProducer(&producer);
625    if (err != OK) {
626        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
627                "Camera %d: Error getting input Surface: %s (%d)",
628                mCameraId, strerror(-err), err);
629    } else {
630        inputSurface->name = String16("CameraInput");
631        inputSurface->graphicBufferProducer = producer;
632    }
633    return res;
634}
635
636bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
637        int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
638        /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
639
640    camera_metadata_ro_entry streamConfigs =
641            (dataSpace == HAL_DATASPACE_DEPTH) ?
642            info.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS) :
643            info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
644
645    int32_t bestWidth = -1;
646    int32_t bestHeight = -1;
647
648    // Iterate through listed stream configurations and find the one with the smallest euclidean
649    // distance from the given dimensions for the given format.
650    for (size_t i = 0; i < streamConfigs.count; i += 4) {
651        int32_t fmt = streamConfigs.data.i32[i];
652        int32_t w = streamConfigs.data.i32[i + 1];
653        int32_t h = streamConfigs.data.i32[i + 2];
654
655        // Ignore input/output type for now
656        if (fmt == format) {
657            if (w == width && h == height) {
658                bestWidth = width;
659                bestHeight = height;
660                break;
661            } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
662                    CameraDeviceClient::euclidDistSquare(w, h, width, height) <
663                    CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) {
664                bestWidth = w;
665                bestHeight = h;
666            }
667        }
668    }
669
670    if (bestWidth == -1) {
671        // Return false if no configurations for this format were listed
672        return false;
673    }
674
675    // Set the outputs to the closet width/height
676    if (outWidth != NULL) {
677        *outWidth = bestWidth;
678    }
679    if (outHeight != NULL) {
680        *outHeight = bestHeight;
681    }
682
683    // Return true if at least one configuration for this format was listed
684    return true;
685}
686
687int64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
688    int64_t d0 = x0 - x1;
689    int64_t d1 = y0 - y1;
690    return d0 * d0 + d1 * d1;
691}
692
693// Create a request object from a template.
694binder::Status CameraDeviceClient::createDefaultRequest(int templateId,
695        /*out*/
696        hardware::camera2::impl::CameraMetadataNative* request)
697{
698    ATRACE_CALL();
699    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
700
701    binder::Status res;
702    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
703
704    Mutex::Autolock icl(mBinderSerializationLock);
705
706    if (!mDevice.get()) {
707        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
708    }
709
710    CameraMetadata metadata;
711    status_t err;
712    if ( (err = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
713        request != NULL) {
714
715        request->swap(metadata);
716    } else {
717        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
718                "Camera %d: Error creating default request for template %d: %s (%d)",
719                mCameraId, templateId, strerror(-err), err);
720    }
721    return res;
722}
723
724binder::Status CameraDeviceClient::getCameraInfo(
725        /*out*/
726        hardware::camera2::impl::CameraMetadataNative* info)
727{
728    ATRACE_CALL();
729    ALOGV("%s", __FUNCTION__);
730
731    binder::Status res;
732
733    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
734
735    Mutex::Autolock icl(mBinderSerializationLock);
736
737    if (!mDevice.get()) {
738        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
739    }
740
741    if (info != NULL) {
742        *info = mDevice->info(); // static camera metadata
743        // TODO: merge with device-specific camera metadata
744    }
745
746    return res;
747}
748
749binder::Status CameraDeviceClient::waitUntilIdle()
750{
751    ATRACE_CALL();
752    ALOGV("%s", __FUNCTION__);
753
754    binder::Status res;
755    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
756
757    Mutex::Autolock icl(mBinderSerializationLock);
758
759    if (!mDevice.get()) {
760        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
761    }
762
763    // FIXME: Also need check repeating burst.
764    if (!mStreamingRequestList.isEmpty()) {
765        String8 msg = String8::format(
766            "Camera %d: Try to waitUntilIdle when there are active streaming requests",
767            mCameraId);
768        ALOGE("%s: %s", __FUNCTION__, msg.string());
769        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
770    }
771    status_t err = mDevice->waitUntilDrained();
772    if (err != OK) {
773        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
774                "Camera %d: Error waiting to drain: %s (%d)",
775                mCameraId, strerror(-err), err);
776    }
777    ALOGV("%s Done", __FUNCTION__);
778    return res;
779}
780
781binder::Status CameraDeviceClient::flush(
782        /*out*/
783        int64_t* lastFrameNumber) {
784    ATRACE_CALL();
785    ALOGV("%s", __FUNCTION__);
786
787    binder::Status res;
788    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
789
790    Mutex::Autolock icl(mBinderSerializationLock);
791
792    if (!mDevice.get()) {
793        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
794    }
795
796    mStreamingRequestList.clear();
797    status_t err = mDevice->flush(lastFrameNumber);
798    if (err != OK) {
799        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
800                "Camera %d: Error flushing device: %s (%d)", mCameraId, strerror(-err), err);
801    }
802    return res;
803}
804
805binder::Status CameraDeviceClient::prepare(int streamId) {
806    ATRACE_CALL();
807    ALOGV("%s", __FUNCTION__);
808
809    binder::Status res;
810    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
811
812    Mutex::Autolock icl(mBinderSerializationLock);
813
814    // Guard against trying to prepare non-created streams
815    ssize_t index = NAME_NOT_FOUND;
816    for (size_t i = 0; i < mStreamMap.size(); ++i) {
817        if (streamId == mStreamMap.valueAt(i)) {
818            index = i;
819            break;
820        }
821    }
822
823    if (index == NAME_NOT_FOUND) {
824        String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no stream "
825              "with that ID exists", mCameraId, streamId);
826        ALOGW("%s: %s", __FUNCTION__, msg.string());
827        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
828    }
829
830    // Also returns BAD_VALUE if stream ID was not valid, or stream already
831    // has been used
832    status_t err = mDevice->prepare(streamId);
833    if (err == BAD_VALUE) {
834        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
835                "Camera %d: Stream %d has already been used, and cannot be prepared",
836                mCameraId, streamId);
837    } else if (err != OK) {
838        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
839                "Camera %d: Error preparing stream %d: %s (%d)", mCameraId, streamId,
840                strerror(-err), err);
841    }
842    return res;
843}
844
845binder::Status CameraDeviceClient::prepare2(int maxCount, int streamId) {
846    ATRACE_CALL();
847    ALOGV("%s", __FUNCTION__);
848
849    binder::Status res;
850    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
851
852    Mutex::Autolock icl(mBinderSerializationLock);
853
854    // Guard against trying to prepare non-created streams
855    ssize_t index = NAME_NOT_FOUND;
856    for (size_t i = 0; i < mStreamMap.size(); ++i) {
857        if (streamId == mStreamMap.valueAt(i)) {
858            index = i;
859            break;
860        }
861    }
862
863    if (index == NAME_NOT_FOUND) {
864        String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no stream "
865              "with that ID exists", mCameraId, streamId);
866        ALOGW("%s: %s", __FUNCTION__, msg.string());
867        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
868    }
869
870    if (maxCount <= 0) {
871        String8 msg = String8::format("Camera %d: maxCount (%d) must be greater than 0",
872                mCameraId, maxCount);
873        ALOGE("%s: %s", __FUNCTION__, msg.string());
874        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
875    }
876
877    // Also returns BAD_VALUE if stream ID was not valid, or stream already
878    // has been used
879    status_t err = mDevice->prepare(maxCount, streamId);
880    if (err == BAD_VALUE) {
881        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
882                "Camera %d: Stream %d has already been used, and cannot be prepared",
883                mCameraId, streamId);
884    } else if (err != OK) {
885        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
886                "Camera %d: Error preparing stream %d: %s (%d)", mCameraId, streamId,
887                strerror(-err), err);
888    }
889
890    return res;
891}
892
893binder::Status CameraDeviceClient::tearDown(int streamId) {
894    ATRACE_CALL();
895    ALOGV("%s", __FUNCTION__);
896
897    binder::Status res;
898    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
899
900    Mutex::Autolock icl(mBinderSerializationLock);
901
902    // Guard against trying to prepare non-created streams
903    ssize_t index = NAME_NOT_FOUND;
904    for (size_t i = 0; i < mStreamMap.size(); ++i) {
905        if (streamId == mStreamMap.valueAt(i)) {
906            index = i;
907            break;
908        }
909    }
910
911    if (index == NAME_NOT_FOUND) {
912        String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no stream "
913              "with that ID exists", mCameraId, streamId);
914        ALOGW("%s: %s", __FUNCTION__, msg.string());
915        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
916    }
917
918    // Also returns BAD_VALUE if stream ID was not valid or if the stream is in
919    // use
920    status_t err = mDevice->tearDown(streamId);
921    if (err == BAD_VALUE) {
922        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
923                "Camera %d: Stream %d is still in use, cannot be torn down",
924                mCameraId, streamId);
925    } else if (err != OK) {
926        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
927                "Camera %d: Error tearing down stream %d: %s (%d)", mCameraId, streamId,
928                strerror(-err), err);
929    }
930
931    return res;
932}
933
934status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
935    return BasicClient::dump(fd, args);
936}
937
938status_t CameraDeviceClient::dumpClient(int fd, const Vector<String16>& args) {
939    String8 result;
940    result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n",
941            mCameraId,
942            (getRemoteCallback() != NULL ?
943                    IInterface::asBinder(getRemoteCallback()).get() : NULL) );
944    result.appendFormat("  Current client UID %u\n", mClientUid);
945
946    result.append("  State:\n");
947    result.appendFormat("    Request ID counter: %d\n", mRequestIdCounter);
948    if (mInputStream.configured) {
949        result.appendFormat("    Current input stream ID: %d\n",
950                    mInputStream.id);
951    } else {
952        result.append("    No input stream configured.\n");
953    }
954    if (!mStreamMap.isEmpty()) {
955        result.append("    Current output stream IDs:\n");
956        for (size_t i = 0; i < mStreamMap.size(); i++) {
957            result.appendFormat("      Stream %d\n", mStreamMap.valueAt(i));
958        }
959    } else {
960        result.append("    No output streams configured.\n");
961    }
962    write(fd, result.string(), result.size());
963    // TODO: print dynamic/request section from most recent requests
964    mFrameProcessor->dump(fd, args);
965
966    return dumpDevice(fd, args);
967}
968
969void CameraDeviceClient::notifyError(int32_t errorCode,
970                                     const CaptureResultExtras& resultExtras) {
971    // Thread safe. Don't bother locking.
972    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
973
974    if (remoteCb != 0) {
975        remoteCb->onDeviceError(errorCode, resultExtras);
976    }
977}
978
979void CameraDeviceClient::notifyIdle() {
980    // Thread safe. Don't bother locking.
981    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
982
983    if (remoteCb != 0) {
984        remoteCb->onDeviceIdle();
985    }
986    Camera2ClientBase::notifyIdle();
987}
988
989void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
990        nsecs_t timestamp) {
991    // Thread safe. Don't bother locking.
992    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
993    if (remoteCb != 0) {
994        remoteCb->onCaptureStarted(resultExtras, timestamp);
995    }
996    Camera2ClientBase::notifyShutter(resultExtras, timestamp);
997}
998
999void CameraDeviceClient::notifyPrepared(int streamId) {
1000    // Thread safe. Don't bother locking.
1001    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1002    if (remoteCb != 0) {
1003        remoteCb->onPrepared(streamId);
1004    }
1005}
1006
1007void CameraDeviceClient::detachDevice() {
1008    if (mDevice == 0) return;
1009
1010    ALOGV("Camera %d: Stopping processors", mCameraId);
1011
1012    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
1013                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
1014                                    /*listener*/this);
1015    mFrameProcessor->requestExit();
1016    ALOGV("Camera %d: Waiting for threads", mCameraId);
1017    mFrameProcessor->join();
1018    ALOGV("Camera %d: Disconnecting device", mCameraId);
1019
1020    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
1021    {
1022        mDevice->clearStreamingRequest();
1023
1024        status_t code;
1025        if ((code = mDevice->waitUntilDrained()) != OK) {
1026            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
1027                  code);
1028        }
1029    }
1030
1031    Camera2ClientBase::detachDevice();
1032}
1033
1034/** Device-related methods */
1035void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
1036    ATRACE_CALL();
1037    ALOGV("%s", __FUNCTION__);
1038
1039    // Thread-safe. No lock necessary.
1040    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
1041    if (remoteCb != NULL) {
1042        remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
1043    }
1044}
1045
1046binder::Status CameraDeviceClient::checkPidStatus(const char* checkLocation) {
1047    status_t res = checkPid(checkLocation);
1048    return (res == OK) ? binder::Status::ok() :
1049            STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
1050                    "Attempt to use camera from a different process than original client");
1051}
1052
1053// TODO: move to Camera2ClientBase
1054bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
1055
1056    const int pid = IPCThreadState::self()->getCallingPid();
1057    const int selfPid = getpid();
1058    camera_metadata_entry_t entry;
1059
1060    /**
1061     * Mixin default important security values
1062     * - android.led.transmit = defaulted ON
1063     */
1064    CameraMetadata staticInfo = mDevice->info();
1065    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
1066    for(size_t i = 0; i < entry.count; ++i) {
1067        uint8_t led = entry.data.u8[i];
1068
1069        switch(led) {
1070            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
1071                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
1072                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
1073                    metadata.update(ANDROID_LED_TRANSMIT,
1074                                    &transmitDefault, 1);
1075                }
1076                break;
1077            }
1078        }
1079    }
1080
1081    // We can do anything!
1082    if (pid == selfPid) {
1083        return true;
1084    }
1085
1086    /**
1087     * Permission check special fields in the request
1088     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
1089     */
1090    entry = metadata.find(ANDROID_LED_TRANSMIT);
1091    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
1092        String16 permissionString =
1093            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
1094        if (!checkCallingPermission(permissionString)) {
1095            const int uid = IPCThreadState::self()->getCallingUid();
1096            ALOGE("Permission Denial: "
1097                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
1098            return false;
1099        }
1100    }
1101
1102    return true;
1103}
1104
1105status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
1106    ALOGV("%s: begin", __FUNCTION__);
1107
1108    const CameraMetadata& staticInfo = mDevice->info();
1109    return CameraUtils::getRotationTransform(staticInfo, transform);
1110}
1111
1112} // namespace android
1113