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