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