CameraDeviceClient.cpp revision e2d167eb689d7a536805f950c31f11b9e9c578ae
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    ALOGV("%s: ending configure (%zu streams)",
258            __FUNCTION__, mStreamMap.size());
259
260    status_t res;
261    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
262
263    Mutex::Autolock icl(mBinderSerializationLock);
264
265    if (!mDevice.get()) return DEAD_OBJECT;
266
267    return mDevice->configureStreams();
268}
269
270status_t CameraDeviceClient::deleteStream(int streamId) {
271    ATRACE_CALL();
272    ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
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    // Guard against trying to delete non-created streams
282    ssize_t index = NAME_NOT_FOUND;
283    for (size_t i = 0; i < mStreamMap.size(); ++i) {
284        if (streamId == mStreamMap.valueAt(i)) {
285            index = i;
286            break;
287        }
288    }
289
290    if (index == NAME_NOT_FOUND) {
291        ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
292              "created yet", __FUNCTION__, mCameraId, streamId);
293        return BAD_VALUE;
294    }
295
296    // Also returns BAD_VALUE if stream ID was not valid
297    res = mDevice->deleteStream(streamId);
298
299    if (res == BAD_VALUE) {
300        ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we"
301              " already checked and the stream ID (%d) should be valid.",
302              __FUNCTION__, mCameraId, streamId);
303    } else if (res == OK) {
304        mStreamMap.removeItemsAt(index);
305
306    }
307
308    return res;
309}
310
311status_t CameraDeviceClient::createStream(int width, int height, int format,
312                      const sp<IGraphicBufferProducer>& bufferProducer)
313{
314    ATRACE_CALL();
315    ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
316
317    status_t res;
318    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
319
320    Mutex::Autolock icl(mBinderSerializationLock);
321
322    if (bufferProducer == NULL) {
323        ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
324        return BAD_VALUE;
325    }
326    if (!mDevice.get()) return DEAD_OBJECT;
327
328    // Don't create multiple streams for the same target surface
329    {
330        ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder());
331        if (index != NAME_NOT_FOUND) {
332            ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
333                  "(ID %zd)",
334                  __FUNCTION__, mCameraId, index);
335            return ALREADY_EXISTS;
336        }
337    }
338
339    // HACK b/10949105
340    // Query consumer usage bits to set async operation mode for
341    // GLConsumer using controlledByApp parameter.
342    bool useAsync = false;
343    int32_t consumerUsage;
344    if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
345            &consumerUsage)) != OK) {
346        ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
347              mCameraId);
348        return res;
349    }
350    if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
351        ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
352                __FUNCTION__, mCameraId);
353        useAsync = true;
354    }
355
356    sp<IBinder> binder;
357    sp<ANativeWindow> anw;
358    if (bufferProducer != 0) {
359        binder = bufferProducer->asBinder();
360        anw = new Surface(bufferProducer, useAsync);
361    }
362
363    // TODO: remove w,h,f since we are ignoring them
364
365    if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
366        ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
367              mCameraId);
368        return res;
369    }
370    if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) {
371        ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
372              mCameraId);
373        return res;
374    }
375    if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) {
376        ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
377              mCameraId);
378        return res;
379    }
380
381    // FIXME: remove this override since the default format should be
382    //       IMPLEMENTATION_DEFINED. b/9487482
383    if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
384        format <= HAL_PIXEL_FORMAT_BGRA_8888) {
385        ALOGW("%s: Camera %d: Overriding format 0x%x to IMPLEMENTATION_DEFINED",
386              __FUNCTION__, mCameraId, format);
387        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
388    }
389
390    // TODO: add startConfigure/stopConfigure call to CameraDeviceBase
391    // this will make it so Camera3Device doesn't call configure_streams
392    // after each call, but only once we are done with all.
393
394    int streamId = -1;
395    res = mDevice->createStream(anw, width, height, format, &streamId);
396
397    if (res == OK) {
398        mStreamMap.add(bufferProducer->asBinder(), streamId);
399
400        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
401              __FUNCTION__, mCameraId, streamId);
402
403        /**
404         * Set the stream transform flags to automatically
405         * rotate the camera stream for preview use cases.
406         */
407        int32_t transform = 0;
408        res = getRotationTransformLocked(&transform);
409
410        if (res != OK) {
411            // Error logged by getRotationTransformLocked.
412            return res;
413        }
414
415        res = mDevice->setStreamTransform(streamId, transform);
416        if (res != OK) {
417            ALOGE("%s: Failed to set stream transform (stream id %d)",
418                  __FUNCTION__, streamId);
419            return res;
420        }
421
422        return streamId;
423    }
424
425    return res;
426}
427
428// Create a request object from a template.
429status_t CameraDeviceClient::createDefaultRequest(int templateId,
430                                                  /*out*/
431                                                  CameraMetadata* request)
432{
433    ATRACE_CALL();
434    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
435
436    status_t res;
437    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
438
439    Mutex::Autolock icl(mBinderSerializationLock);
440
441    if (!mDevice.get()) return DEAD_OBJECT;
442
443    CameraMetadata metadata;
444    if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
445        request != NULL) {
446
447        request->swap(metadata);
448    }
449
450    return res;
451}
452
453status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
454{
455    ATRACE_CALL();
456    ALOGV("%s", __FUNCTION__);
457
458    status_t res = OK;
459
460    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
461
462    Mutex::Autolock icl(mBinderSerializationLock);
463
464    if (!mDevice.get()) return DEAD_OBJECT;
465
466    if (info != NULL) {
467        *info = mDevice->info(); // static camera metadata
468        // TODO: merge with device-specific camera metadata
469    }
470
471    return res;
472}
473
474status_t CameraDeviceClient::waitUntilIdle()
475{
476    ATRACE_CALL();
477    ALOGV("%s", __FUNCTION__);
478
479    status_t res = OK;
480    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
481
482    Mutex::Autolock icl(mBinderSerializationLock);
483
484    if (!mDevice.get()) return DEAD_OBJECT;
485
486    // FIXME: Also need check repeating burst.
487    if (!mStreamingRequestList.isEmpty()) {
488        ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
489              __FUNCTION__, mCameraId);
490        return INVALID_OPERATION;
491    }
492    res = mDevice->waitUntilDrained();
493    ALOGV("%s Done", __FUNCTION__);
494
495    return res;
496}
497
498status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) {
499    ATRACE_CALL();
500    ALOGV("%s", __FUNCTION__);
501
502    status_t res = OK;
503    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
504
505    Mutex::Autolock icl(mBinderSerializationLock);
506
507    if (!mDevice.get()) return DEAD_OBJECT;
508
509    mStreamingRequestList.clear();
510    return mDevice->flush(lastFrameNumber);
511}
512
513status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
514    String8 result;
515    result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n",
516            mCameraId,
517            getRemoteCallback()->asBinder().get(),
518            mClientPid);
519    result.append("  State: ");
520
521    // TODO: print dynamic/request section from most recent requests
522    mFrameProcessor->dump(fd, args);
523
524    return dumpDevice(fd, args);
525}
526
527void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
528                                     const CaptureResultExtras& resultExtras) {
529    // Thread safe. Don't bother locking.
530    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
531
532    if (remoteCb != 0) {
533        remoteCb->onDeviceError(errorCode, resultExtras);
534    }
535}
536
537void CameraDeviceClient::notifyIdle() {
538    // Thread safe. Don't bother locking.
539    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
540
541    if (remoteCb != 0) {
542        remoteCb->onDeviceIdle();
543    }
544}
545
546void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
547        nsecs_t timestamp) {
548    // Thread safe. Don't bother locking.
549    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
550    if (remoteCb != 0) {
551        remoteCb->onCaptureStarted(resultExtras, timestamp);
552    }
553}
554
555// TODO: refactor the code below this with IProCameraUser.
556// it's 100% copy-pasted, so lets not change it right now to make it easier.
557
558void CameraDeviceClient::detachDevice() {
559    if (mDevice == 0) return;
560
561    ALOGV("Camera %d: Stopping processors", mCameraId);
562
563    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
564                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
565                                    /*listener*/this);
566    mFrameProcessor->requestExit();
567    ALOGV("Camera %d: Waiting for threads", mCameraId);
568    mFrameProcessor->join();
569    ALOGV("Camera %d: Disconnecting device", mCameraId);
570
571    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
572    {
573        mDevice->clearStreamingRequest();
574
575        status_t code;
576        if ((code = mDevice->waitUntilDrained()) != OK) {
577            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
578                  code);
579        }
580    }
581
582    Camera2ClientBase::detachDevice();
583}
584
585/** Device-related methods */
586void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
587    ATRACE_CALL();
588    ALOGV("%s", __FUNCTION__);
589
590    // Thread-safe. No lock necessary.
591    sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
592    if (remoteCb != NULL) {
593        remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
594    }
595}
596
597// TODO: move to Camera2ClientBase
598bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
599
600    const int pid = IPCThreadState::self()->getCallingPid();
601    const int selfPid = getpid();
602    camera_metadata_entry_t entry;
603
604    /**
605     * Mixin default important security values
606     * - android.led.transmit = defaulted ON
607     */
608    CameraMetadata staticInfo = mDevice->info();
609    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
610    for(size_t i = 0; i < entry.count; ++i) {
611        uint8_t led = entry.data.u8[i];
612
613        switch(led) {
614            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
615                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
616                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
617                    metadata.update(ANDROID_LED_TRANSMIT,
618                                    &transmitDefault, 1);
619                }
620                break;
621            }
622        }
623    }
624
625    // We can do anything!
626    if (pid == selfPid) {
627        return true;
628    }
629
630    /**
631     * Permission check special fields in the request
632     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
633     */
634    entry = metadata.find(ANDROID_LED_TRANSMIT);
635    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
636        String16 permissionString =
637            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
638        if (!checkCallingPermission(permissionString)) {
639            const int uid = IPCThreadState::self()->getCallingUid();
640            ALOGE("Permission Denial: "
641                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
642            return false;
643        }
644    }
645
646    return true;
647}
648
649status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
650    ALOGV("%s: begin", __FUNCTION__);
651
652    const CameraMetadata& staticInfo = mDevice->info();
653    return CameraUtils::getRotationTransform(staticInfo, transform);
654}
655
656} // namespace android
657