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