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