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