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