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