Camera3Device.cpp revision 2d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4
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    *id = mNextStreamId++;
685    *zslStream = newStream;
686
687    // Continue captures if active at start
688    if (wasActive) {
689        ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
690        res = configureStreamsLocked();
691        if (res != OK) {
692            ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
693                    __FUNCTION__, mNextStreamId, strerror(-res), res);
694            return res;
695        }
696        internalResumeLocked();
697    }
698
699    ALOGV("Camera %d: Created ZSL stream", mId);
700    return OK;
701}
702
703status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
704        uint32_t width, uint32_t height, int format, size_t size, int *id) {
705    ATRACE_CALL();
706    Mutex::Autolock il(mInterfaceLock);
707    Mutex::Autolock l(mLock);
708    ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, size %zu",
709            mId, mNextStreamId, width, height, format, size);
710
711    status_t res;
712    bool wasActive = false;
713
714    switch (mStatus) {
715        case STATUS_ERROR:
716            CLOGE("Device has encountered a serious error");
717            return INVALID_OPERATION;
718        case STATUS_UNINITIALIZED:
719            CLOGE("Device not initialized");
720            return INVALID_OPERATION;
721        case STATUS_UNCONFIGURED:
722        case STATUS_CONFIGURED:
723            // OK
724            break;
725        case STATUS_ACTIVE:
726            ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
727            res = internalPauseAndWaitLocked();
728            if (res != OK) {
729                SET_ERR_L("Can't pause captures to reconfigure streams!");
730                return res;
731            }
732            wasActive = true;
733            break;
734        default:
735            SET_ERR_L("Unexpected status: %d", mStatus);
736            return INVALID_OPERATION;
737    }
738    assert(mStatus != STATUS_ACTIVE);
739
740    sp<Camera3OutputStream> newStream;
741    if (format == HAL_PIXEL_FORMAT_BLOB) {
742        newStream = new Camera3OutputStream(mNextStreamId, consumer,
743                width, height, size, format);
744    } else {
745        newStream = new Camera3OutputStream(mNextStreamId, consumer,
746                width, height, format);
747    }
748    newStream->setStatusTracker(mStatusTracker);
749
750    res = mOutputStreams.add(mNextStreamId, newStream);
751    if (res < 0) {
752        SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
753        return res;
754    }
755
756    *id = mNextStreamId++;
757    mNeedConfig = true;
758
759    // Continue captures if active at start
760    if (wasActive) {
761        ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
762        res = configureStreamsLocked();
763        if (res != OK) {
764            CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
765                    mNextStreamId, strerror(-res), res);
766            return res;
767        }
768        internalResumeLocked();
769    }
770    ALOGV("Camera %d: Created new stream", mId);
771    return OK;
772}
773
774status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
775    ATRACE_CALL();
776    (void)outputId; (void)id;
777
778    CLOGE("Unimplemented");
779    return INVALID_OPERATION;
780}
781
782
783status_t Camera3Device::getStreamInfo(int id,
784        uint32_t *width, uint32_t *height, uint32_t *format) {
785    ATRACE_CALL();
786    Mutex::Autolock il(mInterfaceLock);
787    Mutex::Autolock l(mLock);
788
789    switch (mStatus) {
790        case STATUS_ERROR:
791            CLOGE("Device has encountered a serious error");
792            return INVALID_OPERATION;
793        case STATUS_UNINITIALIZED:
794            CLOGE("Device not initialized!");
795            return INVALID_OPERATION;
796        case STATUS_UNCONFIGURED:
797        case STATUS_CONFIGURED:
798        case STATUS_ACTIVE:
799            // OK
800            break;
801        default:
802            SET_ERR_L("Unexpected status: %d", mStatus);
803            return INVALID_OPERATION;
804    }
805
806    ssize_t idx = mOutputStreams.indexOfKey(id);
807    if (idx == NAME_NOT_FOUND) {
808        CLOGE("Stream %d is unknown", id);
809        return idx;
810    }
811
812    if (width) *width  = mOutputStreams[idx]->getWidth();
813    if (height) *height = mOutputStreams[idx]->getHeight();
814    if (format) *format = mOutputStreams[idx]->getFormat();
815
816    return OK;
817}
818
819status_t Camera3Device::setStreamTransform(int id,
820        int transform) {
821    ATRACE_CALL();
822    Mutex::Autolock il(mInterfaceLock);
823    Mutex::Autolock l(mLock);
824
825    switch (mStatus) {
826        case STATUS_ERROR:
827            CLOGE("Device has encountered a serious error");
828            return INVALID_OPERATION;
829        case STATUS_UNINITIALIZED:
830            CLOGE("Device not initialized");
831            return INVALID_OPERATION;
832        case STATUS_UNCONFIGURED:
833        case STATUS_CONFIGURED:
834        case STATUS_ACTIVE:
835            // OK
836            break;
837        default:
838            SET_ERR_L("Unexpected status: %d", mStatus);
839            return INVALID_OPERATION;
840    }
841
842    ssize_t idx = mOutputStreams.indexOfKey(id);
843    if (idx == NAME_NOT_FOUND) {
844        CLOGE("Stream %d does not exist",
845                id);
846        return BAD_VALUE;
847    }
848
849    return mOutputStreams.editValueAt(idx)->setTransform(transform);
850}
851
852status_t Camera3Device::deleteStream(int id) {
853    ATRACE_CALL();
854    Mutex::Autolock il(mInterfaceLock);
855    Mutex::Autolock l(mLock);
856    status_t res;
857
858    ALOGV("%s: Camera %d: Deleting stream %d", __FUNCTION__, mId, id);
859
860    // CameraDevice semantics require device to already be idle before
861    // deleteStream is called, unlike for createStream.
862    if (mStatus == STATUS_ACTIVE) {
863        ALOGV("%s: Camera %d: Device not idle", __FUNCTION__, mId);
864        return -EBUSY;
865    }
866
867    sp<Camera3StreamInterface> deletedStream;
868    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(id);
869    if (mInputStream != NULL && id == mInputStream->getId()) {
870        deletedStream = mInputStream;
871        mInputStream.clear();
872    } else {
873        if (outputStreamIdx == NAME_NOT_FOUND) {
874            CLOGE("Stream %d does not exist", id);
875            return BAD_VALUE;
876        }
877    }
878
879    // Delete output stream or the output part of a bi-directional stream.
880    if (outputStreamIdx != NAME_NOT_FOUND) {
881        deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
882        mOutputStreams.removeItem(id);
883    }
884
885    // Free up the stream endpoint so that it can be used by some other stream
886    res = deletedStream->disconnect();
887    if (res != OK) {
888        SET_ERR_L("Can't disconnect deleted stream %d", id);
889        // fall through since we want to still list the stream as deleted.
890    }
891    mDeletedStreams.add(deletedStream);
892    mNeedConfig = true;
893
894    return res;
895}
896
897status_t Camera3Device::deleteReprocessStream(int id) {
898    ATRACE_CALL();
899    (void)id;
900
901    CLOGE("Unimplemented");
902    return INVALID_OPERATION;
903}
904
905
906status_t Camera3Device::createDefaultRequest(int templateId,
907        CameraMetadata *request) {
908    ATRACE_CALL();
909    ALOGV("%s: for template %d", __FUNCTION__, templateId);
910    Mutex::Autolock il(mInterfaceLock);
911    Mutex::Autolock l(mLock);
912
913    switch (mStatus) {
914        case STATUS_ERROR:
915            CLOGE("Device has encountered a serious error");
916            return INVALID_OPERATION;
917        case STATUS_UNINITIALIZED:
918            CLOGE("Device is not initialized!");
919            return INVALID_OPERATION;
920        case STATUS_UNCONFIGURED:
921        case STATUS_CONFIGURED:
922        case STATUS_ACTIVE:
923            // OK
924            break;
925        default:
926            SET_ERR_L("Unexpected status: %d", mStatus);
927            return INVALID_OPERATION;
928    }
929
930    const camera_metadata_t *rawRequest;
931    ATRACE_BEGIN("camera3->construct_default_request_settings");
932    rawRequest = mHal3Device->ops->construct_default_request_settings(
933        mHal3Device, templateId);
934    ATRACE_END();
935    if (rawRequest == NULL) {
936        SET_ERR_L("HAL is unable to construct default settings for template %d",
937                templateId);
938        return DEAD_OBJECT;
939    }
940    *request = rawRequest;
941
942    return OK;
943}
944
945status_t Camera3Device::waitUntilDrained() {
946    ATRACE_CALL();
947    Mutex::Autolock il(mInterfaceLock);
948    Mutex::Autolock l(mLock);
949
950    return waitUntilDrainedLocked();
951}
952
953status_t Camera3Device::waitUntilDrainedLocked() {
954    switch (mStatus) {
955        case STATUS_UNINITIALIZED:
956        case STATUS_UNCONFIGURED:
957            ALOGV("%s: Already idle", __FUNCTION__);
958            return OK;
959        case STATUS_CONFIGURED:
960            // To avoid race conditions, check with tracker to be sure
961        case STATUS_ERROR:
962        case STATUS_ACTIVE:
963            // Need to verify shut down
964            break;
965        default:
966            SET_ERR_L("Unexpected status: %d",mStatus);
967            return INVALID_OPERATION;
968    }
969
970    ALOGV("%s: Camera %d: Waiting until idle", __FUNCTION__, mId);
971    status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
972    return res;
973}
974
975// Pause to reconfigure
976status_t Camera3Device::internalPauseAndWaitLocked() {
977    mRequestThread->setPaused(true);
978    mPauseStateNotify = true;
979
980    ALOGV("%s: Camera %d: Internal wait until idle", __FUNCTION__, mId);
981    status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
982    if (res != OK) {
983        SET_ERR_L("Can't idle device in %f seconds!",
984                kShutdownTimeout/1e9);
985    }
986
987    return res;
988}
989
990// Resume after internalPauseAndWaitLocked
991status_t Camera3Device::internalResumeLocked() {
992    status_t res;
993
994    mRequestThread->setPaused(false);
995
996    res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
997    if (res != OK) {
998        SET_ERR_L("Can't transition to active in %f seconds!",
999                kActiveTimeout/1e9);
1000    }
1001    mPauseStateNotify = false;
1002    return OK;
1003}
1004
1005status_t Camera3Device::waitUntilStateThenRelock(bool active,
1006        nsecs_t timeout) {
1007    status_t res = OK;
1008    if (active == (mStatus == STATUS_ACTIVE)) {
1009        // Desired state already reached
1010        return res;
1011    }
1012
1013    bool stateSeen = false;
1014    do {
1015        mRecentStatusUpdates.clear();
1016
1017        res = mStatusChanged.waitRelative(mLock, timeout);
1018        if (res != OK) break;
1019
1020        // Check state change history during wait
1021        for (size_t i = 0; i < mRecentStatusUpdates.size(); i++) {
1022            if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1023                stateSeen = true;
1024                break;
1025            }
1026        }
1027    } while (!stateSeen);
1028
1029    return res;
1030}
1031
1032
1033status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
1034    ATRACE_CALL();
1035    Mutex::Autolock l(mOutputLock);
1036
1037    if (listener != NULL && mListener != NULL) {
1038        ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1039    }
1040    mListener = listener;
1041
1042    return OK;
1043}
1044
1045bool Camera3Device::willNotify3A() {
1046    return false;
1047}
1048
1049status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
1050    status_t res;
1051    Mutex::Autolock l(mOutputLock);
1052
1053    while (mResultQueue.empty()) {
1054        res = mResultSignal.waitRelative(mOutputLock, timeout);
1055        if (res == TIMED_OUT) {
1056            return res;
1057        } else if (res != OK) {
1058            ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)",
1059                    __FUNCTION__, mId, timeout, strerror(-res), res);
1060            return res;
1061        }
1062    }
1063    return OK;
1064}
1065
1066status_t Camera3Device::getNextResult(CaptureResult *frame) {
1067    ATRACE_CALL();
1068    Mutex::Autolock l(mOutputLock);
1069
1070    if (mResultQueue.empty()) {
1071        return NOT_ENOUGH_DATA;
1072    }
1073
1074    if (frame == NULL) {
1075        ALOGE("%s: argument cannot be NULL", __FUNCTION__);
1076        return BAD_VALUE;
1077    }
1078
1079    CaptureResult &result = *(mResultQueue.begin());
1080    frame->mResultExtras = result.mResultExtras;
1081    frame->mMetadata.acquire(result.mMetadata);
1082    mResultQueue.erase(mResultQueue.begin());
1083
1084    return OK;
1085}
1086
1087status_t Camera3Device::triggerAutofocus(uint32_t id) {
1088    ATRACE_CALL();
1089    Mutex::Autolock il(mInterfaceLock);
1090
1091    ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
1092    // Mix-in this trigger into the next request and only the next request.
1093    RequestTrigger trigger[] = {
1094        {
1095            ANDROID_CONTROL_AF_TRIGGER,
1096            ANDROID_CONTROL_AF_TRIGGER_START
1097        },
1098        {
1099            ANDROID_CONTROL_AF_TRIGGER_ID,
1100            static_cast<int32_t>(id)
1101        },
1102    };
1103
1104    return mRequestThread->queueTrigger(trigger,
1105                                        sizeof(trigger)/sizeof(trigger[0]));
1106}
1107
1108status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
1109    ATRACE_CALL();
1110    Mutex::Autolock il(mInterfaceLock);
1111
1112    ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
1113    // Mix-in this trigger into the next request and only the next request.
1114    RequestTrigger trigger[] = {
1115        {
1116            ANDROID_CONTROL_AF_TRIGGER,
1117            ANDROID_CONTROL_AF_TRIGGER_CANCEL
1118        },
1119        {
1120            ANDROID_CONTROL_AF_TRIGGER_ID,
1121            static_cast<int32_t>(id)
1122        },
1123    };
1124
1125    return mRequestThread->queueTrigger(trigger,
1126                                        sizeof(trigger)/sizeof(trigger[0]));
1127}
1128
1129status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
1130    ATRACE_CALL();
1131    Mutex::Autolock il(mInterfaceLock);
1132
1133    ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
1134    // Mix-in this trigger into the next request and only the next request.
1135    RequestTrigger trigger[] = {
1136        {
1137            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1138            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
1139        },
1140        {
1141            ANDROID_CONTROL_AE_PRECAPTURE_ID,
1142            static_cast<int32_t>(id)
1143        },
1144    };
1145
1146    return mRequestThread->queueTrigger(trigger,
1147                                        sizeof(trigger)/sizeof(trigger[0]));
1148}
1149
1150status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
1151        buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
1152    ATRACE_CALL();
1153    (void)reprocessStreamId; (void)buffer; (void)listener;
1154
1155    CLOGE("Unimplemented");
1156    return INVALID_OPERATION;
1157}
1158
1159status_t Camera3Device::flush(int64_t *frameNumber) {
1160    ATRACE_CALL();
1161    ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
1162    Mutex::Autolock il(mInterfaceLock);
1163    Mutex::Autolock l(mLock);
1164
1165    mRequestThread->clear(/*out*/frameNumber);
1166    status_t res;
1167    if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) {
1168        res = mHal3Device->ops->flush(mHal3Device);
1169    } else {
1170        res = waitUntilDrainedLocked();
1171    }
1172
1173    return res;
1174}
1175
1176/**
1177 * Methods called by subclasses
1178 */
1179
1180void Camera3Device::notifyStatus(bool idle) {
1181    {
1182        // Need mLock to safely update state and synchronize to current
1183        // state of methods in flight.
1184        Mutex::Autolock l(mLock);
1185        // We can get various system-idle notices from the status tracker
1186        // while starting up. Only care about them if we've actually sent
1187        // in some requests recently.
1188        if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
1189            return;
1190        }
1191        ALOGV("%s: Camera %d: Now %s", __FUNCTION__, mId,
1192                idle ? "idle" : "active");
1193        mStatus = idle ? STATUS_CONFIGURED : STATUS_ACTIVE;
1194        mRecentStatusUpdates.add(mStatus);
1195        mStatusChanged.signal();
1196
1197        // Skip notifying listener if we're doing some user-transparent
1198        // state changes
1199        if (mPauseStateNotify) return;
1200    }
1201    NotificationListener *listener;
1202    {
1203        Mutex::Autolock l(mOutputLock);
1204        listener = mListener;
1205    }
1206    if (idle && listener != NULL) {
1207        listener->notifyIdle();
1208    }
1209}
1210
1211/**
1212 * Camera3Device private methods
1213 */
1214
1215sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
1216        const CameraMetadata &request) {
1217    ATRACE_CALL();
1218    status_t res;
1219
1220    sp<CaptureRequest> newRequest = new CaptureRequest;
1221    newRequest->mSettings = request;
1222
1223    camera_metadata_entry_t inputStreams =
1224            newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
1225    if (inputStreams.count > 0) {
1226        if (mInputStream == NULL ||
1227                mInputStream->getId() != inputStreams.data.i32[0]) {
1228            CLOGE("Request references unknown input stream %d",
1229                    inputStreams.data.u8[0]);
1230            return NULL;
1231        }
1232        // Lazy completion of stream configuration (allocation/registration)
1233        // on first use
1234        if (mInputStream->isConfiguring()) {
1235            res = mInputStream->finishConfiguration(mHal3Device);
1236            if (res != OK) {
1237                SET_ERR_L("Unable to finish configuring input stream %d:"
1238                        " %s (%d)",
1239                        mInputStream->getId(), strerror(-res), res);
1240                return NULL;
1241            }
1242        }
1243
1244        newRequest->mInputStream = mInputStream;
1245        newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
1246    }
1247
1248    camera_metadata_entry_t streams =
1249            newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
1250    if (streams.count == 0) {
1251        CLOGE("Zero output streams specified!");
1252        return NULL;
1253    }
1254
1255    for (size_t i = 0; i < streams.count; i++) {
1256        int idx = mOutputStreams.indexOfKey(streams.data.i32[i]);
1257        if (idx == NAME_NOT_FOUND) {
1258            CLOGE("Request references unknown stream %d",
1259                    streams.data.u8[i]);
1260            return NULL;
1261        }
1262        sp<Camera3OutputStreamInterface> stream =
1263                mOutputStreams.editValueAt(idx);
1264
1265        // Lazy completion of stream configuration (allocation/registration)
1266        // on first use
1267        if (stream->isConfiguring()) {
1268            res = stream->finishConfiguration(mHal3Device);
1269            if (res != OK) {
1270                SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
1271                        stream->getId(), strerror(-res), res);
1272                return NULL;
1273            }
1274        }
1275
1276        newRequest->mOutputStreams.push(stream);
1277    }
1278    newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
1279
1280    return newRequest;
1281}
1282
1283status_t Camera3Device::configureStreamsLocked() {
1284    ATRACE_CALL();
1285    status_t res;
1286
1287    if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
1288        CLOGE("Not idle");
1289        return INVALID_OPERATION;
1290    }
1291
1292    if (!mNeedConfig) {
1293        ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
1294        return OK;
1295    }
1296
1297    // Start configuring the streams
1298    ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId);
1299
1300    camera3_stream_configuration config;
1301
1302    config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
1303
1304    Vector<camera3_stream_t*> streams;
1305    streams.setCapacity(config.num_streams);
1306
1307    if (mInputStream != NULL) {
1308        camera3_stream_t *inputStream;
1309        inputStream = mInputStream->startConfiguration();
1310        if (inputStream == NULL) {
1311            SET_ERR_L("Can't start input stream configuration");
1312            return INVALID_OPERATION;
1313        }
1314        streams.add(inputStream);
1315    }
1316
1317    for (size_t i = 0; i < mOutputStreams.size(); i++) {
1318
1319        // Don't configure bidi streams twice, nor add them twice to the list
1320        if (mOutputStreams[i].get() ==
1321            static_cast<Camera3StreamInterface*>(mInputStream.get())) {
1322
1323            config.num_streams--;
1324            continue;
1325        }
1326
1327        camera3_stream_t *outputStream;
1328        outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
1329        if (outputStream == NULL) {
1330            SET_ERR_L("Can't start output stream configuration");
1331            return INVALID_OPERATION;
1332        }
1333        streams.add(outputStream);
1334    }
1335
1336    config.streams = streams.editArray();
1337
1338    // Do the HAL configuration; will potentially touch stream
1339    // max_buffers, usage, priv fields.
1340    ATRACE_BEGIN("camera3->configure_streams");
1341    res = mHal3Device->ops->configure_streams(mHal3Device, &config);
1342    ATRACE_END();
1343
1344    if (res != OK) {
1345        SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
1346                strerror(-res), res);
1347        return res;
1348    }
1349
1350    // Finish all stream configuration immediately.
1351    // TODO: Try to relax this later back to lazy completion, which should be
1352    // faster
1353
1354    if (mInputStream != NULL && mInputStream->isConfiguring()) {
1355        res = mInputStream->finishConfiguration(mHal3Device);
1356        if (res != OK) {
1357            SET_ERR_L("Can't finish configuring input stream %d: %s (%d)",
1358                    mInputStream->getId(), strerror(-res), res);
1359            return res;
1360        }
1361    }
1362
1363    for (size_t i = 0; i < mOutputStreams.size(); i++) {
1364        sp<Camera3OutputStreamInterface> outputStream =
1365            mOutputStreams.editValueAt(i);
1366        if (outputStream->isConfiguring()) {
1367            res = outputStream->finishConfiguration(mHal3Device);
1368            if (res != OK) {
1369                SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
1370                        outputStream->getId(), strerror(-res), res);
1371                return res;
1372            }
1373        }
1374    }
1375
1376    // Request thread needs to know to avoid using repeat-last-settings protocol
1377    // across configure_streams() calls
1378    mRequestThread->configurationComplete();
1379
1380    // Update device state
1381
1382    mNeedConfig = false;
1383
1384    if (config.num_streams > 0) {
1385        mStatus = STATUS_CONFIGURED;
1386    } else {
1387        mStatus = STATUS_UNCONFIGURED;
1388    }
1389
1390    ALOGV("%s: Camera %d: Stream configuration complete", __FUNCTION__, mId);
1391
1392    return OK;
1393}
1394
1395void Camera3Device::setErrorState(const char *fmt, ...) {
1396    Mutex::Autolock l(mLock);
1397    va_list args;
1398    va_start(args, fmt);
1399
1400    setErrorStateLockedV(fmt, args);
1401
1402    va_end(args);
1403}
1404
1405void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
1406    Mutex::Autolock l(mLock);
1407    setErrorStateLockedV(fmt, args);
1408}
1409
1410void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
1411    va_list args;
1412    va_start(args, fmt);
1413
1414    setErrorStateLockedV(fmt, args);
1415
1416    va_end(args);
1417}
1418
1419void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
1420    // Print out all error messages to log
1421    String8 errorCause = String8::formatV(fmt, args);
1422    ALOGE("Camera %d: %s", mId, errorCause.string());
1423
1424    // But only do error state transition steps for the first error
1425    if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
1426
1427    // Save stack trace. View by dumping it later.
1428    CameraTraces::saveTrace();
1429    // TODO: consider adding errorCause and client pid/procname
1430
1431    mErrorCause = errorCause;
1432
1433    mRequestThread->setPaused(true);
1434    mStatus = STATUS_ERROR;
1435}
1436
1437/**
1438 * In-flight request management
1439 */
1440
1441status_t Camera3Device::registerInFlight(uint32_t frameNumber,
1442        int32_t numBuffers, CaptureResultExtras resultExtras) {
1443    ATRACE_CALL();
1444    Mutex::Autolock l(mInFlightLock);
1445
1446    ssize_t res;
1447    res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras));
1448    if (res < 0) return res;
1449
1450    return OK;
1451}
1452
1453/**
1454 * QUIRK(partial results)
1455 * Check if all 3A fields are ready, and send off a partial 3A-only result
1456 * to the output frame queue
1457 */
1458bool Camera3Device::processPartial3AQuirk(
1459        uint32_t frameNumber,
1460        const CameraMetadata& partial, const CaptureResultExtras& resultExtras) {
1461
1462    // Check if all 3A states are present
1463    // The full list of fields is
1464    //   android.control.afMode
1465    //   android.control.awbMode
1466    //   android.control.aeState
1467    //   android.control.awbState
1468    //   android.control.afState
1469    //   android.control.afTriggerID
1470    //   android.control.aePrecaptureID
1471    // TODO: Add android.control.aeMode
1472
1473    bool gotAllStates = true;
1474
1475    uint8_t afMode;
1476    uint8_t awbMode;
1477    uint8_t aeState;
1478    uint8_t afState;
1479    uint8_t awbState;
1480    int32_t afTriggerId;
1481    int32_t aeTriggerId;
1482
1483    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE,
1484        &afMode, frameNumber);
1485
1486    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE,
1487        &awbMode, frameNumber);
1488
1489    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE,
1490        &aeState, frameNumber);
1491
1492    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE,
1493        &afState, frameNumber);
1494
1495    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE,
1496        &awbState, frameNumber);
1497
1498    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_TRIGGER_ID,
1499        &afTriggerId, frameNumber);
1500
1501    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1502        &aeTriggerId, frameNumber);
1503
1504    if (!gotAllStates) return false;
1505
1506    ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, "
1507        "AF state %d, AE state %d, AWB state %d, "
1508        "AF trigger %d, AE precapture trigger %d",
1509        __FUNCTION__, mId, frameNumber, resultExtras.requestId,
1510        afMode, awbMode,
1511        afState, aeState, awbState,
1512        afTriggerId, aeTriggerId);
1513
1514    // Got all states, so construct a minimal result to send
1515    // In addition to the above fields, this means adding in
1516    //   android.request.frameCount
1517    //   android.request.requestId
1518    //   android.quirks.partialResult
1519
1520    const size_t kMinimal3AResultEntries = 10;
1521
1522    Mutex::Autolock l(mOutputLock);
1523
1524    CaptureResult captureResult;
1525    captureResult.mResultExtras = resultExtras;
1526    captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0);
1527    // TODO: change this to sp<CaptureResult>. This will need other changes, including,
1528    // but not limited to CameraDeviceBase::getNextResult
1529    CaptureResult& min3AResult =
1530            *mResultQueue.insert(mResultQueue.end(), captureResult);
1531
1532    if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT,
1533            // TODO: This is problematic casting. Need to fix CameraMetadata.
1534            reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) {
1535        return false;
1536    }
1537
1538    int32_t requestId = resultExtras.requestId;
1539    if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID,
1540            &requestId, frameNumber)) {
1541        return false;
1542    }
1543
1544    static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL;
1545    if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT,
1546            &partialResult, frameNumber)) {
1547        return false;
1548    }
1549
1550    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE,
1551            &afMode, frameNumber)) {
1552        return false;
1553    }
1554
1555    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE,
1556            &awbMode, frameNumber)) {
1557        return false;
1558    }
1559
1560    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE,
1561            &aeState, frameNumber)) {
1562        return false;
1563    }
1564
1565    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE,
1566            &afState, frameNumber)) {
1567        return false;
1568    }
1569
1570    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE,
1571            &awbState, frameNumber)) {
1572        return false;
1573    }
1574
1575    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID,
1576            &afTriggerId, frameNumber)) {
1577        return false;
1578    }
1579
1580    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1581            &aeTriggerId, frameNumber)) {
1582        return false;
1583    }
1584
1585    mResultSignal.signal();
1586
1587    return true;
1588}
1589
1590template<typename T>
1591bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag,
1592        T* value, uint32_t frameNumber) {
1593    (void) frameNumber;
1594
1595    camera_metadata_ro_entry_t entry;
1596
1597    entry = result.find(tag);
1598    if (entry.count == 0) {
1599        ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__,
1600            mId, frameNumber, get_camera_metadata_tag_name(tag));
1601        return false;
1602    }
1603
1604    if (sizeof(T) == sizeof(uint8_t)) {
1605        *value = entry.data.u8[0];
1606    } else if (sizeof(T) == sizeof(int32_t)) {
1607        *value = entry.data.i32[0];
1608    } else {
1609        ALOGE("%s: Unexpected type", __FUNCTION__);
1610        return false;
1611    }
1612    return true;
1613}
1614
1615template<typename T>
1616bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,
1617        const T* value, uint32_t frameNumber) {
1618    if (result.update(tag, value, 1) != NO_ERROR) {
1619        mResultQueue.erase(--mResultQueue.end(), mResultQueue.end());
1620        SET_ERR("Frame %d: Failed to set %s in partial metadata",
1621                frameNumber, get_camera_metadata_tag_name(tag));
1622        return false;
1623    }
1624    return true;
1625}
1626
1627/**
1628 * Camera HAL device callback methods
1629 */
1630
1631void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
1632    ATRACE_CALL();
1633
1634    status_t res;
1635
1636    uint32_t frameNumber = result->frame_number;
1637    if (result->result == NULL && result->num_output_buffers == 0) {
1638        SET_ERR("No result data provided by HAL for frame %d",
1639                frameNumber);
1640        return;
1641    }
1642    bool partialResultQuirk = false;
1643    CameraMetadata collectedQuirkResult;
1644    CaptureResultExtras resultExtras;
1645
1646    // Get capture timestamp and resultExtras from list of in-flight requests,
1647    // where it was added by the shutter notification for this frame.
1648    // Then update the in-flight status and remove the in-flight entry if
1649    // all result data has been received.
1650    nsecs_t timestamp = 0;
1651    {
1652        Mutex::Autolock l(mInFlightLock);
1653        ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
1654        if (idx == NAME_NOT_FOUND) {
1655            SET_ERR("Unknown frame number for capture result: %d",
1656                    frameNumber);
1657            return;
1658        }
1659        InFlightRequest &request = mInFlightMap.editValueAt(idx);
1660        ALOGVV("%s: got InFlightRequest requestId = %" PRId32 ", frameNumber = %" PRId64
1661                ", burstId = %" PRId32,
1662                __FUNCTION__, request.resultExtras.requestId, request.resultExtras.frameNumber,
1663                request.resultExtras.burstId);
1664
1665        // Check if this result carries only partial metadata
1666        if (mUsePartialResultQuirk && result->result != NULL) {
1667            camera_metadata_ro_entry_t partialResultEntry;
1668            res = find_camera_metadata_ro_entry(result->result,
1669                    ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry);
1670            if (res != NAME_NOT_FOUND &&
1671                    partialResultEntry.count > 0 &&
1672                    partialResultEntry.data.u8[0] ==
1673                    ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
1674                // A partial result. Flag this as such, and collect this
1675                // set of metadata into the in-flight entry.
1676                partialResultQuirk = true;
1677                request.partialResultQuirk.collectedResult.append(
1678                    result->result);
1679                request.partialResultQuirk.collectedResult.erase(
1680                    ANDROID_QUIRKS_PARTIAL_RESULT);
1681                // Fire off a 3A-only result if possible
1682                if (!request.partialResultQuirk.haveSent3A) {
1683                    request.partialResultQuirk.haveSent3A =
1684                            processPartial3AQuirk(frameNumber,
1685                                    request.partialResultQuirk.collectedResult,
1686                                    request.resultExtras);
1687                }
1688            }
1689        }
1690
1691        timestamp = request.captureTimestamp;
1692        resultExtras = request.resultExtras;
1693
1694        /**
1695         * One of the following must happen before it's legal to call process_capture_result,
1696         * unless partial metadata is being provided:
1697         * - CAMERA3_MSG_SHUTTER (expected during normal operation)
1698         * - CAMERA3_MSG_ERROR (expected during flush)
1699         */
1700        if (request.requestStatus == OK && timestamp == 0 && !partialResultQuirk) {
1701            SET_ERR("Called before shutter notify for frame %d",
1702                    frameNumber);
1703            return;
1704        }
1705
1706        // Did we get the (final) result metadata for this capture?
1707        if (result->result != NULL && !partialResultQuirk) {
1708            if (request.haveResultMetadata) {
1709                SET_ERR("Called multiple times with metadata for frame %d",
1710                        frameNumber);
1711                return;
1712            }
1713            if (mUsePartialResultQuirk &&
1714                    !request.partialResultQuirk.collectedResult.isEmpty()) {
1715                collectedQuirkResult.acquire(
1716                    request.partialResultQuirk.collectedResult);
1717            }
1718            request.haveResultMetadata = true;
1719        }
1720
1721        request.numBuffersLeft -= result->num_output_buffers;
1722
1723        if (request.numBuffersLeft < 0) {
1724            SET_ERR("Too many buffers returned for frame %d",
1725                    frameNumber);
1726            return;
1727        }
1728
1729        // Check if everything has arrived for this result (buffers and metadata), remove it from
1730        // InFlightMap if both arrived or HAL reports error for this request (i.e. during flush).
1731        if ((request.requestStatus != OK) ||
1732                (request.haveResultMetadata && request.numBuffersLeft == 0)) {
1733            ATRACE_ASYNC_END("frame capture", frameNumber);
1734            mInFlightMap.removeItemsAt(idx, 1);
1735        }
1736
1737        // Sanity check - if we have too many in-flight frames, something has
1738        // likely gone wrong
1739        if (mInFlightMap.size() > kInFlightWarnLimit) {
1740            CLOGE("In-flight list too large: %zu", mInFlightMap.size());
1741        }
1742
1743    }
1744
1745    // Process the result metadata, if provided
1746    bool gotResult = false;
1747    if (result->result != NULL && !partialResultQuirk) {
1748        Mutex::Autolock l(mOutputLock);
1749
1750        gotResult = true;
1751
1752        if (frameNumber != mNextResultFrameNumber) {
1753            SET_ERR("Out-of-order capture result metadata submitted! "
1754                    "(got frame number %d, expecting %d)",
1755                    frameNumber, mNextResultFrameNumber);
1756            return;
1757        }
1758        mNextResultFrameNumber++;
1759
1760        CaptureResult captureResult;
1761        captureResult.mResultExtras = resultExtras;
1762        captureResult.mMetadata = result->result;
1763
1764        if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
1765                (int32_t*)&frameNumber, 1) != OK) {
1766            SET_ERR("Failed to set frame# in metadata (%d)",
1767                    frameNumber);
1768            gotResult = false;
1769        } else {
1770            ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
1771                    __FUNCTION__, mId, frameNumber);
1772        }
1773
1774        // Append any previous partials to form a complete result
1775        if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) {
1776            captureResult.mMetadata.append(collectedQuirkResult);
1777        }
1778
1779        captureResult.mMetadata.sort();
1780
1781        // Check that there's a timestamp in the result metadata
1782
1783        camera_metadata_entry entry =
1784                captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
1785        if (entry.count == 0) {
1786            SET_ERR("No timestamp provided by HAL for frame %d!",
1787                    frameNumber);
1788            gotResult = false;
1789        } else if (timestamp != entry.data.i64[0]) {
1790            SET_ERR("Timestamp mismatch between shutter notify and result"
1791                    " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)",
1792                    frameNumber, timestamp, entry.data.i64[0]);
1793            gotResult = false;
1794        }
1795
1796        if (gotResult) {
1797            // Valid result, insert into queue
1798            List<CaptureResult>::iterator queuedResult =
1799                    mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));
1800            ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64
1801                   ", burstId = %" PRId32, __FUNCTION__,
1802                   queuedResult->mResultExtras.requestId,
1803                   queuedResult->mResultExtras.frameNumber,
1804                   queuedResult->mResultExtras.burstId);
1805        }
1806    } // scope for mOutputLock
1807
1808    // Return completed buffers to their streams with the timestamp
1809
1810    for (size_t i = 0; i < result->num_output_buffers; i++) {
1811        Camera3Stream *stream =
1812                Camera3Stream::cast(result->output_buffers[i].stream);
1813        res = stream->returnBuffer(result->output_buffers[i], timestamp);
1814        // Note: stream may be deallocated at this point, if this buffer was the
1815        // last reference to it.
1816        if (res != OK) {
1817            ALOGE("Can't return buffer %zu for frame %d to its stream: "
1818                    " %s (%d)", i, frameNumber, strerror(-res), res);
1819        }
1820    }
1821
1822    // Finally, signal any waiters for new frames
1823
1824    if (gotResult) {
1825        mResultSignal.signal();
1826    }
1827
1828}
1829
1830void Camera3Device::notify(const camera3_notify_msg *msg) {
1831    ATRACE_CALL();
1832    NotificationListener *listener;
1833    {
1834        Mutex::Autolock l(mOutputLock);
1835        listener = mListener;
1836    }
1837
1838    if (msg == NULL) {
1839        SET_ERR("HAL sent NULL notify message!");
1840        return;
1841    }
1842
1843    switch (msg->type) {
1844        case CAMERA3_MSG_ERROR: {
1845            int streamId = 0;
1846            if (msg->message.error.error_stream != NULL) {
1847                Camera3Stream *stream =
1848                        Camera3Stream::cast(
1849                                  msg->message.error.error_stream);
1850                streamId = stream->getId();
1851            }
1852            ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
1853                    mId, __FUNCTION__, msg->message.error.frame_number,
1854                    streamId, msg->message.error.error_code);
1855
1856            CaptureResultExtras resultExtras;
1857            // Set request error status for the request in the in-flight tracking
1858            {
1859                Mutex::Autolock l(mInFlightLock);
1860                ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number);
1861                if (idx >= 0) {
1862                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
1863                    r.requestStatus = msg->message.error.error_code;
1864                    resultExtras = r.resultExtras;
1865                } else {
1866                    resultExtras.frameNumber = msg->message.error.frame_number;
1867                    ALOGE("Camera %d: %s: cannot find in-flight request on frame %" PRId64
1868                          " error", mId, __FUNCTION__, resultExtras.frameNumber);
1869                }
1870            }
1871
1872            if (listener != NULL) {
1873                if (msg->message.error.error_code == CAMERA3_MSG_ERROR_DEVICE) {
1874                    listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
1875                                          resultExtras);
1876                } else {
1877                    listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
1878                                          resultExtras);
1879                }
1880            } else {
1881                ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__);
1882            }
1883            break;
1884        }
1885        case CAMERA3_MSG_SHUTTER: {
1886            ssize_t idx;
1887            uint32_t frameNumber = msg->message.shutter.frame_number;
1888            nsecs_t timestamp = msg->message.shutter.timestamp;
1889            // Verify ordering of shutter notifications
1890            {
1891                Mutex::Autolock l(mOutputLock);
1892                if (frameNumber != mNextShutterFrameNumber) {
1893                    SET_ERR("Shutter notification out-of-order. Expected "
1894                            "notification for frame %d, got frame %d",
1895                            mNextShutterFrameNumber, frameNumber);
1896                    break;
1897                }
1898                mNextShutterFrameNumber++;
1899            }
1900
1901            CaptureResultExtras resultExtras;
1902
1903            // Set timestamp for the request in the in-flight tracking
1904            // and get the request ID to send upstream
1905            {
1906                Mutex::Autolock l(mInFlightLock);
1907                idx = mInFlightMap.indexOfKey(frameNumber);
1908                if (idx >= 0) {
1909                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
1910                    r.captureTimestamp = timestamp;
1911                    resultExtras = r.resultExtras;
1912                }
1913            }
1914            if (idx < 0) {
1915                SET_ERR("Shutter notification for non-existent frame number %d",
1916                        frameNumber);
1917                break;
1918            }
1919            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
1920                    mId, __FUNCTION__, frameNumber, resultExtras.requestId, timestamp);
1921            // Call listener, if any
1922            if (listener != NULL) {
1923                listener->notifyShutter(resultExtras, timestamp);
1924            }
1925            break;
1926        }
1927        default:
1928            SET_ERR("Unknown notify message from HAL: %d",
1929                    msg->type);
1930    }
1931}
1932
1933CameraMetadata Camera3Device::getLatestRequestLocked() {
1934    ALOGV("%s", __FUNCTION__);
1935
1936    CameraMetadata retVal;
1937
1938    if (mRequestThread != NULL) {
1939        retVal = mRequestThread->getLatestRequest();
1940    }
1941
1942    return retVal;
1943}
1944
1945
1946/**
1947 * RequestThread inner class methods
1948 */
1949
1950Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
1951        sp<StatusTracker> statusTracker,
1952        camera3_device_t *hal3Device) :
1953        Thread(false),
1954        mParent(parent),
1955        mStatusTracker(statusTracker),
1956        mHal3Device(hal3Device),
1957        mId(getId(parent)),
1958        mReconfigured(false),
1959        mDoPause(false),
1960        mPaused(true),
1961        mFrameNumber(0),
1962        mLatestRequestId(NAME_NOT_FOUND),
1963        mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) {
1964    mStatusId = statusTracker->addComponent();
1965}
1966
1967void Camera3Device::RequestThread::configurationComplete() {
1968    Mutex::Autolock l(mRequestLock);
1969    mReconfigured = true;
1970}
1971
1972status_t Camera3Device::RequestThread::queueRequestList(
1973        List<sp<CaptureRequest> > &requests,
1974        /*out*/
1975        int64_t *lastFrameNumber) {
1976    Mutex::Autolock l(mRequestLock);
1977    for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
1978            ++it) {
1979        mRequestQueue.push_back(*it);
1980    }
1981
1982    if (lastFrameNumber != NULL) {
1983        *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
1984        ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
1985              __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
1986              *lastFrameNumber);
1987    }
1988
1989    unpauseForNewRequests();
1990
1991    return OK;
1992}
1993
1994
1995status_t Camera3Device::RequestThread::queueTrigger(
1996        RequestTrigger trigger[],
1997        size_t count) {
1998
1999    Mutex::Autolock l(mTriggerMutex);
2000    status_t ret;
2001
2002    for (size_t i = 0; i < count; ++i) {
2003        ret = queueTriggerLocked(trigger[i]);
2004
2005        if (ret != OK) {
2006            return ret;
2007        }
2008    }
2009
2010    return OK;
2011}
2012
2013int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
2014    sp<Camera3Device> d = device.promote();
2015    if (d != NULL) return d->mId;
2016    return 0;
2017}
2018
2019status_t Camera3Device::RequestThread::queueTriggerLocked(
2020        RequestTrigger trigger) {
2021
2022    uint32_t tag = trigger.metadataTag;
2023    ssize_t index = mTriggerMap.indexOfKey(tag);
2024
2025    switch (trigger.getTagType()) {
2026        case TYPE_BYTE:
2027        // fall-through
2028        case TYPE_INT32:
2029            break;
2030        default:
2031            ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
2032                    trigger.getTagType());
2033            return INVALID_OPERATION;
2034    }
2035
2036    /**
2037     * Collect only the latest trigger, since we only have 1 field
2038     * in the request settings per trigger tag, and can't send more than 1
2039     * trigger per request.
2040     */
2041    if (index != NAME_NOT_FOUND) {
2042        mTriggerMap.editValueAt(index) = trigger;
2043    } else {
2044        mTriggerMap.add(tag, trigger);
2045    }
2046
2047    return OK;
2048}
2049
2050status_t Camera3Device::RequestThread::setRepeatingRequests(
2051        const RequestList &requests,
2052        /*out*/
2053        int64_t *lastFrameNumber) {
2054    Mutex::Autolock l(mRequestLock);
2055    if (lastFrameNumber != NULL) {
2056        *lastFrameNumber = mRepeatingLastFrameNumber;
2057    }
2058    mRepeatingRequests.clear();
2059    mRepeatingRequests.insert(mRepeatingRequests.begin(),
2060            requests.begin(), requests.end());
2061
2062    unpauseForNewRequests();
2063
2064    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2065    return OK;
2066}
2067
2068status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
2069    Mutex::Autolock l(mRequestLock);
2070    mRepeatingRequests.clear();
2071    if (lastFrameNumber != NULL) {
2072        *lastFrameNumber = mRepeatingLastFrameNumber;
2073    }
2074    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2075    return OK;
2076}
2077
2078status_t Camera3Device::RequestThread::clear(/*out*/int64_t *lastFrameNumber) {
2079    Mutex::Autolock l(mRequestLock);
2080    ALOGV("RequestThread::%s:", __FUNCTION__);
2081    mRepeatingRequests.clear();
2082    mRequestQueue.clear();
2083    mTriggerMap.clear();
2084    if (lastFrameNumber != NULL) {
2085        *lastFrameNumber = mRepeatingLastFrameNumber;
2086    }
2087    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2088    return OK;
2089}
2090
2091void Camera3Device::RequestThread::setPaused(bool paused) {
2092    Mutex::Autolock l(mPauseLock);
2093    mDoPause = paused;
2094    mDoPauseSignal.signal();
2095}
2096
2097status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
2098        int32_t requestId, nsecs_t timeout) {
2099    Mutex::Autolock l(mLatestRequestMutex);
2100    status_t res;
2101    while (mLatestRequestId != requestId) {
2102        nsecs_t startTime = systemTime();
2103
2104        res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
2105        if (res != OK) return res;
2106
2107        timeout -= (systemTime() - startTime);
2108    }
2109
2110    return OK;
2111}
2112
2113void Camera3Device::RequestThread::requestExit() {
2114    // Call parent to set up shutdown
2115    Thread::requestExit();
2116    // The exit from any possible waits
2117    mDoPauseSignal.signal();
2118    mRequestSignal.signal();
2119}
2120
2121bool Camera3Device::RequestThread::threadLoop() {
2122
2123    status_t res;
2124
2125    // Handle paused state.
2126    if (waitIfPaused()) {
2127        return true;
2128    }
2129
2130    // Get work to do
2131
2132    sp<CaptureRequest> nextRequest = waitForNextRequest();
2133    if (nextRequest == NULL) {
2134        return true;
2135    }
2136
2137    // Create request to HAL
2138    camera3_capture_request_t request = camera3_capture_request_t();
2139    request.frame_number = nextRequest->mResultExtras.frameNumber;
2140    Vector<camera3_stream_buffer_t> outputBuffers;
2141
2142    // Get the request ID, if any
2143    int requestId;
2144    camera_metadata_entry_t requestIdEntry =
2145            nextRequest->mSettings.find(ANDROID_REQUEST_ID);
2146    if (requestIdEntry.count > 0) {
2147        requestId = requestIdEntry.data.i32[0];
2148    } else {
2149        ALOGW("%s: Did not have android.request.id set in the request",
2150                __FUNCTION__);
2151        requestId = NAME_NOT_FOUND;
2152    }
2153
2154    // Insert any queued triggers (before metadata is locked)
2155    int32_t triggerCount;
2156    res = insertTriggers(nextRequest);
2157    if (res < 0) {
2158        SET_ERR("RequestThread: Unable to insert triggers "
2159                "(capture request %d, HAL device: %s (%d)",
2160                request.frame_number, strerror(-res), res);
2161        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2162        return false;
2163    }
2164    triggerCount = res;
2165
2166    bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
2167
2168    // If the request is the same as last, or we had triggers last time
2169    if (mPrevRequest != nextRequest || triggersMixedIn) {
2170        /**
2171         * HAL workaround:
2172         * Insert a dummy trigger ID if a trigger is set but no trigger ID is
2173         */
2174        res = addDummyTriggerIds(nextRequest);
2175        if (res != OK) {
2176            SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
2177                    "(capture request %d, HAL device: %s (%d)",
2178                    request.frame_number, strerror(-res), res);
2179            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2180            return false;
2181        }
2182
2183        /**
2184         * The request should be presorted so accesses in HAL
2185         *   are O(logn). Sidenote, sorting a sorted metadata is nop.
2186         */
2187        nextRequest->mSettings.sort();
2188        request.settings = nextRequest->mSettings.getAndLock();
2189        mPrevRequest = nextRequest;
2190        ALOGVV("%s: Request settings are NEW", __FUNCTION__);
2191
2192        IF_ALOGV() {
2193            camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
2194            find_camera_metadata_ro_entry(
2195                    request.settings,
2196                    ANDROID_CONTROL_AF_TRIGGER,
2197                    &e
2198            );
2199            if (e.count > 0) {
2200                ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
2201                      __FUNCTION__,
2202                      request.frame_number,
2203                      e.data.u8[0]);
2204            }
2205        }
2206    } else {
2207        // leave request.settings NULL to indicate 'reuse latest given'
2208        ALOGVV("%s: Request settings are REUSED",
2209               __FUNCTION__);
2210    }
2211
2212    camera3_stream_buffer_t inputBuffer;
2213
2214    // Fill in buffers
2215
2216    if (nextRequest->mInputStream != NULL) {
2217        request.input_buffer = &inputBuffer;
2218        res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
2219        if (res != OK) {
2220            ALOGE("RequestThread: Can't get input buffer, skipping request:"
2221                    " %s (%d)", strerror(-res), res);
2222            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2223            return true;
2224        }
2225    } else {
2226        request.input_buffer = NULL;
2227    }
2228
2229    outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
2230            nextRequest->mOutputStreams.size());
2231    request.output_buffers = outputBuffers.array();
2232    for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
2233        res = nextRequest->mOutputStreams.editItemAt(i)->
2234                getBuffer(&outputBuffers.editItemAt(i));
2235        if (res != OK) {
2236            ALOGE("RequestThread: Can't get output buffer, skipping request:"
2237                    " %s (%d)", strerror(-res), res);
2238            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2239            return true;
2240        }
2241        request.num_output_buffers++;
2242    }
2243
2244    // Log request in the in-flight queue
2245    sp<Camera3Device> parent = mParent.promote();
2246    if (parent == NULL) {
2247        CLOGE("RequestThread: Parent is gone");
2248        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2249        return false;
2250    }
2251
2252    res = parent->registerInFlight(request.frame_number,
2253            request.num_output_buffers, nextRequest->mResultExtras);
2254    ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
2255           ", burstId = %" PRId32 ".",
2256            __FUNCTION__,
2257            nextRequest->mResultExtras.requestId, nextRequest->mResultExtras.frameNumber,
2258            nextRequest->mResultExtras.burstId);
2259    if (res != OK) {
2260        SET_ERR("RequestThread: Unable to register new in-flight request:"
2261                " %s (%d)", strerror(-res), res);
2262        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2263        return false;
2264    }
2265
2266    // Inform waitUntilRequestProcessed thread of a new request ID
2267    {
2268        Mutex::Autolock al(mLatestRequestMutex);
2269
2270        mLatestRequestId = requestId;
2271        mLatestRequestSignal.signal();
2272    }
2273
2274    // Submit request and block until ready for next one
2275    ATRACE_ASYNC_BEGIN("frame capture", request.frame_number);
2276    ATRACE_BEGIN("camera3->process_capture_request");
2277    res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
2278    ATRACE_END();
2279
2280    if (res != OK) {
2281        SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
2282                " device: %s (%d)", request.frame_number, strerror(-res), res);
2283        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2284        return false;
2285    }
2286
2287    // Update the latest request sent to HAL
2288    if (request.settings != NULL) { // Don't update them if they were unchanged
2289        Mutex::Autolock al(mLatestRequestMutex);
2290
2291        camera_metadata_t* cloned = clone_camera_metadata(request.settings);
2292        mLatestRequest.acquire(cloned);
2293    }
2294
2295    if (request.settings != NULL) {
2296        nextRequest->mSettings.unlock(request.settings);
2297    }
2298
2299    // Remove any previously queued triggers (after unlock)
2300    res = removeTriggers(mPrevRequest);
2301    if (res != OK) {
2302        SET_ERR("RequestThread: Unable to remove triggers "
2303              "(capture request %d, HAL device: %s (%d)",
2304              request.frame_number, strerror(-res), res);
2305        return false;
2306    }
2307    mPrevTriggers = triggerCount;
2308
2309    // Return input buffer back to framework
2310    if (request.input_buffer != NULL) {
2311        Camera3Stream *stream =
2312            Camera3Stream::cast(request.input_buffer->stream);
2313        res = stream->returnInputBuffer(*(request.input_buffer));
2314        // Note: stream may be deallocated at this point, if this buffer was the
2315        // last reference to it.
2316        if (res != OK) {
2317            ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
2318                    "  its stream:%s (%d)",  __FUNCTION__,
2319                    request.frame_number, strerror(-res), res);
2320            // TODO: Report error upstream
2321        }
2322    }
2323
2324    return true;
2325}
2326
2327CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
2328    Mutex::Autolock al(mLatestRequestMutex);
2329
2330    ALOGV("RequestThread::%s", __FUNCTION__);
2331
2332    return mLatestRequest;
2333}
2334
2335
2336void Camera3Device::RequestThread::cleanUpFailedRequest(
2337        camera3_capture_request_t &request,
2338        sp<CaptureRequest> &nextRequest,
2339        Vector<camera3_stream_buffer_t> &outputBuffers) {
2340
2341    if (request.settings != NULL) {
2342        nextRequest->mSettings.unlock(request.settings);
2343    }
2344    if (request.input_buffer != NULL) {
2345        request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
2346        nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
2347    }
2348    for (size_t i = 0; i < request.num_output_buffers; i++) {
2349        outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
2350        nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
2351            outputBuffers[i], 0);
2352    }
2353}
2354
2355sp<Camera3Device::CaptureRequest>
2356        Camera3Device::RequestThread::waitForNextRequest() {
2357    status_t res;
2358    sp<CaptureRequest> nextRequest;
2359
2360    // Optimized a bit for the simple steady-state case (single repeating
2361    // request), to avoid putting that request in the queue temporarily.
2362    Mutex::Autolock l(mRequestLock);
2363
2364    while (mRequestQueue.empty()) {
2365        if (!mRepeatingRequests.empty()) {
2366            // Always atomically enqueue all requests in a repeating request
2367            // list. Guarantees a complete in-sequence set of captures to
2368            // application.
2369            const RequestList &requests = mRepeatingRequests;
2370            RequestList::const_iterator firstRequest =
2371                    requests.begin();
2372            nextRequest = *firstRequest;
2373            mRequestQueue.insert(mRequestQueue.end(),
2374                    ++firstRequest,
2375                    requests.end());
2376            // No need to wait any longer
2377
2378            mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
2379
2380            break;
2381        }
2382
2383        res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
2384
2385        if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
2386                exitPending()) {
2387            Mutex::Autolock pl(mPauseLock);
2388            if (mPaused == false) {
2389                ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
2390                mPaused = true;
2391                // Let the tracker know
2392                sp<StatusTracker> statusTracker = mStatusTracker.promote();
2393                if (statusTracker != 0) {
2394                    statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2395                }
2396            }
2397            // Stop waiting for now and let thread management happen
2398            return NULL;
2399        }
2400    }
2401
2402    if (nextRequest == NULL) {
2403        // Don't have a repeating request already in hand, so queue
2404        // must have an entry now.
2405        RequestList::iterator firstRequest =
2406                mRequestQueue.begin();
2407        nextRequest = *firstRequest;
2408        mRequestQueue.erase(firstRequest);
2409    }
2410
2411    // In case we've been unpaused by setPaused clearing mDoPause, need to
2412    // update internal pause state (capture/setRepeatingRequest unpause
2413    // directly).
2414    Mutex::Autolock pl(mPauseLock);
2415    if (mPaused) {
2416        ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
2417        sp<StatusTracker> statusTracker = mStatusTracker.promote();
2418        if (statusTracker != 0) {
2419            statusTracker->markComponentActive(mStatusId);
2420        }
2421    }
2422    mPaused = false;
2423
2424    // Check if we've reconfigured since last time, and reset the preview
2425    // request if so. Can't use 'NULL request == repeat' across configure calls.
2426    if (mReconfigured) {
2427        mPrevRequest.clear();
2428        mReconfigured = false;
2429    }
2430
2431    if (nextRequest != NULL) {
2432        nextRequest->mResultExtras.frameNumber = mFrameNumber++;
2433    }
2434    return nextRequest;
2435}
2436
2437bool Camera3Device::RequestThread::waitIfPaused() {
2438    status_t res;
2439    Mutex::Autolock l(mPauseLock);
2440    while (mDoPause) {
2441        if (mPaused == false) {
2442            mPaused = true;
2443            ALOGV("%s: RequestThread: Paused", __FUNCTION__);
2444            // Let the tracker know
2445            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2446            if (statusTracker != 0) {
2447                statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2448            }
2449        }
2450
2451        res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
2452        if (res == TIMED_OUT || exitPending()) {
2453            return true;
2454        }
2455    }
2456    // We don't set mPaused to false here, because waitForNextRequest needs
2457    // to further manage the paused state in case of starvation.
2458    return false;
2459}
2460
2461void Camera3Device::RequestThread::unpauseForNewRequests() {
2462    // With work to do, mark thread as unpaused.
2463    // If paused by request (setPaused), don't resume, to avoid
2464    // extra signaling/waiting overhead to waitUntilPaused
2465    mRequestSignal.signal();
2466    Mutex::Autolock p(mPauseLock);
2467    if (!mDoPause) {
2468        ALOGV("%s: RequestThread: Going active", __FUNCTION__);
2469        if (mPaused) {
2470            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2471            if (statusTracker != 0) {
2472                statusTracker->markComponentActive(mStatusId);
2473            }
2474        }
2475        mPaused = false;
2476    }
2477}
2478
2479void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
2480    sp<Camera3Device> parent = mParent.promote();
2481    if (parent != NULL) {
2482        va_list args;
2483        va_start(args, fmt);
2484
2485        parent->setErrorStateV(fmt, args);
2486
2487        va_end(args);
2488    }
2489}
2490
2491status_t Camera3Device::RequestThread::insertTriggers(
2492        const sp<CaptureRequest> &request) {
2493
2494    Mutex::Autolock al(mTriggerMutex);
2495
2496    CameraMetadata &metadata = request->mSettings;
2497    size_t count = mTriggerMap.size();
2498
2499    for (size_t i = 0; i < count; ++i) {
2500        RequestTrigger trigger = mTriggerMap.valueAt(i);
2501
2502        uint32_t tag = trigger.metadataTag;
2503        camera_metadata_entry entry = metadata.find(tag);
2504
2505        if (entry.count > 0) {
2506            /**
2507             * Already has an entry for this trigger in the request.
2508             * Rewrite it with our requested trigger value.
2509             */
2510            RequestTrigger oldTrigger = trigger;
2511
2512            oldTrigger.entryValue = entry.data.u8[0];
2513
2514            mTriggerReplacedMap.add(tag, oldTrigger);
2515        } else {
2516            /**
2517             * More typical, no trigger entry, so we just add it
2518             */
2519            mTriggerRemovedMap.add(tag, trigger);
2520        }
2521
2522        status_t res;
2523
2524        switch (trigger.getTagType()) {
2525            case TYPE_BYTE: {
2526                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2527                res = metadata.update(tag,
2528                                      &entryValue,
2529                                      /*count*/1);
2530                break;
2531            }
2532            case TYPE_INT32:
2533                res = metadata.update(tag,
2534                                      &trigger.entryValue,
2535                                      /*count*/1);
2536                break;
2537            default:
2538                ALOGE("%s: Type not supported: 0x%x",
2539                      __FUNCTION__,
2540                      trigger.getTagType());
2541                return INVALID_OPERATION;
2542        }
2543
2544        if (res != OK) {
2545            ALOGE("%s: Failed to update request metadata with trigger tag %s"
2546                  ", value %d", __FUNCTION__, trigger.getTagName(),
2547                  trigger.entryValue);
2548            return res;
2549        }
2550
2551        ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
2552              trigger.getTagName(),
2553              trigger.entryValue);
2554    }
2555
2556    mTriggerMap.clear();
2557
2558    return count;
2559}
2560
2561status_t Camera3Device::RequestThread::removeTriggers(
2562        const sp<CaptureRequest> &request) {
2563    Mutex::Autolock al(mTriggerMutex);
2564
2565    CameraMetadata &metadata = request->mSettings;
2566
2567    /**
2568     * Replace all old entries with their old values.
2569     */
2570    for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
2571        RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
2572
2573        status_t res;
2574
2575        uint32_t tag = trigger.metadataTag;
2576        switch (trigger.getTagType()) {
2577            case TYPE_BYTE: {
2578                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2579                res = metadata.update(tag,
2580                                      &entryValue,
2581                                      /*count*/1);
2582                break;
2583            }
2584            case TYPE_INT32:
2585                res = metadata.update(tag,
2586                                      &trigger.entryValue,
2587                                      /*count*/1);
2588                break;
2589            default:
2590                ALOGE("%s: Type not supported: 0x%x",
2591                      __FUNCTION__,
2592                      trigger.getTagType());
2593                return INVALID_OPERATION;
2594        }
2595
2596        if (res != OK) {
2597            ALOGE("%s: Failed to restore request metadata with trigger tag %s"
2598                  ", trigger value %d", __FUNCTION__,
2599                  trigger.getTagName(), trigger.entryValue);
2600            return res;
2601        }
2602    }
2603    mTriggerReplacedMap.clear();
2604
2605    /**
2606     * Remove all new entries.
2607     */
2608    for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
2609        RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
2610        status_t res = metadata.erase(trigger.metadataTag);
2611
2612        if (res != OK) {
2613            ALOGE("%s: Failed to erase metadata with trigger tag %s"
2614                  ", trigger value %d", __FUNCTION__,
2615                  trigger.getTagName(), trigger.entryValue);
2616            return res;
2617        }
2618    }
2619    mTriggerRemovedMap.clear();
2620
2621    return OK;
2622}
2623
2624status_t Camera3Device::RequestThread::addDummyTriggerIds(
2625        const sp<CaptureRequest> &request) {
2626    // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
2627    static const int32_t dummyTriggerId = 1;
2628    status_t res;
2629
2630    CameraMetadata &metadata = request->mSettings;
2631
2632    // If AF trigger is active, insert a dummy AF trigger ID if none already
2633    // exists
2634    camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
2635    camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
2636    if (afTrigger.count > 0 &&
2637            afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
2638            afId.count == 0) {
2639        res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
2640        if (res != OK) return res;
2641    }
2642
2643    // If AE precapture trigger is active, insert a dummy precapture trigger ID
2644    // if none already exists
2645    camera_metadata_entry pcTrigger =
2646            metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
2647    camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
2648    if (pcTrigger.count > 0 &&
2649            pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
2650            pcId.count == 0) {
2651        res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
2652                &dummyTriggerId, 1);
2653        if (res != OK) return res;
2654    }
2655
2656    return OK;
2657}
2658
2659
2660/**
2661 * Static callback forwarding methods from HAL to instance
2662 */
2663
2664void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
2665        const camera3_capture_result *result) {
2666    Camera3Device *d =
2667            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2668    d->processCaptureResult(result);
2669}
2670
2671void Camera3Device::sNotify(const camera3_callback_ops *cb,
2672        const camera3_notify_msg *msg) {
2673    Camera3Device *d =
2674            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2675    d->notify(msg);
2676}
2677
2678}; // namespace android
2679