Camera3Device.cpp revision fd6ecdd39bd83ea020f78b425e96310380d66c35
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(int32_t frameNumber,
1409        const CameraMetadata& partial) {
1410
1411    // Check if all 3A states are present
1412    // The full list of fields is
1413    //   android.control.afMode
1414    //   android.control.awbMode
1415    //   android.control.aeState
1416    //   android.control.awbState
1417    //   android.control.afState
1418    //   android.control.afTriggerID
1419    //   android.control.aePrecaptureID
1420    // TODO: Add android.control.aeMode
1421
1422    bool gotAllStates = true;
1423
1424    uint8_t afMode;
1425    uint8_t awbMode;
1426    uint8_t aeState;
1427    uint8_t afState;
1428    uint8_t awbState;
1429    int32_t afTriggerId;
1430    int32_t aeTriggerId;
1431
1432    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE,
1433        &afMode, frameNumber);
1434
1435    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE,
1436        &awbMode, frameNumber);
1437
1438    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE,
1439        &aeState, frameNumber);
1440
1441    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE,
1442        &afState, frameNumber);
1443
1444    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE,
1445        &awbState, frameNumber);
1446
1447    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_TRIGGER_ID,
1448        &afTriggerId, frameNumber);
1449
1450    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1451        &aeTriggerId, frameNumber);
1452
1453    if (!gotAllStates) return false;
1454
1455    ALOGVV("%s: Camera %d: Frame %d: AF mode %d, AWB mode %d, "
1456        "AF state %d, AE state %d, AWB state %d, "
1457        "AF trigger %d, AE precapture trigger %d",
1458        __FUNCTION__, mId, frameNumber,
1459        afMode, awbMode,
1460        afState, aeState, awbState,
1461        afTriggerId, aeTriggerId);
1462
1463    // Got all states, so construct a minimal result to send
1464    // In addition to the above fields, this means adding in
1465    //   android.request.frameCount
1466    //   android.quirks.partialResult
1467
1468    const size_t kMinimal3AResultEntries = 7;
1469
1470    Mutex::Autolock l(mOutputLock);
1471
1472    CameraMetadata& min3AResult =
1473            *mResultQueue.insert(
1474                mResultQueue.end(),
1475                CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0));
1476
1477    if (!insert3AResult(min3AResult, ANDROID_REQUEST_FRAME_COUNT,
1478            &frameNumber, frameNumber)) {
1479        return false;
1480    }
1481
1482    static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL;
1483    if (!insert3AResult(min3AResult, ANDROID_QUIRKS_PARTIAL_RESULT,
1484            &partialResult, frameNumber)) {
1485        return false;
1486    }
1487
1488    if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_MODE,
1489            &afMode, frameNumber)) {
1490        return false;
1491    }
1492
1493    if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_MODE,
1494            &awbMode, frameNumber)) {
1495        return false;
1496    }
1497
1498    if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_STATE,
1499            &aeState, frameNumber)) {
1500        return false;
1501    }
1502
1503    if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_STATE,
1504            &afState, frameNumber)) {
1505        return false;
1506    }
1507
1508    if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_STATE,
1509            &awbState, frameNumber)) {
1510        return false;
1511    }
1512
1513    if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_TRIGGER_ID,
1514            &afTriggerId, frameNumber)) {
1515        return false;
1516    }
1517
1518    if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1519            &aeTriggerId, frameNumber)) {
1520        return false;
1521    }
1522
1523    mResultSignal.signal();
1524
1525    return true;
1526}
1527
1528template<typename T>
1529bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag,
1530        T* value, int32_t frameNumber) {
1531    (void) frameNumber;
1532
1533    camera_metadata_ro_entry_t entry;
1534
1535    entry = result.find(tag);
1536    if (entry.count == 0) {
1537        ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__,
1538            mId, frameNumber, get_camera_metadata_tag_name(tag));
1539        return false;
1540    }
1541
1542    if (sizeof(T) == sizeof(uint8_t)) {
1543        *value = entry.data.u8[0];
1544    } else if (sizeof(T) == sizeof(int32_t)) {
1545        *value = entry.data.i32[0];
1546    } else {
1547        ALOGE("%s: Unexpected type", __FUNCTION__);
1548        return false;
1549    }
1550    return true;
1551}
1552
1553template<typename T>
1554bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,
1555        const T* value, int32_t frameNumber) {
1556    if (result.update(tag, value, 1) != NO_ERROR) {
1557        mResultQueue.erase(--mResultQueue.end(), mResultQueue.end());
1558        SET_ERR("Frame %d: Failed to set %s in partial metadata",
1559                frameNumber, get_camera_metadata_tag_name(tag));
1560        return false;
1561    }
1562    return true;
1563}
1564
1565/**
1566 * Camera HAL device callback methods
1567 */
1568
1569void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
1570    ATRACE_CALL();
1571
1572    status_t res;
1573
1574    uint32_t frameNumber = result->frame_number;
1575    if (result->result == NULL && result->num_output_buffers == 0) {
1576        SET_ERR("No result data provided by HAL for frame %d",
1577                frameNumber);
1578        return;
1579    }
1580    bool partialResultQuirk = false;
1581    CameraMetadata collectedQuirkResult;
1582
1583    // Get capture timestamp from list of in-flight requests, where it was added
1584    // by the shutter notification for this frame. Then update the in-flight
1585    // status and remove the in-flight entry if all result data has been
1586    // received.
1587    nsecs_t timestamp = 0;
1588    {
1589        Mutex::Autolock l(mInFlightLock);
1590        ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
1591        if (idx == NAME_NOT_FOUND) {
1592            SET_ERR("Unknown frame number for capture result: %d",
1593                    frameNumber);
1594            return;
1595        }
1596        InFlightRequest &request = mInFlightMap.editValueAt(idx);
1597
1598        // Check if this result carries only partial metadata
1599        if (mUsePartialResultQuirk && result->result != NULL) {
1600            camera_metadata_ro_entry_t partialResultEntry;
1601            res = find_camera_metadata_ro_entry(result->result,
1602                    ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry);
1603            if (res != NAME_NOT_FOUND &&
1604                    partialResultEntry.count > 0 &&
1605                    partialResultEntry.data.u8[0] ==
1606                    ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
1607                // A partial result. Flag this as such, and collect this
1608                // set of metadata into the in-flight entry.
1609                partialResultQuirk = true;
1610                request.partialResultQuirk.collectedResult.append(
1611                    result->result);
1612                request.partialResultQuirk.collectedResult.erase(
1613                    ANDROID_QUIRKS_PARTIAL_RESULT);
1614                // Fire off a 3A-only result if possible
1615                if (!request.partialResultQuirk.haveSent3A) {
1616                    request.partialResultQuirk.haveSent3A =
1617                            processPartial3AQuirk(frameNumber,
1618                                request.partialResultQuirk.collectedResult);
1619                }
1620            }
1621        }
1622
1623        timestamp = request.captureTimestamp;
1624        /**
1625         * One of the following must happen before it's legal to call process_capture_result,
1626         * unless partial metadata is being provided:
1627         * - CAMERA3_MSG_SHUTTER (expected during normal operation)
1628         * - CAMERA3_MSG_ERROR (expected during flush)
1629         */
1630        if (request.requestStatus == OK && timestamp == 0 && !partialResultQuirk) {
1631            SET_ERR("Called before shutter notify for frame %d",
1632                    frameNumber);
1633            return;
1634        }
1635
1636        // Did we get the (final) result metadata for this capture?
1637        if (result->result != NULL && !partialResultQuirk) {
1638            if (request.haveResultMetadata) {
1639                SET_ERR("Called multiple times with metadata for frame %d",
1640                        frameNumber);
1641                return;
1642            }
1643            if (mUsePartialResultQuirk &&
1644                    !request.partialResultQuirk.collectedResult.isEmpty()) {
1645                collectedQuirkResult.acquire(
1646                    request.partialResultQuirk.collectedResult);
1647            }
1648            request.haveResultMetadata = true;
1649        }
1650
1651        request.numBuffersLeft -= result->num_output_buffers;
1652
1653        if (request.numBuffersLeft < 0) {
1654            SET_ERR("Too many buffers returned for frame %d",
1655                    frameNumber);
1656            return;
1657        }
1658
1659        // Check if everything has arrived for this result (buffers and metadata)
1660        if (request.haveResultMetadata && request.numBuffersLeft == 0) {
1661            ATRACE_ASYNC_END("frame capture", frameNumber);
1662            mInFlightMap.removeItemsAt(idx, 1);
1663        }
1664
1665        // Sanity check - if we have too many in-flight frames, something has
1666        // likely gone wrong
1667        if (mInFlightMap.size() > kInFlightWarnLimit) {
1668            CLOGE("In-flight list too large: %d", mInFlightMap.size());
1669        }
1670
1671    }
1672
1673    // Process the result metadata, if provided
1674    bool gotResult = false;
1675    if (result->result != NULL && !partialResultQuirk) {
1676        Mutex::Autolock l(mOutputLock);
1677
1678        gotResult = true;
1679
1680        if (frameNumber != mNextResultFrameNumber) {
1681            SET_ERR("Out-of-order capture result metadata submitted! "
1682                    "(got frame number %d, expecting %d)",
1683                    frameNumber, mNextResultFrameNumber);
1684            return;
1685        }
1686        mNextResultFrameNumber++;
1687
1688        CameraMetadata captureResult;
1689        captureResult = result->result;
1690
1691        if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
1692                        (int32_t*)&frameNumber, 1) != OK) {
1693            SET_ERR("Failed to set frame# in metadata (%d)",
1694                    frameNumber);
1695            gotResult = false;
1696        } else {
1697            ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
1698                    __FUNCTION__, mId, frameNumber);
1699        }
1700
1701        // Append any previous partials to form a complete result
1702        if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) {
1703            captureResult.append(collectedQuirkResult);
1704        }
1705
1706        captureResult.sort();
1707
1708        // Check that there's a timestamp in the result metadata
1709
1710        camera_metadata_entry entry =
1711                captureResult.find(ANDROID_SENSOR_TIMESTAMP);
1712        if (entry.count == 0) {
1713            SET_ERR("No timestamp provided by HAL for frame %d!",
1714                    frameNumber);
1715            gotResult = false;
1716        } else if (timestamp != entry.data.i64[0]) {
1717            SET_ERR("Timestamp mismatch between shutter notify and result"
1718                    " metadata for frame %d (%lld vs %lld respectively)",
1719                    frameNumber, timestamp, entry.data.i64[0]);
1720            gotResult = false;
1721        }
1722
1723        if (gotResult) {
1724            // Valid result, insert into queue
1725            CameraMetadata& queuedResult =
1726                *mResultQueue.insert(mResultQueue.end(), CameraMetadata());
1727            queuedResult.swap(captureResult);
1728        }
1729    } // scope for mOutputLock
1730
1731    // Return completed buffers to their streams with the timestamp
1732
1733    for (size_t i = 0; i < result->num_output_buffers; i++) {
1734        Camera3Stream *stream =
1735                Camera3Stream::cast(result->output_buffers[i].stream);
1736        res = stream->returnBuffer(result->output_buffers[i], timestamp);
1737        // Note: stream may be deallocated at this point, if this buffer was the
1738        // last reference to it.
1739        if (res != OK) {
1740            ALOGE("Can't return buffer %d for frame %d to its stream: "
1741                    " %s (%d)", i, frameNumber, strerror(-res), res);
1742        }
1743    }
1744
1745    // Finally, signal any waiters for new frames
1746
1747    if (gotResult) {
1748        mResultSignal.signal();
1749    }
1750
1751}
1752
1753
1754
1755void Camera3Device::notify(const camera3_notify_msg *msg) {
1756    ATRACE_CALL();
1757    NotificationListener *listener;
1758    {
1759        Mutex::Autolock l(mOutputLock);
1760        listener = mListener;
1761    }
1762
1763    if (msg == NULL) {
1764        SET_ERR("HAL sent NULL notify message!");
1765        return;
1766    }
1767
1768    switch (msg->type) {
1769        case CAMERA3_MSG_ERROR: {
1770            int streamId = 0;
1771            if (msg->message.error.error_stream != NULL) {
1772                Camera3Stream *stream =
1773                        Camera3Stream::cast(
1774                                  msg->message.error.error_stream);
1775                streamId = stream->getId();
1776            }
1777            ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
1778                    mId, __FUNCTION__, msg->message.error.frame_number,
1779                    streamId, msg->message.error.error_code);
1780
1781            // Set request error status for the request in the in-flight tracking
1782            {
1783                Mutex::Autolock l(mInFlightLock);
1784                ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number);
1785                if (idx >= 0) {
1786                    mInFlightMap.editValueAt(idx).requestStatus = msg->message.error.error_code;
1787                }
1788            }
1789
1790            if (listener != NULL) {
1791                listener->notifyError(msg->message.error.error_code,
1792                        msg->message.error.frame_number, streamId);
1793            }
1794            break;
1795        }
1796        case CAMERA3_MSG_SHUTTER: {
1797            ssize_t idx;
1798            uint32_t frameNumber = msg->message.shutter.frame_number;
1799            nsecs_t timestamp = msg->message.shutter.timestamp;
1800            // Verify ordering of shutter notifications
1801            {
1802                Mutex::Autolock l(mOutputLock);
1803                if (frameNumber != mNextShutterFrameNumber) {
1804                    SET_ERR("Shutter notification out-of-order. Expected "
1805                            "notification for frame %d, got frame %d",
1806                            mNextShutterFrameNumber, frameNumber);
1807                    break;
1808                }
1809                mNextShutterFrameNumber++;
1810            }
1811
1812            int32_t requestId = -1;
1813
1814            // Set timestamp for the request in the in-flight tracking
1815            // and get the request ID to send upstream
1816            {
1817                Mutex::Autolock l(mInFlightLock);
1818                idx = mInFlightMap.indexOfKey(frameNumber);
1819                if (idx >= 0) {
1820                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
1821                    r.captureTimestamp = timestamp;
1822                    requestId = r.requestId;
1823                }
1824            }
1825            if (idx < 0) {
1826                SET_ERR("Shutter notification for non-existent frame number %d",
1827                        frameNumber);
1828                break;
1829            }
1830            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %lld",
1831                    mId, __FUNCTION__, frameNumber, requestId, timestamp);
1832            // Call listener, if any
1833            if (listener != NULL) {
1834                listener->notifyShutter(requestId, timestamp);
1835            }
1836            break;
1837        }
1838        default:
1839            SET_ERR("Unknown notify message from HAL: %d",
1840                    msg->type);
1841    }
1842}
1843
1844CameraMetadata Camera3Device::getLatestRequestLocked() {
1845    ALOGV("%s", __FUNCTION__);
1846
1847    CameraMetadata retVal;
1848
1849    if (mRequestThread != NULL) {
1850        retVal = mRequestThread->getLatestRequest();
1851    }
1852
1853    return retVal;
1854}
1855
1856/**
1857 * RequestThread inner class methods
1858 */
1859
1860Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
1861        sp<StatusTracker> statusTracker,
1862        camera3_device_t *hal3Device) :
1863        Thread(false),
1864        mParent(parent),
1865        mStatusTracker(statusTracker),
1866        mHal3Device(hal3Device),
1867        mId(getId(parent)),
1868        mReconfigured(false),
1869        mDoPause(false),
1870        mPaused(true),
1871        mFrameNumber(0),
1872        mLatestRequestId(NAME_NOT_FOUND) {
1873    mStatusId = statusTracker->addComponent();
1874}
1875
1876void Camera3Device::RequestThread::configurationComplete() {
1877    Mutex::Autolock l(mRequestLock);
1878    mReconfigured = true;
1879}
1880
1881status_t Camera3Device::RequestThread::queueRequest(
1882         sp<CaptureRequest> request) {
1883    Mutex::Autolock l(mRequestLock);
1884    mRequestQueue.push_back(request);
1885
1886    unpauseForNewRequests();
1887
1888    return OK;
1889}
1890
1891
1892status_t Camera3Device::RequestThread::queueTrigger(
1893        RequestTrigger trigger[],
1894        size_t count) {
1895
1896    Mutex::Autolock l(mTriggerMutex);
1897    status_t ret;
1898
1899    for (size_t i = 0; i < count; ++i) {
1900        ret = queueTriggerLocked(trigger[i]);
1901
1902        if (ret != OK) {
1903            return ret;
1904        }
1905    }
1906
1907    return OK;
1908}
1909
1910int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
1911    sp<Camera3Device> d = device.promote();
1912    if (d != NULL) return d->mId;
1913    return 0;
1914}
1915
1916status_t Camera3Device::RequestThread::queueTriggerLocked(
1917        RequestTrigger trigger) {
1918
1919    uint32_t tag = trigger.metadataTag;
1920    ssize_t index = mTriggerMap.indexOfKey(tag);
1921
1922    switch (trigger.getTagType()) {
1923        case TYPE_BYTE:
1924        // fall-through
1925        case TYPE_INT32:
1926            break;
1927        default:
1928            ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
1929                    trigger.getTagType());
1930            return INVALID_OPERATION;
1931    }
1932
1933    /**
1934     * Collect only the latest trigger, since we only have 1 field
1935     * in the request settings per trigger tag, and can't send more than 1
1936     * trigger per request.
1937     */
1938    if (index != NAME_NOT_FOUND) {
1939        mTriggerMap.editValueAt(index) = trigger;
1940    } else {
1941        mTriggerMap.add(tag, trigger);
1942    }
1943
1944    return OK;
1945}
1946
1947status_t Camera3Device::RequestThread::setRepeatingRequests(
1948        const RequestList &requests) {
1949    Mutex::Autolock l(mRequestLock);
1950    mRepeatingRequests.clear();
1951    mRepeatingRequests.insert(mRepeatingRequests.begin(),
1952            requests.begin(), requests.end());
1953
1954    unpauseForNewRequests();
1955
1956    return OK;
1957}
1958
1959status_t Camera3Device::RequestThread::clearRepeatingRequests() {
1960    Mutex::Autolock l(mRequestLock);
1961    mRepeatingRequests.clear();
1962    return OK;
1963}
1964
1965status_t Camera3Device::RequestThread::clear() {
1966    Mutex::Autolock l(mRequestLock);
1967    mRepeatingRequests.clear();
1968    mRequestQueue.clear();
1969    mTriggerMap.clear();
1970    return OK;
1971}
1972
1973void Camera3Device::RequestThread::setPaused(bool paused) {
1974    Mutex::Autolock l(mPauseLock);
1975    mDoPause = paused;
1976    mDoPauseSignal.signal();
1977}
1978
1979status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
1980        int32_t requestId, nsecs_t timeout) {
1981    Mutex::Autolock l(mLatestRequestMutex);
1982    status_t res;
1983    while (mLatestRequestId != requestId) {
1984        nsecs_t startTime = systemTime();
1985
1986        res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
1987        if (res != OK) return res;
1988
1989        timeout -= (systemTime() - startTime);
1990    }
1991
1992    return OK;
1993}
1994
1995void Camera3Device::RequestThread::requestExit() {
1996    // Call parent to set up shutdown
1997    Thread::requestExit();
1998    // The exit from any possible waits
1999    mDoPauseSignal.signal();
2000    mRequestSignal.signal();
2001}
2002
2003bool Camera3Device::RequestThread::threadLoop() {
2004
2005    status_t res;
2006
2007    // Handle paused state.
2008    if (waitIfPaused()) {
2009        return true;
2010    }
2011
2012    // Get work to do
2013
2014    sp<CaptureRequest> nextRequest = waitForNextRequest();
2015    if (nextRequest == NULL) {
2016        return true;
2017    }
2018
2019    // Create request to HAL
2020    camera3_capture_request_t request = camera3_capture_request_t();
2021    Vector<camera3_stream_buffer_t> outputBuffers;
2022
2023    // Get the request ID, if any
2024    int requestId;
2025    camera_metadata_entry_t requestIdEntry =
2026            nextRequest->mSettings.find(ANDROID_REQUEST_ID);
2027    if (requestIdEntry.count > 0) {
2028        requestId = requestIdEntry.data.i32[0];
2029    } else {
2030        ALOGW("%s: Did not have android.request.id set in the request",
2031                __FUNCTION__);
2032        requestId = NAME_NOT_FOUND;
2033    }
2034
2035    // Insert any queued triggers (before metadata is locked)
2036    int32_t triggerCount;
2037    res = insertTriggers(nextRequest);
2038    if (res < 0) {
2039        SET_ERR("RequestThread: Unable to insert triggers "
2040                "(capture request %d, HAL device: %s (%d)",
2041                (mFrameNumber+1), strerror(-res), res);
2042        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2043        return false;
2044    }
2045    triggerCount = res;
2046
2047    bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
2048
2049    // If the request is the same as last, or we had triggers last time
2050    if (mPrevRequest != nextRequest || triggersMixedIn) {
2051        /**
2052         * HAL workaround:
2053         * Insert a dummy trigger ID if a trigger is set but no trigger ID is
2054         */
2055        res = addDummyTriggerIds(nextRequest);
2056        if (res != OK) {
2057            SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
2058                    "(capture request %d, HAL device: %s (%d)",
2059                    (mFrameNumber+1), strerror(-res), res);
2060            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2061            return false;
2062        }
2063
2064        /**
2065         * The request should be presorted so accesses in HAL
2066         *   are O(logn). Sidenote, sorting a sorted metadata is nop.
2067         */
2068        nextRequest->mSettings.sort();
2069        request.settings = nextRequest->mSettings.getAndLock();
2070        mPrevRequest = nextRequest;
2071        ALOGVV("%s: Request settings are NEW", __FUNCTION__);
2072
2073        IF_ALOGV() {
2074            camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
2075            find_camera_metadata_ro_entry(
2076                    request.settings,
2077                    ANDROID_CONTROL_AF_TRIGGER,
2078                    &e
2079            );
2080            if (e.count > 0) {
2081                ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
2082                      __FUNCTION__,
2083                      mFrameNumber+1,
2084                      e.data.u8[0]);
2085            }
2086        }
2087    } else {
2088        // leave request.settings NULL to indicate 'reuse latest given'
2089        ALOGVV("%s: Request settings are REUSED",
2090               __FUNCTION__);
2091    }
2092
2093    camera3_stream_buffer_t inputBuffer;
2094
2095    // Fill in buffers
2096
2097    if (nextRequest->mInputStream != NULL) {
2098        request.input_buffer = &inputBuffer;
2099        res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
2100        if (res != OK) {
2101            ALOGE("RequestThread: Can't get input buffer, skipping request:"
2102                    " %s (%d)", strerror(-res), res);
2103            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2104            return true;
2105        }
2106    } else {
2107        request.input_buffer = NULL;
2108    }
2109
2110    outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
2111            nextRequest->mOutputStreams.size());
2112    request.output_buffers = outputBuffers.array();
2113    for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
2114        res = nextRequest->mOutputStreams.editItemAt(i)->
2115                getBuffer(&outputBuffers.editItemAt(i));
2116        if (res != OK) {
2117            ALOGE("RequestThread: Can't get output buffer, skipping request:"
2118                    " %s (%d)", strerror(-res), res);
2119            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2120            return true;
2121        }
2122        request.num_output_buffers++;
2123    }
2124
2125    request.frame_number = mFrameNumber++;
2126
2127    // Log request in the in-flight queue
2128    sp<Camera3Device> parent = mParent.promote();
2129    if (parent == NULL) {
2130        CLOGE("RequestThread: Parent is gone");
2131        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2132        return false;
2133    }
2134
2135    res = parent->registerInFlight(request.frame_number, requestId,
2136            request.num_output_buffers);
2137    if (res != OK) {
2138        SET_ERR("RequestThread: Unable to register new in-flight request:"
2139                " %s (%d)", strerror(-res), res);
2140        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2141        return false;
2142    }
2143
2144    // Inform waitUntilRequestProcessed thread of a new request ID
2145    {
2146        Mutex::Autolock al(mLatestRequestMutex);
2147
2148        mLatestRequestId = requestId;
2149        mLatestRequestSignal.signal();
2150    }
2151
2152    // Submit request and block until ready for next one
2153    ATRACE_ASYNC_BEGIN("frame capture", request.frame_number);
2154    ATRACE_BEGIN("camera3->process_capture_request");
2155    res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
2156    ATRACE_END();
2157
2158    if (res != OK) {
2159        SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
2160                " device: %s (%d)", request.frame_number, strerror(-res), res);
2161        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2162        return false;
2163    }
2164
2165    // Update the latest request sent to HAL
2166    if (request.settings != NULL) { // Don't update them if they were unchanged
2167        Mutex::Autolock al(mLatestRequestMutex);
2168
2169        camera_metadata_t* cloned = clone_camera_metadata(request.settings);
2170        mLatestRequest.acquire(cloned);
2171    }
2172
2173    if (request.settings != NULL) {
2174        nextRequest->mSettings.unlock(request.settings);
2175    }
2176
2177    // Remove any previously queued triggers (after unlock)
2178    res = removeTriggers(mPrevRequest);
2179    if (res != OK) {
2180        SET_ERR("RequestThread: Unable to remove triggers "
2181              "(capture request %d, HAL device: %s (%d)",
2182              request.frame_number, strerror(-res), res);
2183        return false;
2184    }
2185    mPrevTriggers = triggerCount;
2186
2187    // Return input buffer back to framework
2188    if (request.input_buffer != NULL) {
2189        Camera3Stream *stream =
2190            Camera3Stream::cast(request.input_buffer->stream);
2191        res = stream->returnInputBuffer(*(request.input_buffer));
2192        // Note: stream may be deallocated at this point, if this buffer was the
2193        // last reference to it.
2194        if (res != OK) {
2195            ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
2196                    "  its stream:%s (%d)",  __FUNCTION__,
2197                    request.frame_number, strerror(-res), res);
2198            // TODO: Report error upstream
2199        }
2200    }
2201
2202    return true;
2203}
2204
2205CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
2206    Mutex::Autolock al(mLatestRequestMutex);
2207
2208    ALOGV("RequestThread::%s", __FUNCTION__);
2209
2210    return mLatestRequest;
2211}
2212
2213void Camera3Device::RequestThread::cleanUpFailedRequest(
2214        camera3_capture_request_t &request,
2215        sp<CaptureRequest> &nextRequest,
2216        Vector<camera3_stream_buffer_t> &outputBuffers) {
2217
2218    if (request.settings != NULL) {
2219        nextRequest->mSettings.unlock(request.settings);
2220    }
2221    if (request.input_buffer != NULL) {
2222        request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
2223        nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
2224    }
2225    for (size_t i = 0; i < request.num_output_buffers; i++) {
2226        outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
2227        nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
2228            outputBuffers[i], 0);
2229    }
2230}
2231
2232sp<Camera3Device::CaptureRequest>
2233        Camera3Device::RequestThread::waitForNextRequest() {
2234    status_t res;
2235    sp<CaptureRequest> nextRequest;
2236
2237    // Optimized a bit for the simple steady-state case (single repeating
2238    // request), to avoid putting that request in the queue temporarily.
2239    Mutex::Autolock l(mRequestLock);
2240
2241    while (mRequestQueue.empty()) {
2242        if (!mRepeatingRequests.empty()) {
2243            // Always atomically enqueue all requests in a repeating request
2244            // list. Guarantees a complete in-sequence set of captures to
2245            // application.
2246            const RequestList &requests = mRepeatingRequests;
2247            RequestList::const_iterator firstRequest =
2248                    requests.begin();
2249            nextRequest = *firstRequest;
2250            mRequestQueue.insert(mRequestQueue.end(),
2251                    ++firstRequest,
2252                    requests.end());
2253            // No need to wait any longer
2254            break;
2255        }
2256
2257        res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
2258
2259        if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
2260                exitPending()) {
2261            Mutex::Autolock pl(mPauseLock);
2262            if (mPaused == false) {
2263                ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
2264                mPaused = true;
2265                // Let the tracker know
2266                sp<StatusTracker> statusTracker = mStatusTracker.promote();
2267                if (statusTracker != 0) {
2268                    statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2269                }
2270            }
2271            // Stop waiting for now and let thread management happen
2272            return NULL;
2273        }
2274    }
2275
2276    if (nextRequest == NULL) {
2277        // Don't have a repeating request already in hand, so queue
2278        // must have an entry now.
2279        RequestList::iterator firstRequest =
2280                mRequestQueue.begin();
2281        nextRequest = *firstRequest;
2282        mRequestQueue.erase(firstRequest);
2283    }
2284
2285    // In case we've been unpaused by setPaused clearing mDoPause, need to
2286    // update internal pause state (capture/setRepeatingRequest unpause
2287    // directly).
2288    Mutex::Autolock pl(mPauseLock);
2289    if (mPaused) {
2290        ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
2291        sp<StatusTracker> statusTracker = mStatusTracker.promote();
2292        if (statusTracker != 0) {
2293            statusTracker->markComponentActive(mStatusId);
2294        }
2295    }
2296    mPaused = false;
2297
2298    // Check if we've reconfigured since last time, and reset the preview
2299    // request if so. Can't use 'NULL request == repeat' across configure calls.
2300    if (mReconfigured) {
2301        mPrevRequest.clear();
2302        mReconfigured = false;
2303    }
2304
2305    return nextRequest;
2306}
2307
2308bool Camera3Device::RequestThread::waitIfPaused() {
2309    status_t res;
2310    Mutex::Autolock l(mPauseLock);
2311    while (mDoPause) {
2312        if (mPaused == false) {
2313            mPaused = true;
2314            ALOGV("%s: RequestThread: Paused", __FUNCTION__);
2315            // Let the tracker know
2316            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2317            if (statusTracker != 0) {
2318                statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2319            }
2320        }
2321
2322        res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
2323        if (res == TIMED_OUT || exitPending()) {
2324            return true;
2325        }
2326    }
2327    // We don't set mPaused to false here, because waitForNextRequest needs
2328    // to further manage the paused state in case of starvation.
2329    return false;
2330}
2331
2332void Camera3Device::RequestThread::unpauseForNewRequests() {
2333    // With work to do, mark thread as unpaused.
2334    // If paused by request (setPaused), don't resume, to avoid
2335    // extra signaling/waiting overhead to waitUntilPaused
2336    mRequestSignal.signal();
2337    Mutex::Autolock p(mPauseLock);
2338    if (!mDoPause) {
2339        ALOGV("%s: RequestThread: Going active", __FUNCTION__);
2340        if (mPaused) {
2341            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2342            if (statusTracker != 0) {
2343                statusTracker->markComponentActive(mStatusId);
2344            }
2345        }
2346        mPaused = false;
2347    }
2348}
2349
2350void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
2351    sp<Camera3Device> parent = mParent.promote();
2352    if (parent != NULL) {
2353        va_list args;
2354        va_start(args, fmt);
2355
2356        parent->setErrorStateV(fmt, args);
2357
2358        va_end(args);
2359    }
2360}
2361
2362status_t Camera3Device::RequestThread::insertTriggers(
2363        const sp<CaptureRequest> &request) {
2364
2365    Mutex::Autolock al(mTriggerMutex);
2366
2367    CameraMetadata &metadata = request->mSettings;
2368    size_t count = mTriggerMap.size();
2369
2370    for (size_t i = 0; i < count; ++i) {
2371        RequestTrigger trigger = mTriggerMap.valueAt(i);
2372
2373        uint32_t tag = trigger.metadataTag;
2374        camera_metadata_entry entry = metadata.find(tag);
2375
2376        if (entry.count > 0) {
2377            /**
2378             * Already has an entry for this trigger in the request.
2379             * Rewrite it with our requested trigger value.
2380             */
2381            RequestTrigger oldTrigger = trigger;
2382
2383            oldTrigger.entryValue = entry.data.u8[0];
2384
2385            mTriggerReplacedMap.add(tag, oldTrigger);
2386        } else {
2387            /**
2388             * More typical, no trigger entry, so we just add it
2389             */
2390            mTriggerRemovedMap.add(tag, trigger);
2391        }
2392
2393        status_t res;
2394
2395        switch (trigger.getTagType()) {
2396            case TYPE_BYTE: {
2397                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2398                res = metadata.update(tag,
2399                                      &entryValue,
2400                                      /*count*/1);
2401                break;
2402            }
2403            case TYPE_INT32:
2404                res = metadata.update(tag,
2405                                      &trigger.entryValue,
2406                                      /*count*/1);
2407                break;
2408            default:
2409                ALOGE("%s: Type not supported: 0x%x",
2410                      __FUNCTION__,
2411                      trigger.getTagType());
2412                return INVALID_OPERATION;
2413        }
2414
2415        if (res != OK) {
2416            ALOGE("%s: Failed to update request metadata with trigger tag %s"
2417                  ", value %d", __FUNCTION__, trigger.getTagName(),
2418                  trigger.entryValue);
2419            return res;
2420        }
2421
2422        ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
2423              trigger.getTagName(),
2424              trigger.entryValue);
2425    }
2426
2427    mTriggerMap.clear();
2428
2429    return count;
2430}
2431
2432status_t Camera3Device::RequestThread::removeTriggers(
2433        const sp<CaptureRequest> &request) {
2434    Mutex::Autolock al(mTriggerMutex);
2435
2436    CameraMetadata &metadata = request->mSettings;
2437
2438    /**
2439     * Replace all old entries with their old values.
2440     */
2441    for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
2442        RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
2443
2444        status_t res;
2445
2446        uint32_t tag = trigger.metadataTag;
2447        switch (trigger.getTagType()) {
2448            case TYPE_BYTE: {
2449                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2450                res = metadata.update(tag,
2451                                      &entryValue,
2452                                      /*count*/1);
2453                break;
2454            }
2455            case TYPE_INT32:
2456                res = metadata.update(tag,
2457                                      &trigger.entryValue,
2458                                      /*count*/1);
2459                break;
2460            default:
2461                ALOGE("%s: Type not supported: 0x%x",
2462                      __FUNCTION__,
2463                      trigger.getTagType());
2464                return INVALID_OPERATION;
2465        }
2466
2467        if (res != OK) {
2468            ALOGE("%s: Failed to restore request metadata with trigger tag %s"
2469                  ", trigger value %d", __FUNCTION__,
2470                  trigger.getTagName(), trigger.entryValue);
2471            return res;
2472        }
2473    }
2474    mTriggerReplacedMap.clear();
2475
2476    /**
2477     * Remove all new entries.
2478     */
2479    for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
2480        RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
2481        status_t res = metadata.erase(trigger.metadataTag);
2482
2483        if (res != OK) {
2484            ALOGE("%s: Failed to erase metadata with trigger tag %s"
2485                  ", trigger value %d", __FUNCTION__,
2486                  trigger.getTagName(), trigger.entryValue);
2487            return res;
2488        }
2489    }
2490    mTriggerRemovedMap.clear();
2491
2492    return OK;
2493}
2494
2495status_t Camera3Device::RequestThread::addDummyTriggerIds(
2496        const sp<CaptureRequest> &request) {
2497    // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
2498    static const int32_t dummyTriggerId = 1;
2499    status_t res;
2500
2501    CameraMetadata &metadata = request->mSettings;
2502
2503    // If AF trigger is active, insert a dummy AF trigger ID if none already
2504    // exists
2505    camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
2506    camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
2507    if (afTrigger.count > 0 &&
2508            afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
2509            afId.count == 0) {
2510        res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
2511        if (res != OK) return res;
2512    }
2513
2514    // If AE precapture trigger is active, insert a dummy precapture trigger ID
2515    // if none already exists
2516    camera_metadata_entry pcTrigger =
2517            metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
2518    camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
2519    if (pcTrigger.count > 0 &&
2520            pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
2521            pcId.count == 0) {
2522        res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
2523                &dummyTriggerId, 1);
2524        if (res != OK) return res;
2525    }
2526
2527    return OK;
2528}
2529
2530
2531/**
2532 * Static callback forwarding methods from HAL to instance
2533 */
2534
2535void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
2536        const camera3_capture_result *result) {
2537    Camera3Device *d =
2538            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2539    d->processCaptureResult(result);
2540}
2541
2542void Camera3Device::sNotify(const camera3_callback_ops *cb,
2543        const camera3_notify_msg *msg) {
2544    Camera3Device *d =
2545            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2546    d->notify(msg);
2547}
2548
2549}; // namespace android
2550