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