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