Camera3Device.cpp revision 7ef20390ba4375c4b08edd14923846086987a8c8
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 "Camera3-Device"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20//#define LOG_NNDEBUG 0  // Per-frame verbose logging
21
22#ifdef LOG_NNDEBUG
23#define ALOGVV(...) ALOGV(__VA_ARGS__)
24#else
25#define ALOGVV(...) ((void)0)
26#endif
27
28// Convenience macro for transient errors
29#define CLOGE(fmt, ...) ALOGE("Camera %d: %s: " fmt, mId, __FUNCTION__, \
30            ##__VA_ARGS__)
31
32// Convenience macros for transitioning to the error state
33#define SET_ERR(fmt, ...) setErrorState(   \
34    "%s: " fmt, __FUNCTION__,              \
35    ##__VA_ARGS__)
36#define SET_ERR_L(fmt, ...) setErrorStateLocked( \
37    "%s: " fmt, __FUNCTION__,                    \
38    ##__VA_ARGS__)
39
40#include <inttypes.h>
41
42#include <utils/Log.h>
43#include <utils/Trace.h>
44#include <utils/Timers.h>
45
46#include "utils/CameraTraces.h"
47#include "device3/Camera3Device.h"
48#include "device3/Camera3OutputStream.h"
49#include "device3/Camera3InputStream.h"
50#include "device3/Camera3ZslStream.h"
51
52using namespace android::camera3;
53
54namespace android {
55
56Camera3Device::Camera3Device(int id):
57        mId(id),
58        mHal3Device(NULL),
59        mStatus(STATUS_UNINITIALIZED),
60        mUsePartialResultQuirk(false),
61        mNextResultFrameNumber(0),
62        mNextShutterFrameNumber(0),
63        mListener(NULL)
64{
65    ATRACE_CALL();
66    camera3_callback_ops::notify = &sNotify;
67    camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
68    ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
69}
70
71Camera3Device::~Camera3Device()
72{
73    ATRACE_CALL();
74    ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
75    disconnect();
76}
77
78int Camera3Device::getId() const {
79    return mId;
80}
81
82/**
83 * CameraDeviceBase interface
84 */
85
86status_t Camera3Device::initialize(camera_module_t *module)
87{
88    ATRACE_CALL();
89    Mutex::Autolock il(mInterfaceLock);
90    Mutex::Autolock l(mLock);
91
92    ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
93    if (mStatus != STATUS_UNINITIALIZED) {
94        CLOGE("Already initialized!");
95        return INVALID_OPERATION;
96    }
97
98    /** Open HAL device */
99
100    status_t res;
101    String8 deviceName = String8::format("%d", mId);
102
103    camera3_device_t *device;
104
105    ATRACE_BEGIN("camera3->open");
106    res = module->common.methods->open(&module->common, deviceName.string(),
107            reinterpret_cast<hw_device_t**>(&device));
108    ATRACE_END();
109
110    if (res != OK) {
111        SET_ERR_L("Could not open camera: %s (%d)", strerror(-res), res);
112        return res;
113    }
114
115    /** Cross-check device version */
116
117    if (device->common.version < CAMERA_DEVICE_API_VERSION_3_0) {
118        SET_ERR_L("Could not open camera: "
119                "Camera device should be at least %x, reports %x instead",
120                CAMERA_DEVICE_API_VERSION_3_0,
121                device->common.version);
122        device->common.close(&device->common);
123        return BAD_VALUE;
124    }
125
126    camera_info info;
127    res = module->get_camera_info(mId, &info);
128    if (res != OK) return res;
129
130    if (info.device_version != device->common.version) {
131        SET_ERR_L("HAL reporting mismatched camera_info version (%x)"
132                " and device version (%x).",
133                info.device_version, device->common.version);
134        device->common.close(&device->common);
135        return BAD_VALUE;
136    }
137
138    /** Initialize device with callback functions */
139
140    ATRACE_BEGIN("camera3->initialize");
141    res = device->ops->initialize(device, this);
142    ATRACE_END();
143
144    if (res != OK) {
145        SET_ERR_L("Unable to initialize HAL device: %s (%d)",
146                strerror(-res), res);
147        device->common.close(&device->common);
148        return BAD_VALUE;
149    }
150
151    /** Start up status tracker thread */
152    mStatusTracker = new StatusTracker(this);
153    res = mStatusTracker->run(String8::format("C3Dev-%d-Status", mId).string());
154    if (res != OK) {
155        SET_ERR_L("Unable to start status tracking thread: %s (%d)",
156                strerror(-res), res);
157        device->common.close(&device->common);
158        mStatusTracker.clear();
159        return res;
160    }
161
162    /** Start up request queue thread */
163
164    mRequestThread = new RequestThread(this, mStatusTracker, device);
165    res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
166    if (res != OK) {
167        SET_ERR_L("Unable to start request queue thread: %s (%d)",
168                strerror(-res), res);
169        device->common.close(&device->common);
170        mRequestThread.clear();
171        return res;
172    }
173
174    /** Everything is good to go */
175
176    mDeviceInfo = info.static_camera_characteristics;
177    mHal3Device = device;
178    mStatus = STATUS_UNCONFIGURED;
179    mNextStreamId = 0;
180    mNeedConfig = true;
181    mPauseStateNotify = false;
182
183    /** Check for quirks */
184
185    // Will the HAL be sending in early partial result metadata?
186    camera_metadata_entry partialResultsQuirk =
187            mDeviceInfo.find(ANDROID_QUIRKS_USE_PARTIAL_RESULT);
188    if (partialResultsQuirk.count > 0 && partialResultsQuirk.data.u8[0] == 1) {
189        mUsePartialResultQuirk = true;
190    }
191
192    return OK;
193}
194
195status_t Camera3Device::disconnect() {
196    ATRACE_CALL();
197    Mutex::Autolock il(mInterfaceLock);
198
199    ALOGV("%s: E", __FUNCTION__);
200
201    status_t res = OK;
202
203    {
204        Mutex::Autolock l(mLock);
205        if (mStatus == STATUS_UNINITIALIZED) return res;
206
207        if (mStatus == STATUS_ACTIVE ||
208                (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
209            res = mRequestThread->clearRepeatingRequests();
210            if (res != OK) {
211                SET_ERR_L("Can't stop streaming");
212                // Continue to close device even in case of error
213            } else {
214                res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
215                if (res != OK) {
216                    SET_ERR_L("Timeout waiting for HAL to drain");
217                    // Continue to close device even in case of error
218                }
219            }
220        }
221
222        if (mStatus == STATUS_ERROR) {
223            CLOGE("Shutting down in an error state");
224        }
225
226        if (mStatusTracker != NULL) {
227            mStatusTracker->requestExit();
228        }
229
230        if (mRequestThread != NULL) {
231            mRequestThread->requestExit();
232        }
233
234        mOutputStreams.clear();
235        mInputStream.clear();
236    }
237
238    // Joining done without holding mLock, otherwise deadlocks may ensue
239    // as the threads try to access parent state
240    if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
241        // HAL may be in a bad state, so waiting for request thread
242        // (which may be stuck in the HAL processCaptureRequest call)
243        // could be dangerous.
244        mRequestThread->join();
245    }
246
247    if (mStatusTracker != NULL) {
248        mStatusTracker->join();
249    }
250
251    {
252        Mutex::Autolock l(mLock);
253
254        mRequestThread.clear();
255        mStatusTracker.clear();
256
257        if (mHal3Device != NULL) {
258            ATRACE_BEGIN("camera3->close");
259            mHal3Device->common.close(&mHal3Device->common);
260            ATRACE_END();
261            mHal3Device = NULL;
262        }
263
264        mStatus = STATUS_UNINITIALIZED;
265    }
266
267    ALOGV("%s: X", __FUNCTION__);
268    return res;
269}
270
271// For dumping/debugging only -
272// try to acquire a lock a few times, eventually give up to proceed with
273// debug/dump operations
274bool Camera3Device::tryLockSpinRightRound(Mutex& lock) {
275    bool gotLock = false;
276    for (size_t i = 0; i < kDumpLockAttempts; ++i) {
277        if (lock.tryLock() == NO_ERROR) {
278            gotLock = true;
279            break;
280        } else {
281            usleep(kDumpSleepDuration);
282        }
283    }
284    return gotLock;
285}
286
287status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
288    ATRACE_CALL();
289    (void)args;
290
291    // Try to lock, but continue in case of failure (to avoid blocking in
292    // deadlocks)
293    bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock);
294    bool gotLock = tryLockSpinRightRound(mLock);
295
296    ALOGW_IF(!gotInterfaceLock,
297            "Camera %d: %s: Unable to lock interface lock, proceeding anyway",
298            mId, __FUNCTION__);
299    ALOGW_IF(!gotLock,
300            "Camera %d: %s: Unable to lock main lock, proceeding anyway",
301            mId, __FUNCTION__);
302
303    String8 lines;
304
305    const char *status =
306            mStatus == STATUS_ERROR         ? "ERROR" :
307            mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
308            mStatus == STATUS_UNCONFIGURED  ? "UNCONFIGURED" :
309            mStatus == STATUS_CONFIGURED    ? "CONFIGURED" :
310            mStatus == STATUS_ACTIVE        ? "ACTIVE" :
311            "Unknown";
312
313    lines.appendFormat("    Device status: %s\n", status);
314    if (mStatus == STATUS_ERROR) {
315        lines.appendFormat("    Error cause: %s\n", mErrorCause.string());
316    }
317    lines.appendFormat("    Stream configuration:\n");
318
319    if (mInputStream != NULL) {
320        write(fd, lines.string(), lines.size());
321        mInputStream->dump(fd, args);
322    } else {
323        lines.appendFormat("      No input stream.\n");
324        write(fd, lines.string(), lines.size());
325    }
326    for (size_t i = 0; i < mOutputStreams.size(); i++) {
327        mOutputStreams[i]->dump(fd,args);
328    }
329
330    lines = String8("    In-flight requests:\n");
331    if (mInFlightMap.size() == 0) {
332        lines.append("      None\n");
333    } else {
334        for (size_t i = 0; i < mInFlightMap.size(); i++) {
335            InFlightRequest r = mInFlightMap.valueAt(i);
336            lines.appendFormat("      Frame %d |  Timestamp: %" PRId64 ", metadata"
337                    " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
338                    r.captureTimestamp, r.haveResultMetadata ? "true" : "false",
339                    r.numBuffersLeft);
340        }
341    }
342    write(fd, lines.string(), lines.size());
343
344    {
345        lines = String8("    Last request sent:\n");
346        write(fd, lines.string(), lines.size());
347
348        CameraMetadata lastRequest = getLatestRequestLocked();
349        lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
350    }
351
352    if (mHal3Device != NULL) {
353        lines = String8("    HAL device dump:\n");
354        write(fd, lines.string(), lines.size());
355        mHal3Device->ops->dump(mHal3Device, fd);
356    }
357
358    if (gotLock) mLock.unlock();
359    if (gotInterfaceLock) mInterfaceLock.unlock();
360
361    return OK;
362}
363
364const CameraMetadata& Camera3Device::info() const {
365    ALOGVV("%s: E", __FUNCTION__);
366    if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
367                    mStatus == STATUS_ERROR)) {
368        ALOGW("%s: Access to static info %s!", __FUNCTION__,
369                mStatus == STATUS_ERROR ?
370                "when in error state" : "before init");
371    }
372    return mDeviceInfo;
373}
374
375status_t Camera3Device::checkStatusOkToCaptureLocked() {
376    switch (mStatus) {
377        case STATUS_ERROR:
378            CLOGE("Device has encountered a serious error");
379            return INVALID_OPERATION;
380        case STATUS_UNINITIALIZED:
381            CLOGE("Device not initialized");
382            return INVALID_OPERATION;
383        case STATUS_UNCONFIGURED:
384        case STATUS_CONFIGURED:
385        case STATUS_ACTIVE:
386            // OK
387            break;
388        default:
389            SET_ERR_L("Unexpected status: %d", mStatus);
390            return INVALID_OPERATION;
391    }
392    return OK;
393}
394
395status_t Camera3Device::convertMetadataListToRequestListLocked(
396        const List<const CameraMetadata> &metadataList, RequestList *requestList) {
397    if (requestList == NULL) {
398        CLOGE("requestList cannot be NULL.");
399        return BAD_VALUE;
400    }
401
402    int32_t burstId = 0;
403    for (List<const CameraMetadata>::const_iterator it = metadataList.begin();
404            it != metadataList.end(); ++it) {
405        sp<CaptureRequest> newRequest = setUpRequestLocked(*it);
406        if (newRequest == 0) {
407            CLOGE("Can't create capture request");
408            return BAD_VALUE;
409        }
410
411        // Setup burst Id and request Id
412        newRequest->mResultExtras.burstId = burstId++;
413        if (it->exists(ANDROID_REQUEST_ID)) {
414            if (it->find(ANDROID_REQUEST_ID).count == 0) {
415                CLOGE("RequestID entry exists; but must not be empty in metadata");
416                return BAD_VALUE;
417            }
418            newRequest->mResultExtras.requestId = it->find(ANDROID_REQUEST_ID).data.i32[0];
419        } else {
420            CLOGE("RequestID does not exist in metadata");
421            return BAD_VALUE;
422        }
423
424        requestList->push_back(newRequest);
425
426        ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId);
427    }
428    return OK;
429}
430
431status_t Camera3Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
432    ATRACE_CALL();
433
434    List<const CameraMetadata> requests;
435    requests.push_back(request);
436    return captureList(requests, /*lastFrameNumber*/NULL);
437}
438
439status_t Camera3Device::submitRequestsHelper(
440        const List<const CameraMetadata> &requests, bool repeating,
441        /*out*/
442        int64_t *lastFrameNumber) {
443    ATRACE_CALL();
444    Mutex::Autolock il(mInterfaceLock);
445    Mutex::Autolock l(mLock);
446
447    status_t res = checkStatusOkToCaptureLocked();
448    if (res != OK) {
449        // error logged by previous call
450        return res;
451    }
452
453    RequestList requestList;
454
455    res = convertMetadataListToRequestListLocked(requests, /*out*/&requestList);
456    if (res != OK) {
457        // error logged by previous call
458        return res;
459    }
460
461    if (repeating) {
462        res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
463    } else {
464        res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
465    }
466
467    if (res == OK) {
468        waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
469        if (res != OK) {
470            SET_ERR_L("Can't transition to active in %f seconds!",
471                    kActiveTimeout/1e9);
472        }
473        ALOGV("Camera %d: Capture request %" PRId32 " enqueued", mId,
474              (*(requestList.begin()))->mResultExtras.requestId);
475    } else {
476        CLOGE("Cannot queue request. Impossible.");
477        return BAD_VALUE;
478    }
479
480    return res;
481}
482
483status_t Camera3Device::captureList(const List<const CameraMetadata> &requests,
484                                    int64_t *lastFrameNumber) {
485    ATRACE_CALL();
486
487    return submitRequestsHelper(requests, /*repeating*/false, lastFrameNumber);
488}
489
490status_t Camera3Device::setStreamingRequest(const CameraMetadata &request,
491                                            int64_t* /*lastFrameNumber*/) {
492    ATRACE_CALL();
493
494    List<const CameraMetadata> requests;
495    requests.push_back(request);
496    return setStreamingRequestList(requests, /*lastFrameNumber*/NULL);
497}
498
499status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
500                                                int64_t *lastFrameNumber) {
501    ATRACE_CALL();
502
503    return submitRequestsHelper(requests, /*repeating*/true, lastFrameNumber);
504}
505
506sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
507        const CameraMetadata &request) {
508    status_t res;
509
510    if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
511        res = configureStreamsLocked();
512        if (res != OK) {
513            SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res);
514            return NULL;
515        }
516        if (mStatus == STATUS_UNCONFIGURED) {
517            CLOGE("No streams configured");
518            return NULL;
519        }
520    }
521
522    sp<CaptureRequest> newRequest = createCaptureRequest(request);
523    return newRequest;
524}
525
526status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) {
527    ATRACE_CALL();
528    Mutex::Autolock il(mInterfaceLock);
529    Mutex::Autolock l(mLock);
530
531    switch (mStatus) {
532        case STATUS_ERROR:
533            CLOGE("Device has encountered a serious error");
534            return INVALID_OPERATION;
535        case STATUS_UNINITIALIZED:
536            CLOGE("Device not initialized");
537            return INVALID_OPERATION;
538        case STATUS_UNCONFIGURED:
539        case STATUS_CONFIGURED:
540        case STATUS_ACTIVE:
541            // OK
542            break;
543        default:
544            SET_ERR_L("Unexpected status: %d", mStatus);
545            return INVALID_OPERATION;
546    }
547    ALOGV("Camera %d: Clearing repeating request", mId);
548
549    return mRequestThread->clearRepeatingRequests(lastFrameNumber);
550}
551
552status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
553    ATRACE_CALL();
554    Mutex::Autolock il(mInterfaceLock);
555
556    return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
557}
558
559status_t Camera3Device::createInputStream(
560        uint32_t width, uint32_t height, int format, int *id) {
561    ATRACE_CALL();
562    Mutex::Autolock il(mInterfaceLock);
563    Mutex::Autolock l(mLock);
564    ALOGV("Camera %d: Creating new input stream %d: %d x %d, format %d",
565            mId, mNextStreamId, width, height, format);
566
567    status_t res;
568    bool wasActive = false;
569
570    switch (mStatus) {
571        case STATUS_ERROR:
572            ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
573            return INVALID_OPERATION;
574        case STATUS_UNINITIALIZED:
575            ALOGE("%s: Device not initialized", __FUNCTION__);
576            return INVALID_OPERATION;
577        case STATUS_UNCONFIGURED:
578        case STATUS_CONFIGURED:
579            // OK
580            break;
581        case STATUS_ACTIVE:
582            ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
583            res = internalPauseAndWaitLocked();
584            if (res != OK) {
585                SET_ERR_L("Can't pause captures to reconfigure streams!");
586                return res;
587            }
588            wasActive = true;
589            break;
590        default:
591            SET_ERR_L("%s: Unexpected status: %d", mStatus);
592            return INVALID_OPERATION;
593    }
594    assert(mStatus != STATUS_ACTIVE);
595
596    if (mInputStream != 0) {
597        ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
598        return INVALID_OPERATION;
599    }
600
601    sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
602                width, height, format);
603    newStream->setStatusTracker(mStatusTracker);
604
605    mInputStream = newStream;
606
607    *id = mNextStreamId++;
608
609    // Continue captures if active at start
610    if (wasActive) {
611        ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
612        res = configureStreamsLocked();
613        if (res != OK) {
614            ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
615                    __FUNCTION__, mNextStreamId, strerror(-res), res);
616            return res;
617        }
618        internalResumeLocked();
619    }
620
621    ALOGV("Camera %d: Created input stream", mId);
622    return OK;
623}
624
625
626status_t Camera3Device::createZslStream(
627            uint32_t width, uint32_t height,
628            int depth,
629            /*out*/
630            int *id,
631            sp<Camera3ZslStream>* zslStream) {
632    ATRACE_CALL();
633    Mutex::Autolock il(mInterfaceLock);
634    Mutex::Autolock l(mLock);
635    ALOGV("Camera %d: Creating ZSL stream %d: %d x %d, depth %d",
636            mId, mNextStreamId, width, height, depth);
637
638    status_t res;
639    bool wasActive = false;
640
641    switch (mStatus) {
642        case STATUS_ERROR:
643            ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
644            return INVALID_OPERATION;
645        case STATUS_UNINITIALIZED:
646            ALOGE("%s: Device not initialized", __FUNCTION__);
647            return INVALID_OPERATION;
648        case STATUS_UNCONFIGURED:
649        case STATUS_CONFIGURED:
650            // OK
651            break;
652        case STATUS_ACTIVE:
653            ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
654            res = internalPauseAndWaitLocked();
655            if (res != OK) {
656                SET_ERR_L("Can't pause captures to reconfigure streams!");
657                return res;
658            }
659            wasActive = true;
660            break;
661        default:
662            SET_ERR_L("Unexpected status: %d", mStatus);
663            return INVALID_OPERATION;
664    }
665    assert(mStatus != STATUS_ACTIVE);
666
667    if (mInputStream != 0) {
668        ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
669        return INVALID_OPERATION;
670    }
671
672    sp<Camera3ZslStream> newStream = new Camera3ZslStream(mNextStreamId,
673                width, height, depth);
674    newStream->setStatusTracker(mStatusTracker);
675
676    res = mOutputStreams.add(mNextStreamId, newStream);
677    if (res < 0) {
678        ALOGE("%s: Can't add new stream to set: %s (%d)",
679                __FUNCTION__, strerror(-res), res);
680        return res;
681    }
682    mInputStream = newStream;
683
684    mNeedConfig = true;
685
686    *id = mNextStreamId++;
687    *zslStream = newStream;
688
689    // Continue captures if active at start
690    if (wasActive) {
691        ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
692        res = configureStreamsLocked();
693        if (res != OK) {
694            ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
695                    __FUNCTION__, mNextStreamId, strerror(-res), res);
696            return res;
697        }
698        internalResumeLocked();
699    }
700
701    ALOGV("Camera %d: Created ZSL stream", mId);
702    return OK;
703}
704
705status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
706        uint32_t width, uint32_t height, int format, size_t size, int *id) {
707    ATRACE_CALL();
708    Mutex::Autolock il(mInterfaceLock);
709    Mutex::Autolock l(mLock);
710    ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, size %zu",
711            mId, mNextStreamId, width, height, format, size);
712
713    status_t res;
714    bool wasActive = false;
715
716    switch (mStatus) {
717        case STATUS_ERROR:
718            CLOGE("Device has encountered a serious error");
719            return INVALID_OPERATION;
720        case STATUS_UNINITIALIZED:
721            CLOGE("Device not initialized");
722            return INVALID_OPERATION;
723        case STATUS_UNCONFIGURED:
724        case STATUS_CONFIGURED:
725            // OK
726            break;
727        case STATUS_ACTIVE:
728            ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
729            res = internalPauseAndWaitLocked();
730            if (res != OK) {
731                SET_ERR_L("Can't pause captures to reconfigure streams!");
732                return res;
733            }
734            wasActive = true;
735            break;
736        default:
737            SET_ERR_L("Unexpected status: %d", mStatus);
738            return INVALID_OPERATION;
739    }
740    assert(mStatus != STATUS_ACTIVE);
741
742    sp<Camera3OutputStream> newStream;
743    if (format == HAL_PIXEL_FORMAT_BLOB) {
744        newStream = new Camera3OutputStream(mNextStreamId, consumer,
745                width, height, size, format);
746    } else {
747        newStream = new Camera3OutputStream(mNextStreamId, consumer,
748                width, height, format);
749    }
750    newStream->setStatusTracker(mStatusTracker);
751
752    res = mOutputStreams.add(mNextStreamId, newStream);
753    if (res < 0) {
754        SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
755        return res;
756    }
757
758    *id = mNextStreamId++;
759    mNeedConfig = true;
760
761    // Continue captures if active at start
762    if (wasActive) {
763        ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
764        res = configureStreamsLocked();
765        if (res != OK) {
766            CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
767                    mNextStreamId, strerror(-res), res);
768            return res;
769        }
770        internalResumeLocked();
771    }
772    ALOGV("Camera %d: Created new stream", mId);
773    return OK;
774}
775
776status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
777    ATRACE_CALL();
778    (void)outputId; (void)id;
779
780    CLOGE("Unimplemented");
781    return INVALID_OPERATION;
782}
783
784
785status_t Camera3Device::getStreamInfo(int id,
786        uint32_t *width, uint32_t *height, uint32_t *format) {
787    ATRACE_CALL();
788    Mutex::Autolock il(mInterfaceLock);
789    Mutex::Autolock l(mLock);
790
791    switch (mStatus) {
792        case STATUS_ERROR:
793            CLOGE("Device has encountered a serious error");
794            return INVALID_OPERATION;
795        case STATUS_UNINITIALIZED:
796            CLOGE("Device not initialized!");
797            return INVALID_OPERATION;
798        case STATUS_UNCONFIGURED:
799        case STATUS_CONFIGURED:
800        case STATUS_ACTIVE:
801            // OK
802            break;
803        default:
804            SET_ERR_L("Unexpected status: %d", mStatus);
805            return INVALID_OPERATION;
806    }
807
808    ssize_t idx = mOutputStreams.indexOfKey(id);
809    if (idx == NAME_NOT_FOUND) {
810        CLOGE("Stream %d is unknown", id);
811        return idx;
812    }
813
814    if (width) *width  = mOutputStreams[idx]->getWidth();
815    if (height) *height = mOutputStreams[idx]->getHeight();
816    if (format) *format = mOutputStreams[idx]->getFormat();
817
818    return OK;
819}
820
821status_t Camera3Device::setStreamTransform(int id,
822        int transform) {
823    ATRACE_CALL();
824    Mutex::Autolock il(mInterfaceLock);
825    Mutex::Autolock l(mLock);
826
827    switch (mStatus) {
828        case STATUS_ERROR:
829            CLOGE("Device has encountered a serious error");
830            return INVALID_OPERATION;
831        case STATUS_UNINITIALIZED:
832            CLOGE("Device not initialized");
833            return INVALID_OPERATION;
834        case STATUS_UNCONFIGURED:
835        case STATUS_CONFIGURED:
836        case STATUS_ACTIVE:
837            // OK
838            break;
839        default:
840            SET_ERR_L("Unexpected status: %d", mStatus);
841            return INVALID_OPERATION;
842    }
843
844    ssize_t idx = mOutputStreams.indexOfKey(id);
845    if (idx == NAME_NOT_FOUND) {
846        CLOGE("Stream %d does not exist",
847                id);
848        return BAD_VALUE;
849    }
850
851    return mOutputStreams.editValueAt(idx)->setTransform(transform);
852}
853
854status_t Camera3Device::deleteStream(int id) {
855    ATRACE_CALL();
856    Mutex::Autolock il(mInterfaceLock);
857    Mutex::Autolock l(mLock);
858    status_t res;
859
860    ALOGV("%s: Camera %d: Deleting stream %d", __FUNCTION__, mId, id);
861
862    // CameraDevice semantics require device to already be idle before
863    // deleteStream is called, unlike for createStream.
864    if (mStatus == STATUS_ACTIVE) {
865        ALOGV("%s: Camera %d: Device not idle", __FUNCTION__, mId);
866        return -EBUSY;
867    }
868
869    sp<Camera3StreamInterface> deletedStream;
870    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(id);
871    if (mInputStream != NULL && id == mInputStream->getId()) {
872        deletedStream = mInputStream;
873        mInputStream.clear();
874    } else {
875        if (outputStreamIdx == NAME_NOT_FOUND) {
876            CLOGE("Stream %d does not exist", id);
877            return BAD_VALUE;
878        }
879    }
880
881    // Delete output stream or the output part of a bi-directional stream.
882    if (outputStreamIdx != NAME_NOT_FOUND) {
883        deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
884        mOutputStreams.removeItem(id);
885    }
886
887    // Free up the stream endpoint so that it can be used by some other stream
888    res = deletedStream->disconnect();
889    if (res != OK) {
890        SET_ERR_L("Can't disconnect deleted stream %d", id);
891        // fall through since we want to still list the stream as deleted.
892    }
893    mDeletedStreams.add(deletedStream);
894    mNeedConfig = true;
895
896    return res;
897}
898
899status_t Camera3Device::deleteReprocessStream(int id) {
900    ATRACE_CALL();
901    (void)id;
902
903    CLOGE("Unimplemented");
904    return INVALID_OPERATION;
905}
906
907
908status_t Camera3Device::createDefaultRequest(int templateId,
909        CameraMetadata *request) {
910    ATRACE_CALL();
911    ALOGV("%s: for template %d", __FUNCTION__, templateId);
912    Mutex::Autolock il(mInterfaceLock);
913    Mutex::Autolock l(mLock);
914
915    switch (mStatus) {
916        case STATUS_ERROR:
917            CLOGE("Device has encountered a serious error");
918            return INVALID_OPERATION;
919        case STATUS_UNINITIALIZED:
920            CLOGE("Device is not initialized!");
921            return INVALID_OPERATION;
922        case STATUS_UNCONFIGURED:
923        case STATUS_CONFIGURED:
924        case STATUS_ACTIVE:
925            // OK
926            break;
927        default:
928            SET_ERR_L("Unexpected status: %d", mStatus);
929            return INVALID_OPERATION;
930    }
931
932    const camera_metadata_t *rawRequest;
933    ATRACE_BEGIN("camera3->construct_default_request_settings");
934    rawRequest = mHal3Device->ops->construct_default_request_settings(
935        mHal3Device, templateId);
936    ATRACE_END();
937    if (rawRequest == NULL) {
938        SET_ERR_L("HAL is unable to construct default settings for template %d",
939                templateId);
940        return DEAD_OBJECT;
941    }
942    *request = rawRequest;
943
944    return OK;
945}
946
947status_t Camera3Device::waitUntilDrained() {
948    ATRACE_CALL();
949    Mutex::Autolock il(mInterfaceLock);
950    Mutex::Autolock l(mLock);
951
952    return waitUntilDrainedLocked();
953}
954
955status_t Camera3Device::waitUntilDrainedLocked() {
956    switch (mStatus) {
957        case STATUS_UNINITIALIZED:
958        case STATUS_UNCONFIGURED:
959            ALOGV("%s: Already idle", __FUNCTION__);
960            return OK;
961        case STATUS_CONFIGURED:
962            // To avoid race conditions, check with tracker to be sure
963        case STATUS_ERROR:
964        case STATUS_ACTIVE:
965            // Need to verify shut down
966            break;
967        default:
968            SET_ERR_L("Unexpected status: %d",mStatus);
969            return INVALID_OPERATION;
970    }
971
972    ALOGV("%s: Camera %d: Waiting until idle", __FUNCTION__, mId);
973    status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
974    return res;
975}
976
977// Pause to reconfigure
978status_t Camera3Device::internalPauseAndWaitLocked() {
979    mRequestThread->setPaused(true);
980    mPauseStateNotify = true;
981
982    ALOGV("%s: Camera %d: Internal wait until idle", __FUNCTION__, mId);
983    status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
984    if (res != OK) {
985        SET_ERR_L("Can't idle device in %f seconds!",
986                kShutdownTimeout/1e9);
987    }
988
989    return res;
990}
991
992// Resume after internalPauseAndWaitLocked
993status_t Camera3Device::internalResumeLocked() {
994    status_t res;
995
996    mRequestThread->setPaused(false);
997
998    res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
999    if (res != OK) {
1000        SET_ERR_L("Can't transition to active in %f seconds!",
1001                kActiveTimeout/1e9);
1002    }
1003    mPauseStateNotify = false;
1004    return OK;
1005}
1006
1007status_t Camera3Device::waitUntilStateThenRelock(bool active,
1008        nsecs_t timeout) {
1009    status_t res = OK;
1010    if (active == (mStatus == STATUS_ACTIVE)) {
1011        // Desired state already reached
1012        return res;
1013    }
1014
1015    bool stateSeen = false;
1016    do {
1017        mRecentStatusUpdates.clear();
1018
1019        res = mStatusChanged.waitRelative(mLock, timeout);
1020        if (res != OK) break;
1021
1022        // Check state change history during wait
1023        for (size_t i = 0; i < mRecentStatusUpdates.size(); i++) {
1024            if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1025                stateSeen = true;
1026                break;
1027            }
1028        }
1029    } while (!stateSeen);
1030
1031    return res;
1032}
1033
1034
1035status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
1036    ATRACE_CALL();
1037    Mutex::Autolock l(mOutputLock);
1038
1039    if (listener != NULL && mListener != NULL) {
1040        ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1041    }
1042    mListener = listener;
1043
1044    return OK;
1045}
1046
1047bool Camera3Device::willNotify3A() {
1048    return false;
1049}
1050
1051status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
1052    status_t res;
1053    Mutex::Autolock l(mOutputLock);
1054
1055    while (mResultQueue.empty()) {
1056        res = mResultSignal.waitRelative(mOutputLock, timeout);
1057        if (res == TIMED_OUT) {
1058            return res;
1059        } else if (res != OK) {
1060            ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)",
1061                    __FUNCTION__, mId, timeout, strerror(-res), res);
1062            return res;
1063        }
1064    }
1065    return OK;
1066}
1067
1068status_t Camera3Device::getNextResult(CaptureResult *frame) {
1069    ATRACE_CALL();
1070    Mutex::Autolock l(mOutputLock);
1071
1072    if (mResultQueue.empty()) {
1073        return NOT_ENOUGH_DATA;
1074    }
1075
1076    if (frame == NULL) {
1077        ALOGE("%s: argument cannot be NULL", __FUNCTION__);
1078        return BAD_VALUE;
1079    }
1080
1081    CaptureResult &result = *(mResultQueue.begin());
1082    frame->mResultExtras = result.mResultExtras;
1083    frame->mMetadata.acquire(result.mMetadata);
1084    mResultQueue.erase(mResultQueue.begin());
1085
1086    return OK;
1087}
1088
1089status_t Camera3Device::triggerAutofocus(uint32_t id) {
1090    ATRACE_CALL();
1091    Mutex::Autolock il(mInterfaceLock);
1092
1093    ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
1094    // Mix-in this trigger into the next request and only the next request.
1095    RequestTrigger trigger[] = {
1096        {
1097            ANDROID_CONTROL_AF_TRIGGER,
1098            ANDROID_CONTROL_AF_TRIGGER_START
1099        },
1100        {
1101            ANDROID_CONTROL_AF_TRIGGER_ID,
1102            static_cast<int32_t>(id)
1103        },
1104    };
1105
1106    return mRequestThread->queueTrigger(trigger,
1107                                        sizeof(trigger)/sizeof(trigger[0]));
1108}
1109
1110status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
1111    ATRACE_CALL();
1112    Mutex::Autolock il(mInterfaceLock);
1113
1114    ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
1115    // Mix-in this trigger into the next request and only the next request.
1116    RequestTrigger trigger[] = {
1117        {
1118            ANDROID_CONTROL_AF_TRIGGER,
1119            ANDROID_CONTROL_AF_TRIGGER_CANCEL
1120        },
1121        {
1122            ANDROID_CONTROL_AF_TRIGGER_ID,
1123            static_cast<int32_t>(id)
1124        },
1125    };
1126
1127    return mRequestThread->queueTrigger(trigger,
1128                                        sizeof(trigger)/sizeof(trigger[0]));
1129}
1130
1131status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
1132    ATRACE_CALL();
1133    Mutex::Autolock il(mInterfaceLock);
1134
1135    ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
1136    // Mix-in this trigger into the next request and only the next request.
1137    RequestTrigger trigger[] = {
1138        {
1139            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1140            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
1141        },
1142        {
1143            ANDROID_CONTROL_AE_PRECAPTURE_ID,
1144            static_cast<int32_t>(id)
1145        },
1146    };
1147
1148    return mRequestThread->queueTrigger(trigger,
1149                                        sizeof(trigger)/sizeof(trigger[0]));
1150}
1151
1152status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
1153        buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
1154    ATRACE_CALL();
1155    (void)reprocessStreamId; (void)buffer; (void)listener;
1156
1157    CLOGE("Unimplemented");
1158    return INVALID_OPERATION;
1159}
1160
1161status_t Camera3Device::flush(int64_t *frameNumber) {
1162    ATRACE_CALL();
1163    ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
1164    Mutex::Autolock il(mInterfaceLock);
1165
1166    {
1167        Mutex::Autolock l(mLock);
1168        mRequestThread->clear(/*out*/frameNumber);
1169    }
1170
1171    status_t res;
1172    if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) {
1173        res = mHal3Device->ops->flush(mHal3Device);
1174    } else {
1175        Mutex::Autolock l(mLock);
1176        res = waitUntilDrainedLocked();
1177    }
1178
1179    return res;
1180}
1181
1182/**
1183 * Methods called by subclasses
1184 */
1185
1186void Camera3Device::notifyStatus(bool idle) {
1187    {
1188        // Need mLock to safely update state and synchronize to current
1189        // state of methods in flight.
1190        Mutex::Autolock l(mLock);
1191        // We can get various system-idle notices from the status tracker
1192        // while starting up. Only care about them if we've actually sent
1193        // in some requests recently.
1194        if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
1195            return;
1196        }
1197        ALOGV("%s: Camera %d: Now %s", __FUNCTION__, mId,
1198                idle ? "idle" : "active");
1199        mStatus = idle ? STATUS_CONFIGURED : STATUS_ACTIVE;
1200        mRecentStatusUpdates.add(mStatus);
1201        mStatusChanged.signal();
1202
1203        // Skip notifying listener if we're doing some user-transparent
1204        // state changes
1205        if (mPauseStateNotify) return;
1206    }
1207    NotificationListener *listener;
1208    {
1209        Mutex::Autolock l(mOutputLock);
1210        listener = mListener;
1211    }
1212    if (idle && listener != NULL) {
1213        listener->notifyIdle();
1214    }
1215}
1216
1217/**
1218 * Camera3Device private methods
1219 */
1220
1221sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
1222        const CameraMetadata &request) {
1223    ATRACE_CALL();
1224    status_t res;
1225
1226    sp<CaptureRequest> newRequest = new CaptureRequest;
1227    newRequest->mSettings = request;
1228
1229    camera_metadata_entry_t inputStreams =
1230            newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
1231    if (inputStreams.count > 0) {
1232        if (mInputStream == NULL ||
1233                mInputStream->getId() != inputStreams.data.i32[0]) {
1234            CLOGE("Request references unknown input stream %d",
1235                    inputStreams.data.u8[0]);
1236            return NULL;
1237        }
1238        // Lazy completion of stream configuration (allocation/registration)
1239        // on first use
1240        if (mInputStream->isConfiguring()) {
1241            res = mInputStream->finishConfiguration(mHal3Device);
1242            if (res != OK) {
1243                SET_ERR_L("Unable to finish configuring input stream %d:"
1244                        " %s (%d)",
1245                        mInputStream->getId(), strerror(-res), res);
1246                return NULL;
1247            }
1248        }
1249
1250        newRequest->mInputStream = mInputStream;
1251        newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
1252    }
1253
1254    camera_metadata_entry_t streams =
1255            newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
1256    if (streams.count == 0) {
1257        CLOGE("Zero output streams specified!");
1258        return NULL;
1259    }
1260
1261    for (size_t i = 0; i < streams.count; i++) {
1262        int idx = mOutputStreams.indexOfKey(streams.data.i32[i]);
1263        if (idx == NAME_NOT_FOUND) {
1264            CLOGE("Request references unknown stream %d",
1265                    streams.data.u8[i]);
1266            return NULL;
1267        }
1268        sp<Camera3OutputStreamInterface> stream =
1269                mOutputStreams.editValueAt(idx);
1270
1271        // Lazy completion of stream configuration (allocation/registration)
1272        // on first use
1273        if (stream->isConfiguring()) {
1274            res = stream->finishConfiguration(mHal3Device);
1275            if (res != OK) {
1276                SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
1277                        stream->getId(), strerror(-res), res);
1278                return NULL;
1279            }
1280        }
1281
1282        newRequest->mOutputStreams.push(stream);
1283    }
1284    newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
1285
1286    return newRequest;
1287}
1288
1289status_t Camera3Device::configureStreamsLocked() {
1290    ATRACE_CALL();
1291    status_t res;
1292
1293    if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
1294        CLOGE("Not idle");
1295        return INVALID_OPERATION;
1296    }
1297
1298    if (!mNeedConfig) {
1299        ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
1300        return OK;
1301    }
1302
1303    // Start configuring the streams
1304    ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId);
1305
1306    camera3_stream_configuration config;
1307
1308    config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
1309
1310    Vector<camera3_stream_t*> streams;
1311    streams.setCapacity(config.num_streams);
1312
1313    if (mInputStream != NULL) {
1314        camera3_stream_t *inputStream;
1315        inputStream = mInputStream->startConfiguration();
1316        if (inputStream == NULL) {
1317            SET_ERR_L("Can't start input stream configuration");
1318            return INVALID_OPERATION;
1319        }
1320        streams.add(inputStream);
1321    }
1322
1323    for (size_t i = 0; i < mOutputStreams.size(); i++) {
1324
1325        // Don't configure bidi streams twice, nor add them twice to the list
1326        if (mOutputStreams[i].get() ==
1327            static_cast<Camera3StreamInterface*>(mInputStream.get())) {
1328
1329            config.num_streams--;
1330            continue;
1331        }
1332
1333        camera3_stream_t *outputStream;
1334        outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
1335        if (outputStream == NULL) {
1336            SET_ERR_L("Can't start output stream configuration");
1337            return INVALID_OPERATION;
1338        }
1339        streams.add(outputStream);
1340    }
1341
1342    config.streams = streams.editArray();
1343
1344    // Do the HAL configuration; will potentially touch stream
1345    // max_buffers, usage, priv fields.
1346    ATRACE_BEGIN("camera3->configure_streams");
1347    res = mHal3Device->ops->configure_streams(mHal3Device, &config);
1348    ATRACE_END();
1349
1350    if (res != OK) {
1351        SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
1352                strerror(-res), res);
1353        return res;
1354    }
1355
1356    // Finish all stream configuration immediately.
1357    // TODO: Try to relax this later back to lazy completion, which should be
1358    // faster
1359
1360    if (mInputStream != NULL && mInputStream->isConfiguring()) {
1361        res = mInputStream->finishConfiguration(mHal3Device);
1362        if (res != OK) {
1363            SET_ERR_L("Can't finish configuring input stream %d: %s (%d)",
1364                    mInputStream->getId(), strerror(-res), res);
1365            return res;
1366        }
1367    }
1368
1369    for (size_t i = 0; i < mOutputStreams.size(); i++) {
1370        sp<Camera3OutputStreamInterface> outputStream =
1371            mOutputStreams.editValueAt(i);
1372        if (outputStream->isConfiguring()) {
1373            res = outputStream->finishConfiguration(mHal3Device);
1374            if (res != OK) {
1375                SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
1376                        outputStream->getId(), strerror(-res), res);
1377                return res;
1378            }
1379        }
1380    }
1381
1382    // Request thread needs to know to avoid using repeat-last-settings protocol
1383    // across configure_streams() calls
1384    mRequestThread->configurationComplete();
1385
1386    // Update device state
1387
1388    mNeedConfig = false;
1389
1390    if (config.num_streams > 0) {
1391        mStatus = STATUS_CONFIGURED;
1392    } else {
1393        mStatus = STATUS_UNCONFIGURED;
1394    }
1395
1396    ALOGV("%s: Camera %d: Stream configuration complete", __FUNCTION__, mId);
1397
1398    return OK;
1399}
1400
1401void Camera3Device::setErrorState(const char *fmt, ...) {
1402    Mutex::Autolock l(mLock);
1403    va_list args;
1404    va_start(args, fmt);
1405
1406    setErrorStateLockedV(fmt, args);
1407
1408    va_end(args);
1409}
1410
1411void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
1412    Mutex::Autolock l(mLock);
1413    setErrorStateLockedV(fmt, args);
1414}
1415
1416void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
1417    va_list args;
1418    va_start(args, fmt);
1419
1420    setErrorStateLockedV(fmt, args);
1421
1422    va_end(args);
1423}
1424
1425void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
1426    // Print out all error messages to log
1427    String8 errorCause = String8::formatV(fmt, args);
1428    ALOGE("Camera %d: %s", mId, errorCause.string());
1429
1430    // But only do error state transition steps for the first error
1431    if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
1432
1433    // Save stack trace. View by dumping it later.
1434    CameraTraces::saveTrace();
1435    // TODO: consider adding errorCause and client pid/procname
1436
1437    mErrorCause = errorCause;
1438
1439    mRequestThread->setPaused(true);
1440    mStatus = STATUS_ERROR;
1441}
1442
1443/**
1444 * In-flight request management
1445 */
1446
1447status_t Camera3Device::registerInFlight(uint32_t frameNumber,
1448        int32_t numBuffers, CaptureResultExtras resultExtras) {
1449    ATRACE_CALL();
1450    Mutex::Autolock l(mInFlightLock);
1451
1452    ssize_t res;
1453    res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras));
1454    if (res < 0) return res;
1455
1456    return OK;
1457}
1458
1459/**
1460 * QUIRK(partial results)
1461 * Check if all 3A fields are ready, and send off a partial 3A-only result
1462 * to the output frame queue
1463 */
1464bool Camera3Device::processPartial3AQuirk(
1465        uint32_t frameNumber,
1466        const CameraMetadata& partial, const CaptureResultExtras& resultExtras) {
1467
1468    // Check if all 3A states are present
1469    // The full list of fields is
1470    //   android.control.afMode
1471    //   android.control.awbMode
1472    //   android.control.aeState
1473    //   android.control.awbState
1474    //   android.control.afState
1475    //   android.control.afTriggerID
1476    //   android.control.aePrecaptureID
1477    // TODO: Add android.control.aeMode
1478
1479    bool gotAllStates = true;
1480
1481    uint8_t afMode;
1482    uint8_t awbMode;
1483    uint8_t aeState;
1484    uint8_t afState;
1485    uint8_t awbState;
1486    int32_t afTriggerId;
1487    int32_t aeTriggerId;
1488
1489    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE,
1490        &afMode, frameNumber);
1491
1492    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE,
1493        &awbMode, frameNumber);
1494
1495    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE,
1496        &aeState, frameNumber);
1497
1498    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE,
1499        &afState, frameNumber);
1500
1501    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE,
1502        &awbState, frameNumber);
1503
1504    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_TRIGGER_ID,
1505        &afTriggerId, frameNumber);
1506
1507    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1508        &aeTriggerId, frameNumber);
1509
1510    if (!gotAllStates) return false;
1511
1512    ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, "
1513        "AF state %d, AE state %d, AWB state %d, "
1514        "AF trigger %d, AE precapture trigger %d",
1515        __FUNCTION__, mId, frameNumber, resultExtras.requestId,
1516        afMode, awbMode,
1517        afState, aeState, awbState,
1518        afTriggerId, aeTriggerId);
1519
1520    // Got all states, so construct a minimal result to send
1521    // In addition to the above fields, this means adding in
1522    //   android.request.frameCount
1523    //   android.request.requestId
1524    //   android.quirks.partialResult
1525
1526    const size_t kMinimal3AResultEntries = 10;
1527
1528    Mutex::Autolock l(mOutputLock);
1529
1530    CaptureResult captureResult;
1531    captureResult.mResultExtras = resultExtras;
1532    captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0);
1533    // TODO: change this to sp<CaptureResult>. This will need other changes, including,
1534    // but not limited to CameraDeviceBase::getNextResult
1535    CaptureResult& min3AResult =
1536            *mResultQueue.insert(mResultQueue.end(), captureResult);
1537
1538    if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT,
1539            // TODO: This is problematic casting. Need to fix CameraMetadata.
1540            reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) {
1541        return false;
1542    }
1543
1544    int32_t requestId = resultExtras.requestId;
1545    if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID,
1546            &requestId, frameNumber)) {
1547        return false;
1548    }
1549
1550    static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL;
1551    if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT,
1552            &partialResult, frameNumber)) {
1553        return false;
1554    }
1555
1556    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE,
1557            &afMode, frameNumber)) {
1558        return false;
1559    }
1560
1561    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE,
1562            &awbMode, frameNumber)) {
1563        return false;
1564    }
1565
1566    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE,
1567            &aeState, frameNumber)) {
1568        return false;
1569    }
1570
1571    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE,
1572            &afState, frameNumber)) {
1573        return false;
1574    }
1575
1576    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE,
1577            &awbState, frameNumber)) {
1578        return false;
1579    }
1580
1581    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID,
1582            &afTriggerId, frameNumber)) {
1583        return false;
1584    }
1585
1586    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1587            &aeTriggerId, frameNumber)) {
1588        return false;
1589    }
1590
1591    mResultSignal.signal();
1592
1593    return true;
1594}
1595
1596template<typename T>
1597bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag,
1598        T* value, uint32_t frameNumber) {
1599    (void) frameNumber;
1600
1601    camera_metadata_ro_entry_t entry;
1602
1603    entry = result.find(tag);
1604    if (entry.count == 0) {
1605        ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__,
1606            mId, frameNumber, get_camera_metadata_tag_name(tag));
1607        return false;
1608    }
1609
1610    if (sizeof(T) == sizeof(uint8_t)) {
1611        *value = entry.data.u8[0];
1612    } else if (sizeof(T) == sizeof(int32_t)) {
1613        *value = entry.data.i32[0];
1614    } else {
1615        ALOGE("%s: Unexpected type", __FUNCTION__);
1616        return false;
1617    }
1618    return true;
1619}
1620
1621template<typename T>
1622bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,
1623        const T* value, uint32_t frameNumber) {
1624    if (result.update(tag, value, 1) != NO_ERROR) {
1625        mResultQueue.erase(--mResultQueue.end(), mResultQueue.end());
1626        SET_ERR("Frame %d: Failed to set %s in partial metadata",
1627                frameNumber, get_camera_metadata_tag_name(tag));
1628        return false;
1629    }
1630    return true;
1631}
1632
1633/**
1634 * Camera HAL device callback methods
1635 */
1636
1637void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
1638    ATRACE_CALL();
1639
1640    status_t res;
1641
1642    uint32_t frameNumber = result->frame_number;
1643    if (result->result == NULL && result->num_output_buffers == 0) {
1644        SET_ERR("No result data provided by HAL for frame %d",
1645                frameNumber);
1646        return;
1647    }
1648    bool partialResultQuirk = false;
1649    CameraMetadata collectedQuirkResult;
1650    CaptureResultExtras resultExtras;
1651
1652    // Get capture timestamp and resultExtras from list of in-flight requests,
1653    // where it was added by the shutter notification for this frame.
1654    // Then update the in-flight status and remove the in-flight entry if
1655    // all result data has been received.
1656    nsecs_t timestamp = 0;
1657    {
1658        Mutex::Autolock l(mInFlightLock);
1659        ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
1660        if (idx == NAME_NOT_FOUND) {
1661            SET_ERR("Unknown frame number for capture result: %d",
1662                    frameNumber);
1663            return;
1664        }
1665        InFlightRequest &request = mInFlightMap.editValueAt(idx);
1666        ALOGVV("%s: got InFlightRequest requestId = %" PRId32 ", frameNumber = %" PRId64
1667                ", burstId = %" PRId32,
1668                __FUNCTION__, request.resultExtras.requestId, request.resultExtras.frameNumber,
1669                request.resultExtras.burstId);
1670
1671        // Check if this result carries only partial metadata
1672        if (mUsePartialResultQuirk && result->result != NULL) {
1673            camera_metadata_ro_entry_t partialResultEntry;
1674            res = find_camera_metadata_ro_entry(result->result,
1675                    ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry);
1676            if (res != NAME_NOT_FOUND &&
1677                    partialResultEntry.count > 0 &&
1678                    partialResultEntry.data.u8[0] ==
1679                    ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
1680                // A partial result. Flag this as such, and collect this
1681                // set of metadata into the in-flight entry.
1682                partialResultQuirk = true;
1683                request.partialResultQuirk.collectedResult.append(
1684                    result->result);
1685                request.partialResultQuirk.collectedResult.erase(
1686                    ANDROID_QUIRKS_PARTIAL_RESULT);
1687                // Fire off a 3A-only result if possible
1688                if (!request.partialResultQuirk.haveSent3A) {
1689                    request.partialResultQuirk.haveSent3A =
1690                            processPartial3AQuirk(frameNumber,
1691                                    request.partialResultQuirk.collectedResult,
1692                                    request.resultExtras);
1693                }
1694            }
1695        }
1696
1697        timestamp = request.captureTimestamp;
1698        resultExtras = request.resultExtras;
1699
1700        /**
1701         * One of the following must happen before it's legal to call process_capture_result,
1702         * unless partial metadata is being provided:
1703         * - CAMERA3_MSG_SHUTTER (expected during normal operation)
1704         * - CAMERA3_MSG_ERROR (expected during flush)
1705         */
1706        if (request.requestStatus == OK && timestamp == 0 && !partialResultQuirk) {
1707            SET_ERR("Called before shutter notify for frame %d",
1708                    frameNumber);
1709            return;
1710        }
1711
1712        // Did we get the (final) result metadata for this capture?
1713        if (result->result != NULL && !partialResultQuirk) {
1714            if (request.haveResultMetadata) {
1715                SET_ERR("Called multiple times with metadata for frame %d",
1716                        frameNumber);
1717                return;
1718            }
1719            if (mUsePartialResultQuirk &&
1720                    !request.partialResultQuirk.collectedResult.isEmpty()) {
1721                collectedQuirkResult.acquire(
1722                    request.partialResultQuirk.collectedResult);
1723            }
1724            request.haveResultMetadata = true;
1725        }
1726
1727        request.numBuffersLeft -= result->num_output_buffers;
1728
1729        if (request.numBuffersLeft < 0) {
1730            SET_ERR("Too many buffers returned for frame %d",
1731                    frameNumber);
1732            return;
1733        }
1734
1735        // Check if everything has arrived for this result (buffers and metadata), remove it from
1736        // InFlightMap if both arrived or HAL reports error for this request (i.e. during flush).
1737        if ((request.requestStatus != OK) ||
1738                (request.haveResultMetadata && request.numBuffersLeft == 0)) {
1739            ATRACE_ASYNC_END("frame capture", frameNumber);
1740            mInFlightMap.removeItemsAt(idx, 1);
1741        }
1742
1743        // Sanity check - if we have too many in-flight frames, something has
1744        // likely gone wrong
1745        if (mInFlightMap.size() > kInFlightWarnLimit) {
1746            CLOGE("In-flight list too large: %zu", mInFlightMap.size());
1747        }
1748
1749    }
1750
1751    // Process the result metadata, if provided
1752    bool gotResult = false;
1753    if (result->result != NULL && !partialResultQuirk) {
1754        Mutex::Autolock l(mOutputLock);
1755
1756        gotResult = true;
1757
1758        // TODO: need to track errors for tighter bounds on expected frame number
1759        if (frameNumber < mNextResultFrameNumber) {
1760            SET_ERR("Out-of-order capture result metadata submitted! "
1761                    "(got frame number %d, expecting %d)",
1762                    frameNumber, mNextResultFrameNumber);
1763            return;
1764        }
1765        mNextResultFrameNumber = frameNumber + 1;
1766
1767        CaptureResult captureResult;
1768        captureResult.mResultExtras = resultExtras;
1769        captureResult.mMetadata = result->result;
1770
1771        if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
1772                (int32_t*)&frameNumber, 1) != OK) {
1773            SET_ERR("Failed to set frame# in metadata (%d)",
1774                    frameNumber);
1775            gotResult = false;
1776        } else {
1777            ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
1778                    __FUNCTION__, mId, frameNumber);
1779        }
1780
1781        // Append any previous partials to form a complete result
1782        if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) {
1783            captureResult.mMetadata.append(collectedQuirkResult);
1784        }
1785
1786        captureResult.mMetadata.sort();
1787
1788        // Check that there's a timestamp in the result metadata
1789
1790        camera_metadata_entry entry =
1791                captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
1792        if (entry.count == 0) {
1793            SET_ERR("No timestamp provided by HAL for frame %d!",
1794                    frameNumber);
1795            gotResult = false;
1796        } else if (timestamp != entry.data.i64[0]) {
1797            SET_ERR("Timestamp mismatch between shutter notify and result"
1798                    " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)",
1799                    frameNumber, timestamp, entry.data.i64[0]);
1800            gotResult = false;
1801        }
1802
1803        if (gotResult) {
1804            // Valid result, insert into queue
1805            List<CaptureResult>::iterator queuedResult =
1806                    mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));
1807            ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64
1808                   ", burstId = %" PRId32, __FUNCTION__,
1809                   queuedResult->mResultExtras.requestId,
1810                   queuedResult->mResultExtras.frameNumber,
1811                   queuedResult->mResultExtras.burstId);
1812        }
1813    } // scope for mOutputLock
1814
1815    // Return completed buffers to their streams with the timestamp
1816
1817    for (size_t i = 0; i < result->num_output_buffers; i++) {
1818        Camera3Stream *stream =
1819                Camera3Stream::cast(result->output_buffers[i].stream);
1820        res = stream->returnBuffer(result->output_buffers[i], timestamp);
1821        // Note: stream may be deallocated at this point, if this buffer was the
1822        // last reference to it.
1823        if (res != OK) {
1824            ALOGE("Can't return buffer %zu for frame %d to its stream: "
1825                    " %s (%d)", i, frameNumber, strerror(-res), res);
1826        }
1827    }
1828
1829    // Finally, signal any waiters for new frames
1830
1831    if (gotResult) {
1832        mResultSignal.signal();
1833    }
1834
1835}
1836
1837void Camera3Device::notify(const camera3_notify_msg *msg) {
1838    ATRACE_CALL();
1839    NotificationListener *listener;
1840    {
1841        Mutex::Autolock l(mOutputLock);
1842        listener = mListener;
1843    }
1844
1845    if (msg == NULL) {
1846        SET_ERR("HAL sent NULL notify message!");
1847        return;
1848    }
1849
1850    switch (msg->type) {
1851        case CAMERA3_MSG_ERROR: {
1852            int streamId = 0;
1853            if (msg->message.error.error_stream != NULL) {
1854                Camera3Stream *stream =
1855                        Camera3Stream::cast(
1856                                  msg->message.error.error_stream);
1857                streamId = stream->getId();
1858            }
1859            ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
1860                    mId, __FUNCTION__, msg->message.error.frame_number,
1861                    streamId, msg->message.error.error_code);
1862
1863            CaptureResultExtras resultExtras;
1864            // Set request error status for the request in the in-flight tracking
1865            {
1866                Mutex::Autolock l(mInFlightLock);
1867                ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number);
1868                if (idx >= 0) {
1869                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
1870                    r.requestStatus = msg->message.error.error_code;
1871                    resultExtras = r.resultExtras;
1872                } else {
1873                    resultExtras.frameNumber = msg->message.error.frame_number;
1874                    ALOGE("Camera %d: %s: cannot find in-flight request on frame %" PRId64
1875                          " error", mId, __FUNCTION__, resultExtras.frameNumber);
1876                }
1877            }
1878
1879            if (listener != NULL) {
1880                if (msg->message.error.error_code == CAMERA3_MSG_ERROR_DEVICE) {
1881                    listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
1882                                          resultExtras);
1883                } else {
1884                    listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
1885                                          resultExtras);
1886                }
1887            } else {
1888                ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__);
1889            }
1890            break;
1891        }
1892        case CAMERA3_MSG_SHUTTER: {
1893            ssize_t idx;
1894            uint32_t frameNumber = msg->message.shutter.frame_number;
1895            nsecs_t timestamp = msg->message.shutter.timestamp;
1896            // Verify ordering of shutter notifications
1897            {
1898                Mutex::Autolock l(mOutputLock);
1899                // TODO: need to track errors for tighter bounds on expected frame number.
1900                if (frameNumber < mNextShutterFrameNumber) {
1901                    SET_ERR("Shutter notification out-of-order. Expected "
1902                            "notification for frame %d, got frame %d",
1903                            mNextShutterFrameNumber, frameNumber);
1904                    break;
1905                }
1906                mNextShutterFrameNumber = frameNumber + 1;
1907            }
1908
1909            CaptureResultExtras resultExtras;
1910
1911            // Set timestamp for the request in the in-flight tracking
1912            // and get the request ID to send upstream
1913            {
1914                Mutex::Autolock l(mInFlightLock);
1915                idx = mInFlightMap.indexOfKey(frameNumber);
1916                if (idx >= 0) {
1917                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
1918                    r.captureTimestamp = timestamp;
1919                    resultExtras = r.resultExtras;
1920                }
1921            }
1922            if (idx < 0) {
1923                SET_ERR("Shutter notification for non-existent frame number %d",
1924                        frameNumber);
1925                break;
1926            }
1927            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
1928                    mId, __FUNCTION__, frameNumber, resultExtras.requestId, timestamp);
1929            // Call listener, if any
1930            if (listener != NULL) {
1931                listener->notifyShutter(resultExtras, timestamp);
1932            }
1933            break;
1934        }
1935        default:
1936            SET_ERR("Unknown notify message from HAL: %d",
1937                    msg->type);
1938    }
1939}
1940
1941CameraMetadata Camera3Device::getLatestRequestLocked() {
1942    ALOGV("%s", __FUNCTION__);
1943
1944    CameraMetadata retVal;
1945
1946    if (mRequestThread != NULL) {
1947        retVal = mRequestThread->getLatestRequest();
1948    }
1949
1950    return retVal;
1951}
1952
1953
1954/**
1955 * RequestThread inner class methods
1956 */
1957
1958Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
1959        sp<StatusTracker> statusTracker,
1960        camera3_device_t *hal3Device) :
1961        Thread(false),
1962        mParent(parent),
1963        mStatusTracker(statusTracker),
1964        mHal3Device(hal3Device),
1965        mId(getId(parent)),
1966        mReconfigured(false),
1967        mDoPause(false),
1968        mPaused(true),
1969        mFrameNumber(0),
1970        mLatestRequestId(NAME_NOT_FOUND),
1971        mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) {
1972    mStatusId = statusTracker->addComponent();
1973}
1974
1975void Camera3Device::RequestThread::configurationComplete() {
1976    Mutex::Autolock l(mRequestLock);
1977    mReconfigured = true;
1978}
1979
1980status_t Camera3Device::RequestThread::queueRequestList(
1981        List<sp<CaptureRequest> > &requests,
1982        /*out*/
1983        int64_t *lastFrameNumber) {
1984    Mutex::Autolock l(mRequestLock);
1985    for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
1986            ++it) {
1987        mRequestQueue.push_back(*it);
1988    }
1989
1990    if (lastFrameNumber != NULL) {
1991        *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
1992        ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
1993              __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
1994              *lastFrameNumber);
1995    }
1996
1997    unpauseForNewRequests();
1998
1999    return OK;
2000}
2001
2002
2003status_t Camera3Device::RequestThread::queueTrigger(
2004        RequestTrigger trigger[],
2005        size_t count) {
2006
2007    Mutex::Autolock l(mTriggerMutex);
2008    status_t ret;
2009
2010    for (size_t i = 0; i < count; ++i) {
2011        ret = queueTriggerLocked(trigger[i]);
2012
2013        if (ret != OK) {
2014            return ret;
2015        }
2016    }
2017
2018    return OK;
2019}
2020
2021int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
2022    sp<Camera3Device> d = device.promote();
2023    if (d != NULL) return d->mId;
2024    return 0;
2025}
2026
2027status_t Camera3Device::RequestThread::queueTriggerLocked(
2028        RequestTrigger trigger) {
2029
2030    uint32_t tag = trigger.metadataTag;
2031    ssize_t index = mTriggerMap.indexOfKey(tag);
2032
2033    switch (trigger.getTagType()) {
2034        case TYPE_BYTE:
2035        // fall-through
2036        case TYPE_INT32:
2037            break;
2038        default:
2039            ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
2040                    trigger.getTagType());
2041            return INVALID_OPERATION;
2042    }
2043
2044    /**
2045     * Collect only the latest trigger, since we only have 1 field
2046     * in the request settings per trigger tag, and can't send more than 1
2047     * trigger per request.
2048     */
2049    if (index != NAME_NOT_FOUND) {
2050        mTriggerMap.editValueAt(index) = trigger;
2051    } else {
2052        mTriggerMap.add(tag, trigger);
2053    }
2054
2055    return OK;
2056}
2057
2058status_t Camera3Device::RequestThread::setRepeatingRequests(
2059        const RequestList &requests,
2060        /*out*/
2061        int64_t *lastFrameNumber) {
2062    Mutex::Autolock l(mRequestLock);
2063    if (lastFrameNumber != NULL) {
2064        *lastFrameNumber = mRepeatingLastFrameNumber;
2065    }
2066    mRepeatingRequests.clear();
2067    mRepeatingRequests.insert(mRepeatingRequests.begin(),
2068            requests.begin(), requests.end());
2069
2070    unpauseForNewRequests();
2071
2072    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2073    return OK;
2074}
2075
2076status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
2077    Mutex::Autolock l(mRequestLock);
2078    mRepeatingRequests.clear();
2079    if (lastFrameNumber != NULL) {
2080        *lastFrameNumber = mRepeatingLastFrameNumber;
2081    }
2082    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2083    return OK;
2084}
2085
2086status_t Camera3Device::RequestThread::clear(/*out*/int64_t *lastFrameNumber) {
2087    Mutex::Autolock l(mRequestLock);
2088    ALOGV("RequestThread::%s:", __FUNCTION__);
2089    mRepeatingRequests.clear();
2090    mRequestQueue.clear();
2091    mTriggerMap.clear();
2092    if (lastFrameNumber != NULL) {
2093        *lastFrameNumber = mRepeatingLastFrameNumber;
2094    }
2095    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2096    return OK;
2097}
2098
2099void Camera3Device::RequestThread::setPaused(bool paused) {
2100    Mutex::Autolock l(mPauseLock);
2101    mDoPause = paused;
2102    mDoPauseSignal.signal();
2103}
2104
2105status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
2106        int32_t requestId, nsecs_t timeout) {
2107    Mutex::Autolock l(mLatestRequestMutex);
2108    status_t res;
2109    while (mLatestRequestId != requestId) {
2110        nsecs_t startTime = systemTime();
2111
2112        res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
2113        if (res != OK) return res;
2114
2115        timeout -= (systemTime() - startTime);
2116    }
2117
2118    return OK;
2119}
2120
2121void Camera3Device::RequestThread::requestExit() {
2122    // Call parent to set up shutdown
2123    Thread::requestExit();
2124    // The exit from any possible waits
2125    mDoPauseSignal.signal();
2126    mRequestSignal.signal();
2127}
2128
2129bool Camera3Device::RequestThread::threadLoop() {
2130
2131    status_t res;
2132
2133    // Handle paused state.
2134    if (waitIfPaused()) {
2135        return true;
2136    }
2137
2138    // Get work to do
2139
2140    sp<CaptureRequest> nextRequest = waitForNextRequest();
2141    if (nextRequest == NULL) {
2142        return true;
2143    }
2144
2145    // Create request to HAL
2146    camera3_capture_request_t request = camera3_capture_request_t();
2147    request.frame_number = nextRequest->mResultExtras.frameNumber;
2148    Vector<camera3_stream_buffer_t> outputBuffers;
2149
2150    // Get the request ID, if any
2151    int requestId;
2152    camera_metadata_entry_t requestIdEntry =
2153            nextRequest->mSettings.find(ANDROID_REQUEST_ID);
2154    if (requestIdEntry.count > 0) {
2155        requestId = requestIdEntry.data.i32[0];
2156    } else {
2157        ALOGW("%s: Did not have android.request.id set in the request",
2158                __FUNCTION__);
2159        requestId = NAME_NOT_FOUND;
2160    }
2161
2162    // Insert any queued triggers (before metadata is locked)
2163    int32_t triggerCount;
2164    res = insertTriggers(nextRequest);
2165    if (res < 0) {
2166        SET_ERR("RequestThread: Unable to insert triggers "
2167                "(capture request %d, HAL device: %s (%d)",
2168                request.frame_number, strerror(-res), res);
2169        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2170        return false;
2171    }
2172    triggerCount = res;
2173
2174    bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
2175
2176    // If the request is the same as last, or we had triggers last time
2177    if (mPrevRequest != nextRequest || triggersMixedIn) {
2178        /**
2179         * HAL workaround:
2180         * Insert a dummy trigger ID if a trigger is set but no trigger ID is
2181         */
2182        res = addDummyTriggerIds(nextRequest);
2183        if (res != OK) {
2184            SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
2185                    "(capture request %d, HAL device: %s (%d)",
2186                    request.frame_number, strerror(-res), res);
2187            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2188            return false;
2189        }
2190
2191        /**
2192         * The request should be presorted so accesses in HAL
2193         *   are O(logn). Sidenote, sorting a sorted metadata is nop.
2194         */
2195        nextRequest->mSettings.sort();
2196        request.settings = nextRequest->mSettings.getAndLock();
2197        mPrevRequest = nextRequest;
2198        ALOGVV("%s: Request settings are NEW", __FUNCTION__);
2199
2200        IF_ALOGV() {
2201            camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
2202            find_camera_metadata_ro_entry(
2203                    request.settings,
2204                    ANDROID_CONTROL_AF_TRIGGER,
2205                    &e
2206            );
2207            if (e.count > 0) {
2208                ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
2209                      __FUNCTION__,
2210                      request.frame_number,
2211                      e.data.u8[0]);
2212            }
2213        }
2214    } else {
2215        // leave request.settings NULL to indicate 'reuse latest given'
2216        ALOGVV("%s: Request settings are REUSED",
2217               __FUNCTION__);
2218    }
2219
2220    camera3_stream_buffer_t inputBuffer;
2221
2222    // Fill in buffers
2223
2224    if (nextRequest->mInputStream != NULL) {
2225        request.input_buffer = &inputBuffer;
2226        res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
2227        if (res != OK) {
2228            ALOGE("RequestThread: Can't get input buffer, skipping request:"
2229                    " %s (%d)", strerror(-res), res);
2230            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2231            return true;
2232        }
2233    } else {
2234        request.input_buffer = NULL;
2235    }
2236
2237    outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
2238            nextRequest->mOutputStreams.size());
2239    request.output_buffers = outputBuffers.array();
2240    for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
2241        res = nextRequest->mOutputStreams.editItemAt(i)->
2242                getBuffer(&outputBuffers.editItemAt(i));
2243        if (res != OK) {
2244            ALOGE("RequestThread: Can't get output buffer, skipping request:"
2245                    " %s (%d)", strerror(-res), res);
2246            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2247            return true;
2248        }
2249        request.num_output_buffers++;
2250    }
2251
2252    // Log request in the in-flight queue
2253    sp<Camera3Device> parent = mParent.promote();
2254    if (parent == NULL) {
2255        CLOGE("RequestThread: Parent is gone");
2256        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2257        return false;
2258    }
2259
2260    res = parent->registerInFlight(request.frame_number,
2261            request.num_output_buffers, nextRequest->mResultExtras);
2262    ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
2263           ", burstId = %" PRId32 ".",
2264            __FUNCTION__,
2265            nextRequest->mResultExtras.requestId, nextRequest->mResultExtras.frameNumber,
2266            nextRequest->mResultExtras.burstId);
2267    if (res != OK) {
2268        SET_ERR("RequestThread: Unable to register new in-flight request:"
2269                " %s (%d)", strerror(-res), res);
2270        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2271        return false;
2272    }
2273
2274    // Inform waitUntilRequestProcessed thread of a new request ID
2275    {
2276        Mutex::Autolock al(mLatestRequestMutex);
2277
2278        mLatestRequestId = requestId;
2279        mLatestRequestSignal.signal();
2280    }
2281
2282    // Submit request and block until ready for next one
2283    ATRACE_ASYNC_BEGIN("frame capture", request.frame_number);
2284    ATRACE_BEGIN("camera3->process_capture_request");
2285    res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
2286    ATRACE_END();
2287
2288    if (res != OK) {
2289        SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
2290                " device: %s (%d)", request.frame_number, strerror(-res), res);
2291        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2292        return false;
2293    }
2294
2295    // Update the latest request sent to HAL
2296    if (request.settings != NULL) { // Don't update them if they were unchanged
2297        Mutex::Autolock al(mLatestRequestMutex);
2298
2299        camera_metadata_t* cloned = clone_camera_metadata(request.settings);
2300        mLatestRequest.acquire(cloned);
2301    }
2302
2303    if (request.settings != NULL) {
2304        nextRequest->mSettings.unlock(request.settings);
2305    }
2306
2307    // Remove any previously queued triggers (after unlock)
2308    res = removeTriggers(mPrevRequest);
2309    if (res != OK) {
2310        SET_ERR("RequestThread: Unable to remove triggers "
2311              "(capture request %d, HAL device: %s (%d)",
2312              request.frame_number, strerror(-res), res);
2313        return false;
2314    }
2315    mPrevTriggers = triggerCount;
2316
2317    // Return input buffer back to framework
2318    if (request.input_buffer != NULL) {
2319        Camera3Stream *stream =
2320            Camera3Stream::cast(request.input_buffer->stream);
2321        res = stream->returnInputBuffer(*(request.input_buffer));
2322        // Note: stream may be deallocated at this point, if this buffer was the
2323        // last reference to it.
2324        if (res != OK) {
2325            ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
2326                    "  its stream:%s (%d)",  __FUNCTION__,
2327                    request.frame_number, strerror(-res), res);
2328            // TODO: Report error upstream
2329        }
2330    }
2331
2332    return true;
2333}
2334
2335CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
2336    Mutex::Autolock al(mLatestRequestMutex);
2337
2338    ALOGV("RequestThread::%s", __FUNCTION__);
2339
2340    return mLatestRequest;
2341}
2342
2343
2344void Camera3Device::RequestThread::cleanUpFailedRequest(
2345        camera3_capture_request_t &request,
2346        sp<CaptureRequest> &nextRequest,
2347        Vector<camera3_stream_buffer_t> &outputBuffers) {
2348
2349    if (request.settings != NULL) {
2350        nextRequest->mSettings.unlock(request.settings);
2351    }
2352    if (request.input_buffer != NULL) {
2353        request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
2354        nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
2355    }
2356    for (size_t i = 0; i < request.num_output_buffers; i++) {
2357        outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
2358        nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
2359            outputBuffers[i], 0);
2360    }
2361}
2362
2363sp<Camera3Device::CaptureRequest>
2364        Camera3Device::RequestThread::waitForNextRequest() {
2365    status_t res;
2366    sp<CaptureRequest> nextRequest;
2367
2368    // Optimized a bit for the simple steady-state case (single repeating
2369    // request), to avoid putting that request in the queue temporarily.
2370    Mutex::Autolock l(mRequestLock);
2371
2372    while (mRequestQueue.empty()) {
2373        if (!mRepeatingRequests.empty()) {
2374            // Always atomically enqueue all requests in a repeating request
2375            // list. Guarantees a complete in-sequence set of captures to
2376            // application.
2377            const RequestList &requests = mRepeatingRequests;
2378            RequestList::const_iterator firstRequest =
2379                    requests.begin();
2380            nextRequest = *firstRequest;
2381            mRequestQueue.insert(mRequestQueue.end(),
2382                    ++firstRequest,
2383                    requests.end());
2384            // No need to wait any longer
2385
2386            mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
2387
2388            break;
2389        }
2390
2391        res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
2392
2393        if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
2394                exitPending()) {
2395            Mutex::Autolock pl(mPauseLock);
2396            if (mPaused == false) {
2397                ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
2398                mPaused = true;
2399                // Let the tracker know
2400                sp<StatusTracker> statusTracker = mStatusTracker.promote();
2401                if (statusTracker != 0) {
2402                    statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2403                }
2404            }
2405            // Stop waiting for now and let thread management happen
2406            return NULL;
2407        }
2408    }
2409
2410    if (nextRequest == NULL) {
2411        // Don't have a repeating request already in hand, so queue
2412        // must have an entry now.
2413        RequestList::iterator firstRequest =
2414                mRequestQueue.begin();
2415        nextRequest = *firstRequest;
2416        mRequestQueue.erase(firstRequest);
2417    }
2418
2419    // In case we've been unpaused by setPaused clearing mDoPause, need to
2420    // update internal pause state (capture/setRepeatingRequest unpause
2421    // directly).
2422    Mutex::Autolock pl(mPauseLock);
2423    if (mPaused) {
2424        ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
2425        sp<StatusTracker> statusTracker = mStatusTracker.promote();
2426        if (statusTracker != 0) {
2427            statusTracker->markComponentActive(mStatusId);
2428        }
2429    }
2430    mPaused = false;
2431
2432    // Check if we've reconfigured since last time, and reset the preview
2433    // request if so. Can't use 'NULL request == repeat' across configure calls.
2434    if (mReconfigured) {
2435        mPrevRequest.clear();
2436        mReconfigured = false;
2437    }
2438
2439    if (nextRequest != NULL) {
2440        nextRequest->mResultExtras.frameNumber = mFrameNumber++;
2441    }
2442    return nextRequest;
2443}
2444
2445bool Camera3Device::RequestThread::waitIfPaused() {
2446    status_t res;
2447    Mutex::Autolock l(mPauseLock);
2448    while (mDoPause) {
2449        if (mPaused == false) {
2450            mPaused = true;
2451            ALOGV("%s: RequestThread: Paused", __FUNCTION__);
2452            // Let the tracker know
2453            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2454            if (statusTracker != 0) {
2455                statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2456            }
2457        }
2458
2459        res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
2460        if (res == TIMED_OUT || exitPending()) {
2461            return true;
2462        }
2463    }
2464    // We don't set mPaused to false here, because waitForNextRequest needs
2465    // to further manage the paused state in case of starvation.
2466    return false;
2467}
2468
2469void Camera3Device::RequestThread::unpauseForNewRequests() {
2470    // With work to do, mark thread as unpaused.
2471    // If paused by request (setPaused), don't resume, to avoid
2472    // extra signaling/waiting overhead to waitUntilPaused
2473    mRequestSignal.signal();
2474    Mutex::Autolock p(mPauseLock);
2475    if (!mDoPause) {
2476        ALOGV("%s: RequestThread: Going active", __FUNCTION__);
2477        if (mPaused) {
2478            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2479            if (statusTracker != 0) {
2480                statusTracker->markComponentActive(mStatusId);
2481            }
2482        }
2483        mPaused = false;
2484    }
2485}
2486
2487void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
2488    sp<Camera3Device> parent = mParent.promote();
2489    if (parent != NULL) {
2490        va_list args;
2491        va_start(args, fmt);
2492
2493        parent->setErrorStateV(fmt, args);
2494
2495        va_end(args);
2496    }
2497}
2498
2499status_t Camera3Device::RequestThread::insertTriggers(
2500        const sp<CaptureRequest> &request) {
2501
2502    Mutex::Autolock al(mTriggerMutex);
2503
2504    CameraMetadata &metadata = request->mSettings;
2505    size_t count = mTriggerMap.size();
2506
2507    for (size_t i = 0; i < count; ++i) {
2508        RequestTrigger trigger = mTriggerMap.valueAt(i);
2509
2510        uint32_t tag = trigger.metadataTag;
2511        camera_metadata_entry entry = metadata.find(tag);
2512
2513        if (entry.count > 0) {
2514            /**
2515             * Already has an entry for this trigger in the request.
2516             * Rewrite it with our requested trigger value.
2517             */
2518            RequestTrigger oldTrigger = trigger;
2519
2520            oldTrigger.entryValue = entry.data.u8[0];
2521
2522            mTriggerReplacedMap.add(tag, oldTrigger);
2523        } else {
2524            /**
2525             * More typical, no trigger entry, so we just add it
2526             */
2527            mTriggerRemovedMap.add(tag, trigger);
2528        }
2529
2530        status_t res;
2531
2532        switch (trigger.getTagType()) {
2533            case TYPE_BYTE: {
2534                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2535                res = metadata.update(tag,
2536                                      &entryValue,
2537                                      /*count*/1);
2538                break;
2539            }
2540            case TYPE_INT32:
2541                res = metadata.update(tag,
2542                                      &trigger.entryValue,
2543                                      /*count*/1);
2544                break;
2545            default:
2546                ALOGE("%s: Type not supported: 0x%x",
2547                      __FUNCTION__,
2548                      trigger.getTagType());
2549                return INVALID_OPERATION;
2550        }
2551
2552        if (res != OK) {
2553            ALOGE("%s: Failed to update request metadata with trigger tag %s"
2554                  ", value %d", __FUNCTION__, trigger.getTagName(),
2555                  trigger.entryValue);
2556            return res;
2557        }
2558
2559        ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
2560              trigger.getTagName(),
2561              trigger.entryValue);
2562    }
2563
2564    mTriggerMap.clear();
2565
2566    return count;
2567}
2568
2569status_t Camera3Device::RequestThread::removeTriggers(
2570        const sp<CaptureRequest> &request) {
2571    Mutex::Autolock al(mTriggerMutex);
2572
2573    CameraMetadata &metadata = request->mSettings;
2574
2575    /**
2576     * Replace all old entries with their old values.
2577     */
2578    for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
2579        RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
2580
2581        status_t res;
2582
2583        uint32_t tag = trigger.metadataTag;
2584        switch (trigger.getTagType()) {
2585            case TYPE_BYTE: {
2586                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2587                res = metadata.update(tag,
2588                                      &entryValue,
2589                                      /*count*/1);
2590                break;
2591            }
2592            case TYPE_INT32:
2593                res = metadata.update(tag,
2594                                      &trigger.entryValue,
2595                                      /*count*/1);
2596                break;
2597            default:
2598                ALOGE("%s: Type not supported: 0x%x",
2599                      __FUNCTION__,
2600                      trigger.getTagType());
2601                return INVALID_OPERATION;
2602        }
2603
2604        if (res != OK) {
2605            ALOGE("%s: Failed to restore request metadata with trigger tag %s"
2606                  ", trigger value %d", __FUNCTION__,
2607                  trigger.getTagName(), trigger.entryValue);
2608            return res;
2609        }
2610    }
2611    mTriggerReplacedMap.clear();
2612
2613    /**
2614     * Remove all new entries.
2615     */
2616    for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
2617        RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
2618        status_t res = metadata.erase(trigger.metadataTag);
2619
2620        if (res != OK) {
2621            ALOGE("%s: Failed to erase metadata with trigger tag %s"
2622                  ", trigger value %d", __FUNCTION__,
2623                  trigger.getTagName(), trigger.entryValue);
2624            return res;
2625        }
2626    }
2627    mTriggerRemovedMap.clear();
2628
2629    return OK;
2630}
2631
2632status_t Camera3Device::RequestThread::addDummyTriggerIds(
2633        const sp<CaptureRequest> &request) {
2634    // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
2635    static const int32_t dummyTriggerId = 1;
2636    status_t res;
2637
2638    CameraMetadata &metadata = request->mSettings;
2639
2640    // If AF trigger is active, insert a dummy AF trigger ID if none already
2641    // exists
2642    camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
2643    camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
2644    if (afTrigger.count > 0 &&
2645            afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
2646            afId.count == 0) {
2647        res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
2648        if (res != OK) return res;
2649    }
2650
2651    // If AE precapture trigger is active, insert a dummy precapture trigger ID
2652    // if none already exists
2653    camera_metadata_entry pcTrigger =
2654            metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
2655    camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
2656    if (pcTrigger.count > 0 &&
2657            pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
2658            pcId.count == 0) {
2659        res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
2660                &dummyTriggerId, 1);
2661        if (res != OK) return res;
2662    }
2663
2664    return OK;
2665}
2666
2667
2668/**
2669 * Static callback forwarding methods from HAL to instance
2670 */
2671
2672void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
2673        const camera3_capture_result *result) {
2674    Camera3Device *d =
2675            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2676    d->processCaptureResult(result);
2677}
2678
2679void Camera3Device::sNotify(const camera3_callback_ops *cb,
2680        const camera3_notify_msg *msg) {
2681    Camera3Device *d =
2682            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2683    d->notify(msg);
2684}
2685
2686}; // namespace android
2687