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