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