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