Camera3Device.cpp revision c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6
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, bool hasInput) {
1537    ATRACE_CALL();
1538    Mutex::Autolock l(mInFlightLock);
1539
1540    ssize_t res;
1541    res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput));
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    bool hasInputBufferInRequest = false;
1733
1734    // Get capture timestamp and resultExtras from list of in-flight requests,
1735    // where it was added by the shutter notification for this frame.
1736    // Then update the in-flight status and remove the in-flight entry if
1737    // all result data has been received.
1738    nsecs_t timestamp = 0;
1739    {
1740        Mutex::Autolock l(mInFlightLock);
1741        ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
1742        if (idx == NAME_NOT_FOUND) {
1743            SET_ERR("Unknown frame number for capture result: %d",
1744                    frameNumber);
1745            return;
1746        }
1747        InFlightRequest &request = mInFlightMap.editValueAt(idx);
1748        ALOGVV("%s: got InFlightRequest requestId = %" PRId32 ", frameNumber = %" PRId64
1749                ", burstId = %" PRId32,
1750                __FUNCTION__, request.resultExtras.requestId, request.resultExtras.frameNumber,
1751                request.resultExtras.burstId);
1752
1753        // Check if this result carries only partial metadata
1754        if (mUsePartialResultQuirk && result->result != NULL) {
1755            camera_metadata_ro_entry_t partialResultEntry;
1756            res = find_camera_metadata_ro_entry(result->result,
1757                    ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry);
1758            if (res != NAME_NOT_FOUND &&
1759                    partialResultEntry.count > 0 &&
1760                    partialResultEntry.data.u8[0] ==
1761                    ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
1762                // A partial result. Flag this as such, and collect this
1763                // set of metadata into the in-flight entry.
1764                partialResultQuirk = true;
1765                request.partialResultQuirk.collectedResult.append(
1766                    result->result);
1767                request.partialResultQuirk.collectedResult.erase(
1768                    ANDROID_QUIRKS_PARTIAL_RESULT);
1769                // Fire off a 3A-only result if possible
1770                if (!request.partialResultQuirk.haveSent3A) {
1771                    request.partialResultQuirk.haveSent3A =
1772                            processPartial3AQuirk(frameNumber,
1773                                    request.partialResultQuirk.collectedResult,
1774                                    request.resultExtras);
1775                }
1776            }
1777        }
1778
1779        timestamp = request.captureTimestamp;
1780        resultExtras = request.resultExtras;
1781        hasInputBufferInRequest = request.hasInputBuffer;
1782
1783        /**
1784         * One of the following must happen before it's legal to call process_capture_result,
1785         * unless partial metadata is being provided:
1786         * - CAMERA3_MSG_SHUTTER (expected during normal operation)
1787         * - CAMERA3_MSG_ERROR (expected during flush)
1788         */
1789        if (request.requestStatus == OK && timestamp == 0 && !partialResultQuirk) {
1790            SET_ERR("Called before shutter notify for frame %d",
1791                    frameNumber);
1792            return;
1793        }
1794
1795        // Did we get the (final) result metadata for this capture?
1796        if (result->result != NULL && !partialResultQuirk) {
1797            if (request.haveResultMetadata) {
1798                SET_ERR("Called multiple times with metadata for frame %d",
1799                        frameNumber);
1800                return;
1801            }
1802            if (mUsePartialResultQuirk &&
1803                    !request.partialResultQuirk.collectedResult.isEmpty()) {
1804                collectedQuirkResult.acquire(
1805                    request.partialResultQuirk.collectedResult);
1806            }
1807            request.haveResultMetadata = true;
1808        }
1809
1810        uint32_t numBuffersReturned = result->num_output_buffers;
1811        if (result->input_buffer != NULL) {
1812            if (hasInputBufferInRequest) {
1813                numBuffersReturned += 1;
1814            } else {
1815                ALOGW("%s: Input buffer should be NULL if there is no input"
1816                        " buffer sent in the request",
1817                        __FUNCTION__);
1818            }
1819        }
1820        request.numBuffersLeft -= numBuffersReturned;
1821        if (request.numBuffersLeft < 0) {
1822            SET_ERR("Too many buffers returned for frame %d",
1823                    frameNumber);
1824            return;
1825        }
1826
1827        // Check if everything has arrived for this result (buffers and metadata), remove it from
1828        // InFlightMap if both arrived or HAL reports error for this request (i.e. during flush).
1829        if ((request.requestStatus != OK) ||
1830                (request.haveResultMetadata && request.numBuffersLeft == 0)) {
1831            ATRACE_ASYNC_END("frame capture", frameNumber);
1832            mInFlightMap.removeItemsAt(idx, 1);
1833        }
1834
1835        // Sanity check - if we have too many in-flight frames, something has
1836        // likely gone wrong
1837        if (mInFlightMap.size() > kInFlightWarnLimit) {
1838            CLOGE("In-flight list too large: %zu", mInFlightMap.size());
1839        }
1840
1841    }
1842
1843    // Process the result metadata, if provided
1844    bool gotResult = false;
1845    if (result->result != NULL && !partialResultQuirk) {
1846        Mutex::Autolock l(mOutputLock);
1847
1848        gotResult = true;
1849
1850        // TODO: need to track errors for tighter bounds on expected frame number
1851        if (frameNumber < mNextResultFrameNumber) {
1852            SET_ERR("Out-of-order capture result metadata submitted! "
1853                    "(got frame number %d, expecting %d)",
1854                    frameNumber, mNextResultFrameNumber);
1855            return;
1856        }
1857        mNextResultFrameNumber = frameNumber + 1;
1858
1859        CaptureResult captureResult;
1860        captureResult.mResultExtras = resultExtras;
1861        captureResult.mMetadata = result->result;
1862
1863        if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
1864                (int32_t*)&frameNumber, 1) != OK) {
1865            SET_ERR("Failed to set frame# in metadata (%d)",
1866                    frameNumber);
1867            gotResult = false;
1868        } else {
1869            ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
1870                    __FUNCTION__, mId, frameNumber);
1871        }
1872
1873        // Append any previous partials to form a complete result
1874        if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) {
1875            captureResult.mMetadata.append(collectedQuirkResult);
1876        }
1877
1878        captureResult.mMetadata.sort();
1879
1880        // Check that there's a timestamp in the result metadata
1881
1882        camera_metadata_entry entry =
1883                captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
1884        if (entry.count == 0) {
1885            SET_ERR("No timestamp provided by HAL for frame %d!",
1886                    frameNumber);
1887            gotResult = false;
1888        } else if (timestamp != entry.data.i64[0]) {
1889            SET_ERR("Timestamp mismatch between shutter notify and result"
1890                    " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)",
1891                    frameNumber, timestamp, entry.data.i64[0]);
1892            gotResult = false;
1893        }
1894
1895        if (gotResult) {
1896            // Valid result, insert into queue
1897            List<CaptureResult>::iterator queuedResult =
1898                    mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));
1899            ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64
1900                   ", burstId = %" PRId32, __FUNCTION__,
1901                   queuedResult->mResultExtras.requestId,
1902                   queuedResult->mResultExtras.frameNumber,
1903                   queuedResult->mResultExtras.burstId);
1904        }
1905    } // scope for mOutputLock
1906
1907    // Return completed buffers to their streams with the timestamp
1908
1909    for (size_t i = 0; i < result->num_output_buffers; i++) {
1910        Camera3Stream *stream =
1911                Camera3Stream::cast(result->output_buffers[i].stream);
1912        res = stream->returnBuffer(result->output_buffers[i], timestamp);
1913        // Note: stream may be deallocated at this point, if this buffer was the
1914        // last reference to it.
1915        if (res != OK) {
1916            ALOGE("Can't return buffer %zu for frame %d to its stream: "
1917                    " %s (%d)", i, frameNumber, strerror(-res), res);
1918        }
1919    }
1920
1921    if (result->input_buffer != NULL) {
1922        if (hasInputBufferInRequest) {
1923            Camera3Stream *stream =
1924                Camera3Stream::cast(result->input_buffer->stream);
1925            res = stream->returnInputBuffer(*(result->input_buffer));
1926            // Note: stream may be deallocated at this point, if this buffer was the
1927            // last reference to it.
1928            if (res != OK) {
1929                ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
1930                      "  its stream:%s (%d)",  __FUNCTION__,
1931                      frameNumber, strerror(-res), res);
1932           } else {
1933               ALOGW("%s: Input buffer should be NULL if there is no input"
1934                       " buffer sent in the request",
1935                       __FUNCTION__);
1936           }
1937        }
1938    }
1939
1940    // Finally, signal any waiters for new frames
1941
1942    if (gotResult) {
1943        mResultSignal.signal();
1944    }
1945
1946}
1947
1948void Camera3Device::notify(const camera3_notify_msg *msg) {
1949    ATRACE_CALL();
1950    NotificationListener *listener;
1951    {
1952        Mutex::Autolock l(mOutputLock);
1953        listener = mListener;
1954    }
1955
1956    if (msg == NULL) {
1957        SET_ERR("HAL sent NULL notify message!");
1958        return;
1959    }
1960
1961    switch (msg->type) {
1962        case CAMERA3_MSG_ERROR: {
1963            int streamId = 0;
1964            if (msg->message.error.error_stream != NULL) {
1965                Camera3Stream *stream =
1966                        Camera3Stream::cast(
1967                                  msg->message.error.error_stream);
1968                streamId = stream->getId();
1969            }
1970            ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
1971                    mId, __FUNCTION__, msg->message.error.frame_number,
1972                    streamId, msg->message.error.error_code);
1973
1974            CaptureResultExtras resultExtras;
1975            // Set request error status for the request in the in-flight tracking
1976            {
1977                Mutex::Autolock l(mInFlightLock);
1978                ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number);
1979                if (idx >= 0) {
1980                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
1981                    r.requestStatus = msg->message.error.error_code;
1982                    resultExtras = r.resultExtras;
1983                } else {
1984                    resultExtras.frameNumber = msg->message.error.frame_number;
1985                    ALOGE("Camera %d: %s: cannot find in-flight request on frame %" PRId64
1986                          " error", mId, __FUNCTION__, resultExtras.frameNumber);
1987                }
1988            }
1989
1990            if (listener != NULL) {
1991                if (msg->message.error.error_code == CAMERA3_MSG_ERROR_DEVICE) {
1992                    listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
1993                                          resultExtras);
1994                }
1995            } else {
1996                ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__);
1997            }
1998            break;
1999        }
2000        case CAMERA3_MSG_SHUTTER: {
2001            ssize_t idx;
2002            uint32_t frameNumber = msg->message.shutter.frame_number;
2003            nsecs_t timestamp = msg->message.shutter.timestamp;
2004            // Verify ordering of shutter notifications
2005            {
2006                Mutex::Autolock l(mOutputLock);
2007                // TODO: need to track errors for tighter bounds on expected frame number.
2008                if (frameNumber < mNextShutterFrameNumber) {
2009                    SET_ERR("Shutter notification out-of-order. Expected "
2010                            "notification for frame %d, got frame %d",
2011                            mNextShutterFrameNumber, frameNumber);
2012                    break;
2013                }
2014                mNextShutterFrameNumber = frameNumber + 1;
2015            }
2016
2017            CaptureResultExtras resultExtras;
2018
2019            // Set timestamp for the request in the in-flight tracking
2020            // and get the request ID to send upstream
2021            {
2022                Mutex::Autolock l(mInFlightLock);
2023                idx = mInFlightMap.indexOfKey(frameNumber);
2024                if (idx >= 0) {
2025                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
2026                    r.captureTimestamp = timestamp;
2027                    resultExtras = r.resultExtras;
2028                }
2029            }
2030            if (idx < 0) {
2031                SET_ERR("Shutter notification for non-existent frame number %d",
2032                        frameNumber);
2033                break;
2034            }
2035            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
2036                    mId, __FUNCTION__, frameNumber, resultExtras.requestId, timestamp);
2037            // Call listener, if any
2038            if (listener != NULL) {
2039                listener->notifyShutter(resultExtras, timestamp);
2040            }
2041            break;
2042        }
2043        default:
2044            SET_ERR("Unknown notify message from HAL: %d",
2045                    msg->type);
2046    }
2047}
2048
2049CameraMetadata Camera3Device::getLatestRequestLocked() {
2050    ALOGV("%s", __FUNCTION__);
2051
2052    CameraMetadata retVal;
2053
2054    if (mRequestThread != NULL) {
2055        retVal = mRequestThread->getLatestRequest();
2056    }
2057
2058    return retVal;
2059}
2060
2061
2062/**
2063 * RequestThread inner class methods
2064 */
2065
2066Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
2067        sp<StatusTracker> statusTracker,
2068        camera3_device_t *hal3Device) :
2069        Thread(false),
2070        mParent(parent),
2071        mStatusTracker(statusTracker),
2072        mHal3Device(hal3Device),
2073        mId(getId(parent)),
2074        mReconfigured(false),
2075        mDoPause(false),
2076        mPaused(true),
2077        mFrameNumber(0),
2078        mLatestRequestId(NAME_NOT_FOUND),
2079        mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) {
2080    mStatusId = statusTracker->addComponent();
2081}
2082
2083void Camera3Device::RequestThread::configurationComplete() {
2084    Mutex::Autolock l(mRequestLock);
2085    mReconfigured = true;
2086}
2087
2088status_t Camera3Device::RequestThread::queueRequestList(
2089        List<sp<CaptureRequest> > &requests,
2090        /*out*/
2091        int64_t *lastFrameNumber) {
2092    Mutex::Autolock l(mRequestLock);
2093    for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
2094            ++it) {
2095        mRequestQueue.push_back(*it);
2096    }
2097
2098    if (lastFrameNumber != NULL) {
2099        *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
2100        ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
2101              __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
2102              *lastFrameNumber);
2103    }
2104
2105    unpauseForNewRequests();
2106
2107    return OK;
2108}
2109
2110
2111status_t Camera3Device::RequestThread::queueTrigger(
2112        RequestTrigger trigger[],
2113        size_t count) {
2114
2115    Mutex::Autolock l(mTriggerMutex);
2116    status_t ret;
2117
2118    for (size_t i = 0; i < count; ++i) {
2119        ret = queueTriggerLocked(trigger[i]);
2120
2121        if (ret != OK) {
2122            return ret;
2123        }
2124    }
2125
2126    return OK;
2127}
2128
2129int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
2130    sp<Camera3Device> d = device.promote();
2131    if (d != NULL) return d->mId;
2132    return 0;
2133}
2134
2135status_t Camera3Device::RequestThread::queueTriggerLocked(
2136        RequestTrigger trigger) {
2137
2138    uint32_t tag = trigger.metadataTag;
2139    ssize_t index = mTriggerMap.indexOfKey(tag);
2140
2141    switch (trigger.getTagType()) {
2142        case TYPE_BYTE:
2143        // fall-through
2144        case TYPE_INT32:
2145            break;
2146        default:
2147            ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
2148                    trigger.getTagType());
2149            return INVALID_OPERATION;
2150    }
2151
2152    /**
2153     * Collect only the latest trigger, since we only have 1 field
2154     * in the request settings per trigger tag, and can't send more than 1
2155     * trigger per request.
2156     */
2157    if (index != NAME_NOT_FOUND) {
2158        mTriggerMap.editValueAt(index) = trigger;
2159    } else {
2160        mTriggerMap.add(tag, trigger);
2161    }
2162
2163    return OK;
2164}
2165
2166status_t Camera3Device::RequestThread::setRepeatingRequests(
2167        const RequestList &requests,
2168        /*out*/
2169        int64_t *lastFrameNumber) {
2170    Mutex::Autolock l(mRequestLock);
2171    if (lastFrameNumber != NULL) {
2172        *lastFrameNumber = mRepeatingLastFrameNumber;
2173    }
2174    mRepeatingRequests.clear();
2175    mRepeatingRequests.insert(mRepeatingRequests.begin(),
2176            requests.begin(), requests.end());
2177
2178    unpauseForNewRequests();
2179
2180    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2181    return OK;
2182}
2183
2184bool Camera3Device::RequestThread::isRepeatingRequestLocked(const sp<CaptureRequest> requestIn) {
2185    if (mRepeatingRequests.empty()) {
2186        return false;
2187    }
2188    int32_t requestId = requestIn->mResultExtras.requestId;
2189    const RequestList &repeatRequests = mRepeatingRequests;
2190    // All repeating requests are guaranteed to have same id so only check first quest
2191    const sp<CaptureRequest> firstRequest = *repeatRequests.begin();
2192    return (firstRequest->mResultExtras.requestId == requestId);
2193}
2194
2195status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
2196    Mutex::Autolock l(mRequestLock);
2197    mRepeatingRequests.clear();
2198    if (lastFrameNumber != NULL) {
2199        *lastFrameNumber = mRepeatingLastFrameNumber;
2200    }
2201    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2202    return OK;
2203}
2204
2205status_t Camera3Device::RequestThread::clear(/*out*/int64_t *lastFrameNumber) {
2206    Mutex::Autolock l(mRequestLock);
2207    ALOGV("RequestThread::%s:", __FUNCTION__);
2208    mRepeatingRequests.clear();
2209
2210    // Decrement repeating frame count for those requests never sent to device
2211    // TODO: Remove this after we have proper error handling so these requests
2212    // will generate an error callback. This might be the only place calling
2213    // isRepeatingRequestLocked. If so, isRepeatingRequestLocked should also be removed.
2214    const RequestList &requests = mRequestQueue;
2215    for (RequestList::const_iterator it = requests.begin();
2216            it != requests.end(); ++it) {
2217        if (isRepeatingRequestLocked(*it)) {
2218            mRepeatingLastFrameNumber--;
2219        }
2220    }
2221    mRequestQueue.clear();
2222    mTriggerMap.clear();
2223    if (lastFrameNumber != NULL) {
2224        *lastFrameNumber = mRepeatingLastFrameNumber;
2225    }
2226    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2227    return OK;
2228}
2229
2230void Camera3Device::RequestThread::setPaused(bool paused) {
2231    Mutex::Autolock l(mPauseLock);
2232    mDoPause = paused;
2233    mDoPauseSignal.signal();
2234}
2235
2236status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
2237        int32_t requestId, nsecs_t timeout) {
2238    Mutex::Autolock l(mLatestRequestMutex);
2239    status_t res;
2240    while (mLatestRequestId != requestId) {
2241        nsecs_t startTime = systemTime();
2242
2243        res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
2244        if (res != OK) return res;
2245
2246        timeout -= (systemTime() - startTime);
2247    }
2248
2249    return OK;
2250}
2251
2252void Camera3Device::RequestThread::requestExit() {
2253    // Call parent to set up shutdown
2254    Thread::requestExit();
2255    // The exit from any possible waits
2256    mDoPauseSignal.signal();
2257    mRequestSignal.signal();
2258}
2259
2260bool Camera3Device::RequestThread::threadLoop() {
2261
2262    status_t res;
2263
2264    // Handle paused state.
2265    if (waitIfPaused()) {
2266        return true;
2267    }
2268
2269    // Get work to do
2270
2271    sp<CaptureRequest> nextRequest = waitForNextRequest();
2272    if (nextRequest == NULL) {
2273        return true;
2274    }
2275
2276    // Create request to HAL
2277    camera3_capture_request_t request = camera3_capture_request_t();
2278    request.frame_number = nextRequest->mResultExtras.frameNumber;
2279    Vector<camera3_stream_buffer_t> outputBuffers;
2280
2281    // Get the request ID, if any
2282    int requestId;
2283    camera_metadata_entry_t requestIdEntry =
2284            nextRequest->mSettings.find(ANDROID_REQUEST_ID);
2285    if (requestIdEntry.count > 0) {
2286        requestId = requestIdEntry.data.i32[0];
2287    } else {
2288        ALOGW("%s: Did not have android.request.id set in the request",
2289                __FUNCTION__);
2290        requestId = NAME_NOT_FOUND;
2291    }
2292
2293    // Insert any queued triggers (before metadata is locked)
2294    int32_t triggerCount;
2295    res = insertTriggers(nextRequest);
2296    if (res < 0) {
2297        SET_ERR("RequestThread: Unable to insert triggers "
2298                "(capture request %d, HAL device: %s (%d)",
2299                request.frame_number, strerror(-res), res);
2300        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2301        return false;
2302    }
2303    triggerCount = res;
2304
2305    bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
2306
2307    // If the request is the same as last, or we had triggers last time
2308    if (mPrevRequest != nextRequest || triggersMixedIn) {
2309        /**
2310         * HAL workaround:
2311         * Insert a dummy trigger ID if a trigger is set but no trigger ID is
2312         */
2313        res = addDummyTriggerIds(nextRequest);
2314        if (res != OK) {
2315            SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
2316                    "(capture request %d, HAL device: %s (%d)",
2317                    request.frame_number, strerror(-res), res);
2318            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2319            return false;
2320        }
2321
2322        /**
2323         * The request should be presorted so accesses in HAL
2324         *   are O(logn). Sidenote, sorting a sorted metadata is nop.
2325         */
2326        nextRequest->mSettings.sort();
2327        request.settings = nextRequest->mSettings.getAndLock();
2328        mPrevRequest = nextRequest;
2329        ALOGVV("%s: Request settings are NEW", __FUNCTION__);
2330
2331        IF_ALOGV() {
2332            camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
2333            find_camera_metadata_ro_entry(
2334                    request.settings,
2335                    ANDROID_CONTROL_AF_TRIGGER,
2336                    &e
2337            );
2338            if (e.count > 0) {
2339                ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
2340                      __FUNCTION__,
2341                      request.frame_number,
2342                      e.data.u8[0]);
2343            }
2344        }
2345    } else {
2346        // leave request.settings NULL to indicate 'reuse latest given'
2347        ALOGVV("%s: Request settings are REUSED",
2348               __FUNCTION__);
2349    }
2350
2351    camera3_stream_buffer_t inputBuffer;
2352    uint32_t totalNumBuffers = 0;
2353
2354    // Fill in buffers
2355
2356    if (nextRequest->mInputStream != NULL) {
2357        request.input_buffer = &inputBuffer;
2358        res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
2359        if (res != OK) {
2360            ALOGE("RequestThread: Can't get input buffer, skipping request:"
2361                    " %s (%d)", strerror(-res), res);
2362            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2363            return true;
2364        }
2365        totalNumBuffers += 1;
2366    } else {
2367        request.input_buffer = NULL;
2368    }
2369
2370    outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
2371            nextRequest->mOutputStreams.size());
2372    request.output_buffers = outputBuffers.array();
2373    for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
2374        res = nextRequest->mOutputStreams.editItemAt(i)->
2375                getBuffer(&outputBuffers.editItemAt(i));
2376        if (res != OK) {
2377            ALOGE("RequestThread: Can't get output buffer, skipping request:"
2378                    " %s (%d)", strerror(-res), res);
2379            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2380            return true;
2381        }
2382        request.num_output_buffers++;
2383    }
2384    totalNumBuffers += request.num_output_buffers;
2385
2386    // Log request in the in-flight queue
2387    sp<Camera3Device> parent = mParent.promote();
2388    if (parent == NULL) {
2389        CLOGE("RequestThread: Parent is gone");
2390        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2391        return false;
2392    }
2393
2394    res = parent->registerInFlight(request.frame_number,
2395            totalNumBuffers, nextRequest->mResultExtras,
2396            /*hasInput*/request.input_buffer != NULL);
2397    ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
2398           ", burstId = %" PRId32 ".",
2399            __FUNCTION__,
2400            nextRequest->mResultExtras.requestId, nextRequest->mResultExtras.frameNumber,
2401            nextRequest->mResultExtras.burstId);
2402    if (res != OK) {
2403        SET_ERR("RequestThread: Unable to register new in-flight request:"
2404                " %s (%d)", strerror(-res), res);
2405        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2406        return false;
2407    }
2408
2409    // Inform waitUntilRequestProcessed thread of a new request ID
2410    {
2411        Mutex::Autolock al(mLatestRequestMutex);
2412
2413        mLatestRequestId = requestId;
2414        mLatestRequestSignal.signal();
2415    }
2416
2417    // Submit request and block until ready for next one
2418    ATRACE_ASYNC_BEGIN("frame capture", request.frame_number);
2419    ATRACE_BEGIN("camera3->process_capture_request");
2420    res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
2421    ATRACE_END();
2422
2423    if (res != OK) {
2424        SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
2425                " device: %s (%d)", request.frame_number, strerror(-res), res);
2426        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2427        return false;
2428    }
2429
2430    // Update the latest request sent to HAL
2431    if (request.settings != NULL) { // Don't update them if they were unchanged
2432        Mutex::Autolock al(mLatestRequestMutex);
2433
2434        camera_metadata_t* cloned = clone_camera_metadata(request.settings);
2435        mLatestRequest.acquire(cloned);
2436    }
2437
2438    if (request.settings != NULL) {
2439        nextRequest->mSettings.unlock(request.settings);
2440    }
2441
2442    // Remove any previously queued triggers (after unlock)
2443    res = removeTriggers(mPrevRequest);
2444    if (res != OK) {
2445        SET_ERR("RequestThread: Unable to remove triggers "
2446              "(capture request %d, HAL device: %s (%d)",
2447              request.frame_number, strerror(-res), res);
2448        return false;
2449    }
2450    mPrevTriggers = triggerCount;
2451
2452    return true;
2453}
2454
2455CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
2456    Mutex::Autolock al(mLatestRequestMutex);
2457
2458    ALOGV("RequestThread::%s", __FUNCTION__);
2459
2460    return mLatestRequest;
2461}
2462
2463
2464void Camera3Device::RequestThread::cleanUpFailedRequest(
2465        camera3_capture_request_t &request,
2466        sp<CaptureRequest> &nextRequest,
2467        Vector<camera3_stream_buffer_t> &outputBuffers) {
2468
2469    if (request.settings != NULL) {
2470        nextRequest->mSettings.unlock(request.settings);
2471    }
2472    if (request.input_buffer != NULL) {
2473        request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
2474        nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
2475    }
2476    for (size_t i = 0; i < request.num_output_buffers; i++) {
2477        outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
2478        nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
2479            outputBuffers[i], 0);
2480    }
2481}
2482
2483sp<Camera3Device::CaptureRequest>
2484        Camera3Device::RequestThread::waitForNextRequest() {
2485    status_t res;
2486    sp<CaptureRequest> nextRequest;
2487
2488    // Optimized a bit for the simple steady-state case (single repeating
2489    // request), to avoid putting that request in the queue temporarily.
2490    Mutex::Autolock l(mRequestLock);
2491
2492    while (mRequestQueue.empty()) {
2493        if (!mRepeatingRequests.empty()) {
2494            // Always atomically enqueue all requests in a repeating request
2495            // list. Guarantees a complete in-sequence set of captures to
2496            // application.
2497            const RequestList &requests = mRepeatingRequests;
2498            RequestList::const_iterator firstRequest =
2499                    requests.begin();
2500            nextRequest = *firstRequest;
2501            mRequestQueue.insert(mRequestQueue.end(),
2502                    ++firstRequest,
2503                    requests.end());
2504            // No need to wait any longer
2505
2506            mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
2507
2508            break;
2509        }
2510
2511        res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
2512
2513        if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
2514                exitPending()) {
2515            Mutex::Autolock pl(mPauseLock);
2516            if (mPaused == false) {
2517                ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
2518                mPaused = true;
2519                // Let the tracker know
2520                sp<StatusTracker> statusTracker = mStatusTracker.promote();
2521                if (statusTracker != 0) {
2522                    statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2523                }
2524            }
2525            // Stop waiting for now and let thread management happen
2526            return NULL;
2527        }
2528    }
2529
2530    if (nextRequest == NULL) {
2531        // Don't have a repeating request already in hand, so queue
2532        // must have an entry now.
2533        RequestList::iterator firstRequest =
2534                mRequestQueue.begin();
2535        nextRequest = *firstRequest;
2536        mRequestQueue.erase(firstRequest);
2537    }
2538
2539    // In case we've been unpaused by setPaused clearing mDoPause, need to
2540    // update internal pause state (capture/setRepeatingRequest unpause
2541    // directly).
2542    Mutex::Autolock pl(mPauseLock);
2543    if (mPaused) {
2544        ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
2545        sp<StatusTracker> statusTracker = mStatusTracker.promote();
2546        if (statusTracker != 0) {
2547            statusTracker->markComponentActive(mStatusId);
2548        }
2549    }
2550    mPaused = false;
2551
2552    // Check if we've reconfigured since last time, and reset the preview
2553    // request if so. Can't use 'NULL request == repeat' across configure calls.
2554    if (mReconfigured) {
2555        mPrevRequest.clear();
2556        mReconfigured = false;
2557    }
2558
2559    if (nextRequest != NULL) {
2560        nextRequest->mResultExtras.frameNumber = mFrameNumber++;
2561    }
2562    return nextRequest;
2563}
2564
2565bool Camera3Device::RequestThread::waitIfPaused() {
2566    status_t res;
2567    Mutex::Autolock l(mPauseLock);
2568    while (mDoPause) {
2569        if (mPaused == false) {
2570            mPaused = true;
2571            ALOGV("%s: RequestThread: Paused", __FUNCTION__);
2572            // Let the tracker know
2573            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2574            if (statusTracker != 0) {
2575                statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2576            }
2577        }
2578
2579        res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
2580        if (res == TIMED_OUT || exitPending()) {
2581            return true;
2582        }
2583    }
2584    // We don't set mPaused to false here, because waitForNextRequest needs
2585    // to further manage the paused state in case of starvation.
2586    return false;
2587}
2588
2589void Camera3Device::RequestThread::unpauseForNewRequests() {
2590    // With work to do, mark thread as unpaused.
2591    // If paused by request (setPaused), don't resume, to avoid
2592    // extra signaling/waiting overhead to waitUntilPaused
2593    mRequestSignal.signal();
2594    Mutex::Autolock p(mPauseLock);
2595    if (!mDoPause) {
2596        ALOGV("%s: RequestThread: Going active", __FUNCTION__);
2597        if (mPaused) {
2598            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2599            if (statusTracker != 0) {
2600                statusTracker->markComponentActive(mStatusId);
2601            }
2602        }
2603        mPaused = false;
2604    }
2605}
2606
2607void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
2608    sp<Camera3Device> parent = mParent.promote();
2609    if (parent != NULL) {
2610        va_list args;
2611        va_start(args, fmt);
2612
2613        parent->setErrorStateV(fmt, args);
2614
2615        va_end(args);
2616    }
2617}
2618
2619status_t Camera3Device::RequestThread::insertTriggers(
2620        const sp<CaptureRequest> &request) {
2621
2622    Mutex::Autolock al(mTriggerMutex);
2623
2624    sp<Camera3Device> parent = mParent.promote();
2625    if (parent == NULL) {
2626        CLOGE("RequestThread: Parent is gone");
2627        return DEAD_OBJECT;
2628    }
2629
2630    CameraMetadata &metadata = request->mSettings;
2631    size_t count = mTriggerMap.size();
2632
2633    for (size_t i = 0; i < count; ++i) {
2634        RequestTrigger trigger = mTriggerMap.valueAt(i);
2635        uint32_t tag = trigger.metadataTag;
2636
2637        if (tag == ANDROID_CONTROL_AF_TRIGGER_ID || tag == ANDROID_CONTROL_AE_PRECAPTURE_ID) {
2638            bool isAeTrigger = (trigger.metadataTag == ANDROID_CONTROL_AE_PRECAPTURE_ID);
2639            uint32_t triggerId = static_cast<uint32_t>(trigger.entryValue);
2640            isAeTrigger ? request->mResultExtras.precaptureTriggerId = triggerId :
2641                          request->mResultExtras.afTriggerId = triggerId;
2642            if (parent->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
2643                continue; // Trigger ID tag is deprecated since device HAL 3.2
2644            }
2645        }
2646
2647        camera_metadata_entry entry = metadata.find(tag);
2648
2649        if (entry.count > 0) {
2650            /**
2651             * Already has an entry for this trigger in the request.
2652             * Rewrite it with our requested trigger value.
2653             */
2654            RequestTrigger oldTrigger = trigger;
2655
2656            oldTrigger.entryValue = entry.data.u8[0];
2657
2658            mTriggerReplacedMap.add(tag, oldTrigger);
2659        } else {
2660            /**
2661             * More typical, no trigger entry, so we just add it
2662             */
2663            mTriggerRemovedMap.add(tag, trigger);
2664        }
2665
2666        status_t res;
2667
2668        switch (trigger.getTagType()) {
2669            case TYPE_BYTE: {
2670                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2671                res = metadata.update(tag,
2672                                      &entryValue,
2673                                      /*count*/1);
2674                break;
2675            }
2676            case TYPE_INT32:
2677                res = metadata.update(tag,
2678                                      &trigger.entryValue,
2679                                      /*count*/1);
2680                break;
2681            default:
2682                ALOGE("%s: Type not supported: 0x%x",
2683                      __FUNCTION__,
2684                      trigger.getTagType());
2685                return INVALID_OPERATION;
2686        }
2687
2688        if (res != OK) {
2689            ALOGE("%s: Failed to update request metadata with trigger tag %s"
2690                  ", value %d", __FUNCTION__, trigger.getTagName(),
2691                  trigger.entryValue);
2692            return res;
2693        }
2694
2695        ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
2696              trigger.getTagName(),
2697              trigger.entryValue);
2698    }
2699
2700    mTriggerMap.clear();
2701
2702    return count;
2703}
2704
2705status_t Camera3Device::RequestThread::removeTriggers(
2706        const sp<CaptureRequest> &request) {
2707    Mutex::Autolock al(mTriggerMutex);
2708
2709    CameraMetadata &metadata = request->mSettings;
2710
2711    /**
2712     * Replace all old entries with their old values.
2713     */
2714    for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
2715        RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
2716
2717        status_t res;
2718
2719        uint32_t tag = trigger.metadataTag;
2720        switch (trigger.getTagType()) {
2721            case TYPE_BYTE: {
2722                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2723                res = metadata.update(tag,
2724                                      &entryValue,
2725                                      /*count*/1);
2726                break;
2727            }
2728            case TYPE_INT32:
2729                res = metadata.update(tag,
2730                                      &trigger.entryValue,
2731                                      /*count*/1);
2732                break;
2733            default:
2734                ALOGE("%s: Type not supported: 0x%x",
2735                      __FUNCTION__,
2736                      trigger.getTagType());
2737                return INVALID_OPERATION;
2738        }
2739
2740        if (res != OK) {
2741            ALOGE("%s: Failed to restore request metadata with trigger tag %s"
2742                  ", trigger value %d", __FUNCTION__,
2743                  trigger.getTagName(), trigger.entryValue);
2744            return res;
2745        }
2746    }
2747    mTriggerReplacedMap.clear();
2748
2749    /**
2750     * Remove all new entries.
2751     */
2752    for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
2753        RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
2754        status_t res = metadata.erase(trigger.metadataTag);
2755
2756        if (res != OK) {
2757            ALOGE("%s: Failed to erase metadata with trigger tag %s"
2758                  ", trigger value %d", __FUNCTION__,
2759                  trigger.getTagName(), trigger.entryValue);
2760            return res;
2761        }
2762    }
2763    mTriggerRemovedMap.clear();
2764
2765    return OK;
2766}
2767
2768status_t Camera3Device::RequestThread::addDummyTriggerIds(
2769        const sp<CaptureRequest> &request) {
2770    // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
2771    static const int32_t dummyTriggerId = 1;
2772    status_t res;
2773
2774    CameraMetadata &metadata = request->mSettings;
2775
2776    // If AF trigger is active, insert a dummy AF trigger ID if none already
2777    // exists
2778    camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
2779    camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
2780    if (afTrigger.count > 0 &&
2781            afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
2782            afId.count == 0) {
2783        res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
2784        if (res != OK) return res;
2785    }
2786
2787    // If AE precapture trigger is active, insert a dummy precapture trigger ID
2788    // if none already exists
2789    camera_metadata_entry pcTrigger =
2790            metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
2791    camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
2792    if (pcTrigger.count > 0 &&
2793            pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
2794            pcId.count == 0) {
2795        res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
2796                &dummyTriggerId, 1);
2797        if (res != OK) return res;
2798    }
2799
2800    return OK;
2801}
2802
2803
2804/**
2805 * Static callback forwarding methods from HAL to instance
2806 */
2807
2808void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
2809        const camera3_capture_result *result) {
2810    Camera3Device *d =
2811            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2812    d->processCaptureResult(result);
2813}
2814
2815void Camera3Device::sNotify(const camera3_callback_ops *cb,
2816        const camera3_notify_msg *msg) {
2817    Camera3Device *d =
2818            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2819    d->notify(msg);
2820}
2821
2822}; // namespace android
2823