CameraDeviceClient.cpp revision 28c9b6f298134624cb52b1af4ed8716dddb983d3
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    res = mDevice->createStream(anw, width, height, format, &streamId);
388
389    if (res == OK) {
390        mStreamMap.add(bufferProducer->asBinder(), streamId);
391
392        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
393              __FUNCTION__, mCameraId, streamId);
394
395        /**
396         * Set the stream transform flags to automatically
397         * rotate the camera stream for preview use cases.
398         */
399        int32_t transform = 0;
400        res = getRotationTransformLocked(&transform);
401
402        if (res != OK) {
403            // Error logged by getRotationTransformLocked.
404            return res;
405        }
406
407        res = mDevice->setStreamTransform(streamId, transform);
408        if (res != OK) {
409            ALOGE("%s: Failed to set stream transform (stream id %d)",
410                  __FUNCTION__, streamId);
411            return res;
412        }
413
414        return streamId;
415    }
416
417    return res;
418}
419
420// Create a request object from a template.
421status_t CameraDeviceClient::createDefaultRequest(int templateId,
422                                                  /*out*/
423                                                  CameraMetadata* request)
424{
425    ATRACE_CALL();
426    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
427
428    status_t res;
429    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
430
431    Mutex::Autolock icl(mBinderSerializationLock);
432
433    if (!mDevice.get()) return DEAD_OBJECT;
434
435    CameraMetadata metadata;
436    if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
437        request != NULL) {
438
439        request->swap(metadata);
440    }
441
442    return res;
443}
444
445status_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
446{
447    ATRACE_CALL();
448    ALOGV("%s", __FUNCTION__);
449
450    status_t res = OK;
451
452    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
453
454    Mutex::Autolock icl(mBinderSerializationLock);
455
456    if (!mDevice.get()) return DEAD_OBJECT;
457
458    if (info != NULL) {
459        *info = mDevice->info(); // static camera metadata
460        // TODO: merge with device-specific camera metadata
461    }
462
463    return res;
464}
465
466status_t CameraDeviceClient::waitUntilIdle()
467{
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    // FIXME: Also need check repeating burst.
479    if (!mStreamingRequestList.isEmpty()) {
480        ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
481              __FUNCTION__, mCameraId);
482        return INVALID_OPERATION;
483    }
484    res = mDevice->waitUntilDrained();
485    ALOGV("%s Done", __FUNCTION__);
486
487    return res;
488}
489
490status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) {
491    ATRACE_CALL();
492    ALOGV("%s", __FUNCTION__);
493
494    status_t res = OK;
495    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
496
497    Mutex::Autolock icl(mBinderSerializationLock);
498
499    if (!mDevice.get()) return DEAD_OBJECT;
500
501    mStreamingRequestList.clear();
502    return mDevice->flush(lastFrameNumber);
503}
504
505status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
506    String8 result;
507    result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n",
508            mCameraId,
509            getRemoteCallback()->asBinder().get(),
510            mClientPid);
511    result.append("  State: ");
512
513    // TODO: print dynamic/request section from most recent requests
514    mFrameProcessor->dump(fd, args);
515
516    return dumpDevice(fd, args);
517}
518
519void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
520                                     const CaptureResultExtras& resultExtras) {
521    // Thread safe. Don't bother locking.
522    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
523
524    if (remoteCb != 0) {
525        remoteCb->onDeviceError(errorCode, resultExtras);
526    }
527}
528
529void CameraDeviceClient::notifyIdle() {
530    // Thread safe. Don't bother locking.
531    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
532
533    if (remoteCb != 0) {
534        remoteCb->onDeviceIdle();
535    }
536}
537
538void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
539        nsecs_t timestamp) {
540    // Thread safe. Don't bother locking.
541    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
542    if (remoteCb != 0) {
543        remoteCb->onCaptureStarted(resultExtras, timestamp);
544    }
545}
546
547// TODO: refactor the code below this with IProCameraUser.
548// it's 100% copy-pasted, so lets not change it right now to make it easier.
549
550void CameraDeviceClient::detachDevice() {
551    if (mDevice == 0) return;
552
553    ALOGV("Camera %d: Stopping processors", mCameraId);
554
555    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
556                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
557                                    /*listener*/this);
558    mFrameProcessor->requestExit();
559    ALOGV("Camera %d: Waiting for threads", mCameraId);
560    mFrameProcessor->join();
561    ALOGV("Camera %d: Disconnecting device", mCameraId);
562
563    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
564    {
565        mDevice->clearStreamingRequest();
566
567        status_t code;
568        if ((code = mDevice->waitUntilDrained()) != OK) {
569            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
570                  code);
571        }
572    }
573
574    Camera2ClientBase::detachDevice();
575}
576
577/** Device-related methods */
578void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
579    ATRACE_CALL();
580    ALOGV("%s", __FUNCTION__);
581
582    // Thread-safe. No lock necessary.
583    sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
584    if (remoteCb != NULL) {
585        remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
586    }
587}
588
589// TODO: move to Camera2ClientBase
590bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
591
592    const int pid = IPCThreadState::self()->getCallingPid();
593    const int selfPid = getpid();
594    camera_metadata_entry_t entry;
595
596    /**
597     * Mixin default important security values
598     * - android.led.transmit = defaulted ON
599     */
600    CameraMetadata staticInfo = mDevice->info();
601    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
602    for(size_t i = 0; i < entry.count; ++i) {
603        uint8_t led = entry.data.u8[i];
604
605        switch(led) {
606            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
607                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
608                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
609                    metadata.update(ANDROID_LED_TRANSMIT,
610                                    &transmitDefault, 1);
611                }
612                break;
613            }
614        }
615    }
616
617    // We can do anything!
618    if (pid == selfPid) {
619        return true;
620    }
621
622    /**
623     * Permission check special fields in the request
624     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
625     */
626    entry = metadata.find(ANDROID_LED_TRANSMIT);
627    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
628        String16 permissionString =
629            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
630        if (!checkCallingPermission(permissionString)) {
631            const int uid = IPCThreadState::self()->getCallingUid();
632            ALOGE("Permission Denial: "
633                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
634            return false;
635        }
636    }
637
638    return true;
639}
640
641status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
642    ALOGV("%s: begin", __FUNCTION__);
643
644    const CameraMetadata& staticInfo = mDevice->info();
645    return CameraUtils::getRotationTransform(staticInfo, transform);
646}
647
648} // namespace android
649