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