CameraDeviceClient.cpp revision f1e98d857ec377f2c9b916073d40732e6ebb7ced
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
27#include "common/CameraDeviceBase.h"
28#include "api2/CameraDeviceClient.h"
29
30
31
32namespace android {
33using namespace camera2;
34
35CameraDeviceClientBase::CameraDeviceClientBase(
36        const sp<CameraService>& cameraService,
37        const sp<ICameraDeviceCallbacks>& remoteCallback,
38        const String16& clientPackageName,
39        int cameraId,
40        int cameraFacing,
41        int clientPid,
42        uid_t clientUid,
43        int servicePid) :
44    BasicClient(cameraService, remoteCallback->asBinder(), clientPackageName,
45                cameraId, cameraFacing, clientPid, clientUid, servicePid),
46    mRemoteCallback(remoteCallback) {
47}
48
49// Interface used by CameraService
50
51CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
52                                   const sp<ICameraDeviceCallbacks>& remoteCallback,
53                                   const String16& clientPackageName,
54                                   int cameraId,
55                                   int cameraFacing,
56                                   int clientPid,
57                                   uid_t clientUid,
58                                   int servicePid) :
59    Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
60                cameraId, cameraFacing, clientPid, clientUid, servicePid),
61    mRequestIdCounter(0) {
62
63    ATRACE_CALL();
64    ALOGI("CameraDeviceClient %d: Opened", cameraId);
65}
66
67status_t CameraDeviceClient::initialize(camera_module_t *module)
68{
69    ATRACE_CALL();
70    status_t res;
71
72    res = Camera2ClientBase::initialize(module);
73    if (res != OK) {
74        return res;
75    }
76
77    String8 threadName;
78    mFrameProcessor = new FrameProcessorBase(mDevice);
79    threadName = String8::format("CDU-%d-FrameProc", mCameraId);
80    mFrameProcessor->run(threadName.string());
81
82    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
83                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
84                                      /*listener*/this);
85
86    return OK;
87}
88
89CameraDeviceClient::~CameraDeviceClient() {
90}
91
92status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
93                                         bool streaming) {
94    ATRACE_CALL();
95    ALOGV("%s", __FUNCTION__);
96
97    status_t res;
98
99    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
100
101    Mutex::Autolock icl(mBinderSerializationLock);
102
103    if (!mDevice.get()) return DEAD_OBJECT;
104
105    if (request == 0) {
106        ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
107              __FUNCTION__, mCameraId);
108        return BAD_VALUE;
109    }
110
111    CameraMetadata metadata(request->mMetadata);
112
113    if (metadata.isEmpty()) {
114        ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
115               __FUNCTION__, mCameraId);
116        return BAD_VALUE;
117    } else if (request->mSurfaceList.size() == 0) {
118        ALOGE("%s: Camera %d: Requests must have at least one surface target. "
119              "Rejecting request.", __FUNCTION__, mCameraId);
120        return BAD_VALUE;
121    }
122
123    if (!enforceRequestPermissions(metadata)) {
124        // Callee logs
125        return PERMISSION_DENIED;
126    }
127
128    /**
129     * Write in the output stream IDs which we calculate from
130     * the capture request's list of surface targets
131     */
132    Vector<int32_t> outputStreamIds;
133    outputStreamIds.setCapacity(request->mSurfaceList.size());
134    for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
135        sp<Surface> surface = request->mSurfaceList[i];
136
137        if (surface == 0) continue;
138
139        sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
140        int idx = mStreamMap.indexOfKey(gbp->asBinder());
141
142        // Trying to submit request with surface that wasn't created
143        if (idx == NAME_NOT_FOUND) {
144            ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
145                  " we have not called createStream on",
146                  __FUNCTION__, mCameraId);
147            return BAD_VALUE;
148        }
149
150        int streamId = mStreamMap.valueAt(idx);
151        outputStreamIds.push_back(streamId);
152        ALOGV("%s: Camera %d: Appending output stream %d to request",
153              __FUNCTION__, mCameraId, streamId);
154    }
155
156    metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
157                    outputStreamIds.size());
158
159    int32_t requestId = mRequestIdCounter++;
160    metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
161    ALOGV("%s: Camera %d: Submitting request with ID %d",
162          __FUNCTION__, mCameraId, requestId);
163
164    if (streaming) {
165        res = mDevice->setStreamingRequest(metadata);
166        if (res != OK) {
167            ALOGE("%s: Camera %d:  Got error %d after trying to set streaming "
168                  "request", __FUNCTION__, mCameraId, res);
169        } else {
170            mStreamingRequestList.push_back(requestId);
171        }
172    } else {
173        res = mDevice->capture(metadata);
174        if (res != OK) {
175            ALOGE("%s: Camera %d: Got error %d after trying to set capture",
176                  __FUNCTION__, mCameraId, res);
177        }
178    }
179
180    ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
181    if (res == OK) {
182        return requestId;
183    }
184
185    return res;
186}
187
188status_t CameraDeviceClient::cancelRequest(int requestId) {
189    ATRACE_CALL();
190    ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
191
192    status_t res;
193
194    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
195
196    Mutex::Autolock icl(mBinderSerializationLock);
197
198    if (!mDevice.get()) return DEAD_OBJECT;
199
200    Vector<int>::iterator it, end;
201    for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
202         it != end; ++it) {
203        if (*it == requestId) {
204            break;
205        }
206    }
207
208    if (it == end) {
209        ALOGE("%s: Camera%d: Did not find request id %d in list of streaming "
210              "requests", __FUNCTION__, mCameraId, requestId);
211        return BAD_VALUE;
212    }
213
214    res = mDevice->clearStreamingRequest();
215
216    if (res == OK) {
217        ALOGV("%s: Camera %d: Successfully cleared streaming request",
218              __FUNCTION__, mCameraId);
219        mStreamingRequestList.erase(it);
220    }
221
222    return res;
223}
224
225status_t CameraDeviceClient::deleteStream(int streamId) {
226    ATRACE_CALL();
227    ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
228
229    status_t res;
230    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
231
232    Mutex::Autolock icl(mBinderSerializationLock);
233
234    if (!mDevice.get()) return DEAD_OBJECT;
235
236    // Guard against trying to delete non-created streams
237    ssize_t index = NAME_NOT_FOUND;
238    for (size_t i = 0; i < mStreamMap.size(); ++i) {
239        if (streamId == mStreamMap.valueAt(i)) {
240            index = i;
241            break;
242        }
243    }
244
245    if (index == NAME_NOT_FOUND) {
246        ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
247              "created yet", __FUNCTION__, mCameraId, streamId);
248        return BAD_VALUE;
249    }
250
251    // Also returns BAD_VALUE if stream ID was not valid
252    res = mDevice->deleteStream(streamId);
253
254    if (res == BAD_VALUE) {
255        ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we"
256              " already checked and the stream ID (%d) should be valid.",
257              __FUNCTION__, mCameraId, streamId);
258    } else if (res == OK) {
259        mStreamMap.removeItemsAt(index);
260
261        ALOGV("%s: Camera %d: Successfully deleted stream ID (%d)",
262              __FUNCTION__, mCameraId, streamId);
263    }
264
265    return res;
266}
267
268status_t CameraDeviceClient::createStream(int width, int height, int format,
269                      const sp<IGraphicBufferProducer>& bufferProducer)
270{
271    ATRACE_CALL();
272    ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
273
274    status_t res;
275    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
276
277    Mutex::Autolock icl(mBinderSerializationLock);
278
279    if (!mDevice.get()) return DEAD_OBJECT;
280
281    // Don't create multiple streams for the same target surface
282    {
283        ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder());
284        if (index != NAME_NOT_FOUND) {
285            ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
286                  "(ID %d)",
287                  __FUNCTION__, mCameraId, index);
288            return ALREADY_EXISTS;
289        }
290    }
291
292    // HACK b/10949105
293    // Query consumer usage bits to set async operation mode for
294    // GLConsumer using controlledByApp parameter.
295    bool useAsync = false;
296    int32_t consumerUsage;
297    if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
298            &consumerUsage)) != OK) {
299        ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
300              mCameraId);
301        return res;
302    }
303    if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
304        ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
305                __FUNCTION__, mCameraId);
306        useAsync = true;
307    }
308
309    sp<IBinder> binder;
310    sp<ANativeWindow> anw;
311    if (bufferProducer != 0) {
312        binder = bufferProducer->asBinder();
313        anw = new Surface(bufferProducer, useAsync);
314    }
315
316    // TODO: remove w,h,f since we are ignoring them
317
318    if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
319        ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
320              mCameraId);
321        return res;
322    }
323    if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) {
324        ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
325              mCameraId);
326        return res;
327    }
328    if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) {
329        ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
330              mCameraId);
331        return res;
332    }
333
334    // FIXME: remove this override since the default format should be
335    //       IMPLEMENTATION_DEFINED. b/9487482
336    if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
337        format <= HAL_PIXEL_FORMAT_BGRA_8888) {
338        ALOGW("%s: Camera %d: Overriding format 0x%x to IMPLEMENTATION_DEFINED",
339              __FUNCTION__, mCameraId, format);
340        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
341    }
342
343    // TODO: add startConfigure/stopConfigure call to CameraDeviceBase
344    // this will make it so Camera3Device doesn't call configure_streams
345    // after each call, but only once we are done with all.
346
347    int streamId = -1;
348    if (format == HAL_PIXEL_FORMAT_BLOB) {
349        // JPEG buffers need to be sized for maximum possible compressed size
350        CameraMetadata staticInfo = mDevice->info();
351        camera_metadata_entry_t entry = staticInfo.find(ANDROID_JPEG_MAX_SIZE);
352        if (entry.count == 0) {
353            ALOGE("%s: Camera %d: Can't find maximum JPEG size in "
354                    "static metadata!", __FUNCTION__, mCameraId);
355            return INVALID_OPERATION;
356        }
357        int32_t maxJpegSize = entry.data.i32[0];
358        res = mDevice->createStream(anw, width, height, format, maxJpegSize,
359                &streamId);
360    } else {
361        // All other streams are a known size
362        res = mDevice->createStream(anw, width, height, format, /*size*/0,
363                &streamId);
364    }
365
366    if (res == OK) {
367        mStreamMap.add(bufferProducer->asBinder(), streamId);
368
369        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
370              __FUNCTION__, mCameraId, streamId);
371
372        /**
373         * Set the stream transform flags to automatically
374         * rotate the camera stream for preview use cases.
375         */
376        int32_t transform = 0;
377        res = getRotationTransformLocked(&transform);
378
379        if (res != OK) {
380            // Error logged by getRotationTransformLocked.
381            return res;
382        }
383
384        res = mDevice->setStreamTransform(streamId, transform);
385        if (res != OK) {
386            ALOGE("%s: Failed to set stream transform (stream id %d)",
387                  __FUNCTION__, streamId);
388            return res;
389        }
390
391        return streamId;
392    }
393
394    return res;
395}
396
397// Create a request object from a template.
398status_t CameraDeviceClient::createDefaultRequest(int templateId,
399                                                  /*out*/
400                                                  CameraMetadata* request)
401{
402    ATRACE_CALL();
403    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
404
405    status_t res;
406    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
407
408    Mutex::Autolock icl(mBinderSerializationLock);
409
410    if (!mDevice.get()) return DEAD_OBJECT;
411
412    CameraMetadata metadata;
413    if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
414        request != NULL) {
415
416        request->swap(metadata);
417    }
418
419    return res;
420}
421
422status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
423{
424    ATRACE_CALL();
425    ALOGV("%s", __FUNCTION__);
426
427    status_t res = OK;
428
429    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
430
431    Mutex::Autolock icl(mBinderSerializationLock);
432
433    if (!mDevice.get()) return DEAD_OBJECT;
434
435    if (info != NULL) {
436        *info = mDevice->info(); // static camera metadata
437        // TODO: merge with device-specific camera metadata
438    }
439
440    return res;
441}
442
443status_t CameraDeviceClient::waitUntilIdle()
444{
445    ATRACE_CALL();
446    ALOGV("%s", __FUNCTION__);
447
448    status_t res = OK;
449    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
450
451    Mutex::Autolock icl(mBinderSerializationLock);
452
453    if (!mDevice.get()) return DEAD_OBJECT;
454
455    // FIXME: Also need check repeating burst.
456    if (!mStreamingRequestList.isEmpty()) {
457        ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
458              __FUNCTION__, mCameraId);
459        return INVALID_OPERATION;
460    }
461    res = mDevice->waitUntilDrained();
462    ALOGV("%s Done", __FUNCTION__);
463
464    return res;
465}
466
467status_t CameraDeviceClient::flush() {
468    ATRACE_CALL();
469    ALOGV("%s", __FUNCTION__);
470
471    status_t res = OK;
472    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
473
474    Mutex::Autolock icl(mBinderSerializationLock);
475
476    if (!mDevice.get()) return DEAD_OBJECT;
477
478    return mDevice->flush();
479}
480
481status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
482    String8 result;
483    result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n",
484            mCameraId,
485            getRemoteCallback()->asBinder().get(),
486            mClientPid);
487    result.append("  State: ");
488
489    // TODO: print dynamic/request section from most recent requests
490    mFrameProcessor->dump(fd, args);
491
492    return dumpDevice(fd, args);
493}
494
495
496void CameraDeviceClient::notifyError() {
497    // Thread safe. Don't bother locking.
498    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
499
500    if (remoteCb != 0) {
501        remoteCb->onDeviceError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE);
502    }
503}
504
505void CameraDeviceClient::notifyIdle() {
506    // Thread safe. Don't bother locking.
507    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
508
509    if (remoteCb != 0) {
510        remoteCb->onDeviceIdle();
511    }
512}
513
514void CameraDeviceClient::notifyShutter(int requestId,
515        nsecs_t timestamp) {
516    // Thread safe. Don't bother locking.
517    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
518    if (remoteCb != 0) {
519        remoteCb->onCaptureStarted(requestId, timestamp);
520    }
521}
522
523// TODO: refactor the code below this with IProCameraUser.
524// it's 100% copy-pasted, so lets not change it right now to make it easier.
525
526void CameraDeviceClient::detachDevice() {
527    if (mDevice == 0) return;
528
529    ALOGV("Camera %d: Stopping processors", mCameraId);
530
531    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
532                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
533                                    /*listener*/this);
534    mFrameProcessor->requestExit();
535    ALOGV("Camera %d: Waiting for threads", mCameraId);
536    mFrameProcessor->join();
537    ALOGV("Camera %d: Disconnecting device", mCameraId);
538
539    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
540    {
541        mDevice->clearStreamingRequest();
542
543        status_t code;
544        if ((code = mDevice->waitUntilDrained()) != OK) {
545            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
546                  code);
547        }
548    }
549
550    Camera2ClientBase::detachDevice();
551}
552
553/** Device-related methods */
554void CameraDeviceClient::onFrameAvailable(int32_t requestId,
555        const CameraMetadata& frame) {
556    ATRACE_CALL();
557    ALOGV("%s", __FUNCTION__);
558
559    // Thread-safe. No lock necessary.
560    sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
561    if (remoteCb != NULL) {
562        ALOGV("%s: frame = %p ", __FUNCTION__, &frame);
563        remoteCb->onResultReceived(requestId, frame);
564    }
565}
566
567// TODO: move to Camera2ClientBase
568bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
569
570    const int pid = IPCThreadState::self()->getCallingPid();
571    const int selfPid = getpid();
572    camera_metadata_entry_t entry;
573
574    /**
575     * Mixin default important security values
576     * - android.led.transmit = defaulted ON
577     */
578    CameraMetadata staticInfo = mDevice->info();
579    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
580    for(size_t i = 0; i < entry.count; ++i) {
581        uint8_t led = entry.data.u8[i];
582
583        switch(led) {
584            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
585                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
586                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
587                    metadata.update(ANDROID_LED_TRANSMIT,
588                                    &transmitDefault, 1);
589                }
590                break;
591            }
592        }
593    }
594
595    // We can do anything!
596    if (pid == selfPid) {
597        return true;
598    }
599
600    /**
601     * Permission check special fields in the request
602     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
603     */
604    entry = metadata.find(ANDROID_LED_TRANSMIT);
605    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
606        String16 permissionString =
607            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
608        if (!checkCallingPermission(permissionString)) {
609            const int uid = IPCThreadState::self()->getCallingUid();
610            ALOGE("Permission Denial: "
611                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
612            return false;
613        }
614    }
615
616    return true;
617}
618
619status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
620    ALOGV("%s: begin", __FUNCTION__);
621
622    if (transform == NULL) {
623        ALOGW("%s: null transform", __FUNCTION__);
624        return BAD_VALUE;
625    }
626
627    *transform = 0;
628
629    const CameraMetadata& staticInfo = mDevice->info();
630    camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
631    if (entry.count == 0) {
632        ALOGE("%s: Camera %d: Can't find android.sensor.orientation in "
633                "static metadata!", __FUNCTION__, mCameraId);
634        return INVALID_OPERATION;
635    }
636
637    int32_t& flags = *transform;
638
639    int orientation = entry.data.i32[0];
640    switch (orientation) {
641        case 0:
642            flags = 0;
643            break;
644        case 90:
645            flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
646            break;
647        case 180:
648            flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
649            break;
650        case 270:
651            flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
652            break;
653        default:
654            ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
655                  __FUNCTION__, orientation);
656            return INVALID_OPERATION;
657    }
658
659    /**
660     * This magic flag makes surfaceflinger un-rotate the buffers
661     * to counter the extra global device UI rotation whenever the user
662     * physically rotates the device.
663     *
664     * By doing this, the camera buffer always ends up aligned
665     * with the physical camera for a "see through" effect.
666     *
667     * In essence, the buffer only gets rotated during preview use-cases.
668     * The user is still responsible to re-create streams of the proper
669     * aspect ratio, or the preview will end up looking non-uniformly
670     * stretched.
671     */
672    flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
673
674    ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
675
676    return OK;
677}
678
679} // namespace android
680