Camera3Device.cpp revision f67e23ef637d0b53a0d4bebb68c654234df3da94
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, size_t size, 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, size %zu",
801            mId, mNextStreamId, width, height, format, size);
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            ALOGV("%s: Overwrite Jpeg output buffer size from %zu to %zu",
837                    __FUNCTION__, size, jpegBufferSize);
838        } else {
839            SET_ERR_L("Invalid jpeg buffer size %zd", jpegBufferSize);
840            return BAD_VALUE;
841        }
842
843        newStream = new Camera3OutputStream(mNextStreamId, consumer,
844                width, height, jpegBufferSize, format);
845    } else {
846        newStream = new Camera3OutputStream(mNextStreamId, consumer,
847                width, height, format);
848    }
849    newStream->setStatusTracker(mStatusTracker);
850
851    res = mOutputStreams.add(mNextStreamId, newStream);
852    if (res < 0) {
853        SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
854        return res;
855    }
856
857    *id = mNextStreamId++;
858    mNeedConfig = true;
859
860    // Continue captures if active at start
861    if (wasActive) {
862        ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
863        res = configureStreamsLocked();
864        if (res != OK) {
865            CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
866                    mNextStreamId, strerror(-res), res);
867            return res;
868        }
869        internalResumeLocked();
870    }
871    ALOGV("Camera %d: Created new stream", mId);
872    return OK;
873}
874
875status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
876    ATRACE_CALL();
877    (void)outputId; (void)id;
878
879    CLOGE("Unimplemented");
880    return INVALID_OPERATION;
881}
882
883
884status_t Camera3Device::getStreamInfo(int id,
885        uint32_t *width, uint32_t *height, uint32_t *format) {
886    ATRACE_CALL();
887    Mutex::Autolock il(mInterfaceLock);
888    Mutex::Autolock l(mLock);
889
890    switch (mStatus) {
891        case STATUS_ERROR:
892            CLOGE("Device has encountered a serious error");
893            return INVALID_OPERATION;
894        case STATUS_UNINITIALIZED:
895            CLOGE("Device not initialized!");
896            return INVALID_OPERATION;
897        case STATUS_UNCONFIGURED:
898        case STATUS_CONFIGURED:
899        case STATUS_ACTIVE:
900            // OK
901            break;
902        default:
903            SET_ERR_L("Unexpected status: %d", mStatus);
904            return INVALID_OPERATION;
905    }
906
907    ssize_t idx = mOutputStreams.indexOfKey(id);
908    if (idx == NAME_NOT_FOUND) {
909        CLOGE("Stream %d is unknown", id);
910        return idx;
911    }
912
913    if (width) *width  = mOutputStreams[idx]->getWidth();
914    if (height) *height = mOutputStreams[idx]->getHeight();
915    if (format) *format = mOutputStreams[idx]->getFormat();
916
917    return OK;
918}
919
920status_t Camera3Device::setStreamTransform(int id,
921        int transform) {
922    ATRACE_CALL();
923    Mutex::Autolock il(mInterfaceLock);
924    Mutex::Autolock l(mLock);
925
926    switch (mStatus) {
927        case STATUS_ERROR:
928            CLOGE("Device has encountered a serious error");
929            return INVALID_OPERATION;
930        case STATUS_UNINITIALIZED:
931            CLOGE("Device not initialized");
932            return INVALID_OPERATION;
933        case STATUS_UNCONFIGURED:
934        case STATUS_CONFIGURED:
935        case STATUS_ACTIVE:
936            // OK
937            break;
938        default:
939            SET_ERR_L("Unexpected status: %d", mStatus);
940            return INVALID_OPERATION;
941    }
942
943    ssize_t idx = mOutputStreams.indexOfKey(id);
944    if (idx == NAME_NOT_FOUND) {
945        CLOGE("Stream %d does not exist",
946                id);
947        return BAD_VALUE;
948    }
949
950    return mOutputStreams.editValueAt(idx)->setTransform(transform);
951}
952
953status_t Camera3Device::deleteStream(int id) {
954    ATRACE_CALL();
955    Mutex::Autolock il(mInterfaceLock);
956    Mutex::Autolock l(mLock);
957    status_t res;
958
959    ALOGV("%s: Camera %d: Deleting stream %d", __FUNCTION__, mId, id);
960
961    // CameraDevice semantics require device to already be idle before
962    // deleteStream is called, unlike for createStream.
963    if (mStatus == STATUS_ACTIVE) {
964        ALOGV("%s: Camera %d: Device not idle", __FUNCTION__, mId);
965        return -EBUSY;
966    }
967
968    sp<Camera3StreamInterface> deletedStream;
969    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(id);
970    if (mInputStream != NULL && id == mInputStream->getId()) {
971        deletedStream = mInputStream;
972        mInputStream.clear();
973    } else {
974        if (outputStreamIdx == NAME_NOT_FOUND) {
975            CLOGE("Stream %d does not exist", id);
976            return BAD_VALUE;
977        }
978    }
979
980    // Delete output stream or the output part of a bi-directional stream.
981    if (outputStreamIdx != NAME_NOT_FOUND) {
982        deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
983        mOutputStreams.removeItem(id);
984    }
985
986    // Free up the stream endpoint so that it can be used by some other stream
987    res = deletedStream->disconnect();
988    if (res != OK) {
989        SET_ERR_L("Can't disconnect deleted stream %d", id);
990        // fall through since we want to still list the stream as deleted.
991    }
992    mDeletedStreams.add(deletedStream);
993    mNeedConfig = true;
994
995    return res;
996}
997
998status_t Camera3Device::deleteReprocessStream(int id) {
999    ATRACE_CALL();
1000    (void)id;
1001
1002    CLOGE("Unimplemented");
1003    return INVALID_OPERATION;
1004}
1005
1006
1007status_t Camera3Device::createDefaultRequest(int templateId,
1008        CameraMetadata *request) {
1009    ATRACE_CALL();
1010    ALOGV("%s: for template %d", __FUNCTION__, templateId);
1011    Mutex::Autolock il(mInterfaceLock);
1012    Mutex::Autolock l(mLock);
1013
1014    switch (mStatus) {
1015        case STATUS_ERROR:
1016            CLOGE("Device has encountered a serious error");
1017            return INVALID_OPERATION;
1018        case STATUS_UNINITIALIZED:
1019            CLOGE("Device is not initialized!");
1020            return INVALID_OPERATION;
1021        case STATUS_UNCONFIGURED:
1022        case STATUS_CONFIGURED:
1023        case STATUS_ACTIVE:
1024            // OK
1025            break;
1026        default:
1027            SET_ERR_L("Unexpected status: %d", mStatus);
1028            return INVALID_OPERATION;
1029    }
1030
1031    const camera_metadata_t *rawRequest;
1032    ATRACE_BEGIN("camera3->construct_default_request_settings");
1033    rawRequest = mHal3Device->ops->construct_default_request_settings(
1034        mHal3Device, templateId);
1035    ATRACE_END();
1036    if (rawRequest == NULL) {
1037        SET_ERR_L("HAL is unable to construct default settings for template %d",
1038                templateId);
1039        return DEAD_OBJECT;
1040    }
1041    *request = rawRequest;
1042
1043    return OK;
1044}
1045
1046status_t Camera3Device::waitUntilDrained() {
1047    ATRACE_CALL();
1048    Mutex::Autolock il(mInterfaceLock);
1049    Mutex::Autolock l(mLock);
1050
1051    return waitUntilDrainedLocked();
1052}
1053
1054status_t Camera3Device::waitUntilDrainedLocked() {
1055    switch (mStatus) {
1056        case STATUS_UNINITIALIZED:
1057        case STATUS_UNCONFIGURED:
1058            ALOGV("%s: Already idle", __FUNCTION__);
1059            return OK;
1060        case STATUS_CONFIGURED:
1061            // To avoid race conditions, check with tracker to be sure
1062        case STATUS_ERROR:
1063        case STATUS_ACTIVE:
1064            // Need to verify shut down
1065            break;
1066        default:
1067            SET_ERR_L("Unexpected status: %d",mStatus);
1068            return INVALID_OPERATION;
1069    }
1070
1071    ALOGV("%s: Camera %d: Waiting until idle", __FUNCTION__, mId);
1072    status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
1073    return res;
1074}
1075
1076// Pause to reconfigure
1077status_t Camera3Device::internalPauseAndWaitLocked() {
1078    mRequestThread->setPaused(true);
1079    mPauseStateNotify = true;
1080
1081    ALOGV("%s: Camera %d: Internal wait until idle", __FUNCTION__, mId);
1082    status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
1083    if (res != OK) {
1084        SET_ERR_L("Can't idle device in %f seconds!",
1085                kShutdownTimeout/1e9);
1086    }
1087
1088    return res;
1089}
1090
1091// Resume after internalPauseAndWaitLocked
1092status_t Camera3Device::internalResumeLocked() {
1093    status_t res;
1094
1095    mRequestThread->setPaused(false);
1096
1097    res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
1098    if (res != OK) {
1099        SET_ERR_L("Can't transition to active in %f seconds!",
1100                kActiveTimeout/1e9);
1101    }
1102    mPauseStateNotify = false;
1103    return OK;
1104}
1105
1106status_t Camera3Device::waitUntilStateThenRelock(bool active,
1107        nsecs_t timeout) {
1108    status_t res = OK;
1109    if (active == (mStatus == STATUS_ACTIVE)) {
1110        // Desired state already reached
1111        return res;
1112    }
1113
1114    bool stateSeen = false;
1115    do {
1116        mRecentStatusUpdates.clear();
1117
1118        res = mStatusChanged.waitRelative(mLock, timeout);
1119        if (res != OK) break;
1120
1121        // Check state change history during wait
1122        for (size_t i = 0; i < mRecentStatusUpdates.size(); i++) {
1123            if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1124                stateSeen = true;
1125                break;
1126            }
1127        }
1128    } while (!stateSeen);
1129
1130    return res;
1131}
1132
1133
1134status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
1135    ATRACE_CALL();
1136    Mutex::Autolock l(mOutputLock);
1137
1138    if (listener != NULL && mListener != NULL) {
1139        ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1140    }
1141    mListener = listener;
1142
1143    return OK;
1144}
1145
1146bool Camera3Device::willNotify3A() {
1147    return false;
1148}
1149
1150status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
1151    status_t res;
1152    Mutex::Autolock l(mOutputLock);
1153
1154    while (mResultQueue.empty()) {
1155        res = mResultSignal.waitRelative(mOutputLock, timeout);
1156        if (res == TIMED_OUT) {
1157            return res;
1158        } else if (res != OK) {
1159            ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)",
1160                    __FUNCTION__, mId, timeout, strerror(-res), res);
1161            return res;
1162        }
1163    }
1164    return OK;
1165}
1166
1167status_t Camera3Device::getNextResult(CaptureResult *frame) {
1168    ATRACE_CALL();
1169    Mutex::Autolock l(mOutputLock);
1170
1171    if (mResultQueue.empty()) {
1172        return NOT_ENOUGH_DATA;
1173    }
1174
1175    if (frame == NULL) {
1176        ALOGE("%s: argument cannot be NULL", __FUNCTION__);
1177        return BAD_VALUE;
1178    }
1179
1180    CaptureResult &result = *(mResultQueue.begin());
1181    frame->mResultExtras = result.mResultExtras;
1182    frame->mMetadata.acquire(result.mMetadata);
1183    mResultQueue.erase(mResultQueue.begin());
1184
1185    return OK;
1186}
1187
1188status_t Camera3Device::triggerAutofocus(uint32_t id) {
1189    ATRACE_CALL();
1190    Mutex::Autolock il(mInterfaceLock);
1191
1192    ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
1193    // Mix-in this trigger into the next request and only the next request.
1194    RequestTrigger trigger[] = {
1195        {
1196            ANDROID_CONTROL_AF_TRIGGER,
1197            ANDROID_CONTROL_AF_TRIGGER_START
1198        },
1199        {
1200            ANDROID_CONTROL_AF_TRIGGER_ID,
1201            static_cast<int32_t>(id)
1202        }
1203    };
1204
1205    return mRequestThread->queueTrigger(trigger,
1206                                        sizeof(trigger)/sizeof(trigger[0]));
1207}
1208
1209status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
1210    ATRACE_CALL();
1211    Mutex::Autolock il(mInterfaceLock);
1212
1213    ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
1214    // Mix-in this trigger into the next request and only the next request.
1215    RequestTrigger trigger[] = {
1216        {
1217            ANDROID_CONTROL_AF_TRIGGER,
1218            ANDROID_CONTROL_AF_TRIGGER_CANCEL
1219        },
1220        {
1221            ANDROID_CONTROL_AF_TRIGGER_ID,
1222            static_cast<int32_t>(id)
1223        }
1224    };
1225
1226    return mRequestThread->queueTrigger(trigger,
1227                                        sizeof(trigger)/sizeof(trigger[0]));
1228}
1229
1230status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
1231    ATRACE_CALL();
1232    Mutex::Autolock il(mInterfaceLock);
1233
1234    ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
1235    // Mix-in this trigger into the next request and only the next request.
1236    RequestTrigger trigger[] = {
1237        {
1238            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1239            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
1240        },
1241        {
1242            ANDROID_CONTROL_AE_PRECAPTURE_ID,
1243            static_cast<int32_t>(id)
1244        }
1245    };
1246
1247    return mRequestThread->queueTrigger(trigger,
1248                                        sizeof(trigger)/sizeof(trigger[0]));
1249}
1250
1251status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
1252        buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
1253    ATRACE_CALL();
1254    (void)reprocessStreamId; (void)buffer; (void)listener;
1255
1256    CLOGE("Unimplemented");
1257    return INVALID_OPERATION;
1258}
1259
1260status_t Camera3Device::flush(int64_t *frameNumber) {
1261    ATRACE_CALL();
1262    ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
1263    Mutex::Autolock il(mInterfaceLock);
1264
1265    {
1266        Mutex::Autolock l(mLock);
1267        mRequestThread->clear(/*out*/frameNumber);
1268    }
1269
1270    status_t res;
1271    if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) {
1272        res = mHal3Device->ops->flush(mHal3Device);
1273    } else {
1274        Mutex::Autolock l(mLock);
1275        res = waitUntilDrainedLocked();
1276    }
1277
1278    return res;
1279}
1280
1281uint32_t Camera3Device::getDeviceVersion() {
1282    ATRACE_CALL();
1283    Mutex::Autolock il(mInterfaceLock);
1284    return mDeviceVersion;
1285}
1286
1287/**
1288 * Methods called by subclasses
1289 */
1290
1291void Camera3Device::notifyStatus(bool idle) {
1292    {
1293        // Need mLock to safely update state and synchronize to current
1294        // state of methods in flight.
1295        Mutex::Autolock l(mLock);
1296        // We can get various system-idle notices from the status tracker
1297        // while starting up. Only care about them if we've actually sent
1298        // in some requests recently.
1299        if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
1300            return;
1301        }
1302        ALOGV("%s: Camera %d: Now %s", __FUNCTION__, mId,
1303                idle ? "idle" : "active");
1304        mStatus = idle ? STATUS_CONFIGURED : STATUS_ACTIVE;
1305        mRecentStatusUpdates.add(mStatus);
1306        mStatusChanged.signal();
1307
1308        // Skip notifying listener if we're doing some user-transparent
1309        // state changes
1310        if (mPauseStateNotify) return;
1311    }
1312    NotificationListener *listener;
1313    {
1314        Mutex::Autolock l(mOutputLock);
1315        listener = mListener;
1316    }
1317    if (idle && listener != NULL) {
1318        listener->notifyIdle();
1319    }
1320}
1321
1322/**
1323 * Camera3Device private methods
1324 */
1325
1326sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
1327        const CameraMetadata &request) {
1328    ATRACE_CALL();
1329    status_t res;
1330
1331    sp<CaptureRequest> newRequest = new CaptureRequest;
1332    newRequest->mSettings = request;
1333
1334    camera_metadata_entry_t inputStreams =
1335            newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
1336    if (inputStreams.count > 0) {
1337        if (mInputStream == NULL ||
1338                mInputStream->getId() != inputStreams.data.i32[0]) {
1339            CLOGE("Request references unknown input stream %d",
1340                    inputStreams.data.u8[0]);
1341            return NULL;
1342        }
1343        // Lazy completion of stream configuration (allocation/registration)
1344        // on first use
1345        if (mInputStream->isConfiguring()) {
1346            res = mInputStream->finishConfiguration(mHal3Device);
1347            if (res != OK) {
1348                SET_ERR_L("Unable to finish configuring input stream %d:"
1349                        " %s (%d)",
1350                        mInputStream->getId(), strerror(-res), res);
1351                return NULL;
1352            }
1353        }
1354
1355        newRequest->mInputStream = mInputStream;
1356        newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
1357    }
1358
1359    camera_metadata_entry_t streams =
1360            newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
1361    if (streams.count == 0) {
1362        CLOGE("Zero output streams specified!");
1363        return NULL;
1364    }
1365
1366    for (size_t i = 0; i < streams.count; i++) {
1367        int idx = mOutputStreams.indexOfKey(streams.data.i32[i]);
1368        if (idx == NAME_NOT_FOUND) {
1369            CLOGE("Request references unknown stream %d",
1370                    streams.data.u8[i]);
1371            return NULL;
1372        }
1373        sp<Camera3OutputStreamInterface> stream =
1374                mOutputStreams.editValueAt(idx);
1375
1376        // Lazy completion of stream configuration (allocation/registration)
1377        // on first use
1378        if (stream->isConfiguring()) {
1379            res = stream->finishConfiguration(mHal3Device);
1380            if (res != OK) {
1381                SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
1382                        stream->getId(), strerror(-res), res);
1383                return NULL;
1384            }
1385        }
1386
1387        newRequest->mOutputStreams.push(stream);
1388    }
1389    newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
1390
1391    return newRequest;
1392}
1393
1394status_t Camera3Device::configureStreamsLocked() {
1395    ATRACE_CALL();
1396    status_t res;
1397
1398    if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
1399        CLOGE("Not idle");
1400        return INVALID_OPERATION;
1401    }
1402
1403    if (!mNeedConfig) {
1404        ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
1405        return OK;
1406    }
1407
1408    // Start configuring the streams
1409    ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId);
1410
1411    camera3_stream_configuration config;
1412
1413    config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
1414
1415    Vector<camera3_stream_t*> streams;
1416    streams.setCapacity(config.num_streams);
1417
1418    if (mInputStream != NULL) {
1419        camera3_stream_t *inputStream;
1420        inputStream = mInputStream->startConfiguration();
1421        if (inputStream == NULL) {
1422            SET_ERR_L("Can't start input stream configuration");
1423            return INVALID_OPERATION;
1424        }
1425        streams.add(inputStream);
1426    }
1427
1428    for (size_t i = 0; i < mOutputStreams.size(); i++) {
1429
1430        // Don't configure bidi streams twice, nor add them twice to the list
1431        if (mOutputStreams[i].get() ==
1432            static_cast<Camera3StreamInterface*>(mInputStream.get())) {
1433
1434            config.num_streams--;
1435            continue;
1436        }
1437
1438        camera3_stream_t *outputStream;
1439        outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
1440        if (outputStream == NULL) {
1441            SET_ERR_L("Can't start output stream configuration");
1442            return INVALID_OPERATION;
1443        }
1444        streams.add(outputStream);
1445    }
1446
1447    config.streams = streams.editArray();
1448
1449    // Do the HAL configuration; will potentially touch stream
1450    // max_buffers, usage, priv fields.
1451    ATRACE_BEGIN("camera3->configure_streams");
1452    res = mHal3Device->ops->configure_streams(mHal3Device, &config);
1453    ATRACE_END();
1454
1455    if (res != OK) {
1456        SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
1457                strerror(-res), res);
1458        return res;
1459    }
1460
1461    // Finish all stream configuration immediately.
1462    // TODO: Try to relax this later back to lazy completion, which should be
1463    // faster
1464
1465    if (mInputStream != NULL && mInputStream->isConfiguring()) {
1466        res = mInputStream->finishConfiguration(mHal3Device);
1467        if (res != OK) {
1468            SET_ERR_L("Can't finish configuring input stream %d: %s (%d)",
1469                    mInputStream->getId(), strerror(-res), res);
1470            return res;
1471        }
1472    }
1473
1474    for (size_t i = 0; i < mOutputStreams.size(); i++) {
1475        sp<Camera3OutputStreamInterface> outputStream =
1476            mOutputStreams.editValueAt(i);
1477        if (outputStream->isConfiguring()) {
1478            res = outputStream->finishConfiguration(mHal3Device);
1479            if (res != OK) {
1480                SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
1481                        outputStream->getId(), strerror(-res), res);
1482                return res;
1483            }
1484        }
1485    }
1486
1487    // Request thread needs to know to avoid using repeat-last-settings protocol
1488    // across configure_streams() calls
1489    mRequestThread->configurationComplete();
1490
1491    // Update device state
1492
1493    mNeedConfig = false;
1494
1495    if (config.num_streams > 0) {
1496        mStatus = STATUS_CONFIGURED;
1497    } else {
1498        mStatus = STATUS_UNCONFIGURED;
1499    }
1500
1501    ALOGV("%s: Camera %d: Stream configuration complete", __FUNCTION__, mId);
1502
1503    // tear down the deleted streams after configure streams.
1504    mDeletedStreams.clear();
1505
1506    return OK;
1507}
1508
1509void Camera3Device::setErrorState(const char *fmt, ...) {
1510    Mutex::Autolock l(mLock);
1511    va_list args;
1512    va_start(args, fmt);
1513
1514    setErrorStateLockedV(fmt, args);
1515
1516    va_end(args);
1517}
1518
1519void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
1520    Mutex::Autolock l(mLock);
1521    setErrorStateLockedV(fmt, args);
1522}
1523
1524void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
1525    va_list args;
1526    va_start(args, fmt);
1527
1528    setErrorStateLockedV(fmt, args);
1529
1530    va_end(args);
1531}
1532
1533void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
1534    // Print out all error messages to log
1535    String8 errorCause = String8::formatV(fmt, args);
1536    ALOGE("Camera %d: %s", mId, errorCause.string());
1537
1538    // But only do error state transition steps for the first error
1539    if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
1540
1541    // Save stack trace. View by dumping it later.
1542    CameraTraces::saveTrace();
1543    // TODO: consider adding errorCause and client pid/procname
1544
1545    mErrorCause = errorCause;
1546
1547    mRequestThread->setPaused(true);
1548    mStatus = STATUS_ERROR;
1549}
1550
1551/**
1552 * In-flight request management
1553 */
1554
1555status_t Camera3Device::registerInFlight(uint32_t frameNumber,
1556        int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput) {
1557    ATRACE_CALL();
1558    Mutex::Autolock l(mInFlightLock);
1559
1560    ssize_t res;
1561    res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput));
1562    if (res < 0) return res;
1563
1564    return OK;
1565}
1566
1567/**
1568 * Check if all 3A fields are ready, and send off a partial 3A-only result
1569 * to the output frame queue
1570 */
1571bool Camera3Device::processPartial3AResult(
1572        uint32_t frameNumber,
1573        const CameraMetadata& partial, const CaptureResultExtras& resultExtras) {
1574
1575    // Check if all 3A states are present
1576    // The full list of fields is
1577    //   android.control.afMode
1578    //   android.control.awbMode
1579    //   android.control.aeState
1580    //   android.control.awbState
1581    //   android.control.afState
1582    //   android.control.afTriggerID
1583    //   android.control.aePrecaptureID
1584    // TODO: Add android.control.aeMode
1585
1586    bool gotAllStates = true;
1587
1588    uint8_t afMode;
1589    uint8_t awbMode;
1590    uint8_t aeState;
1591    uint8_t afState;
1592    uint8_t awbState;
1593
1594    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE,
1595        &afMode, frameNumber);
1596
1597    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE,
1598        &awbMode, frameNumber);
1599
1600    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE,
1601        &aeState, frameNumber);
1602
1603    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE,
1604        &afState, frameNumber);
1605
1606    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE,
1607        &awbState, frameNumber);
1608
1609    if (!gotAllStates) return false;
1610
1611    ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, "
1612        "AF state %d, AE state %d, AWB state %d, "
1613        "AF trigger %d, AE precapture trigger %d",
1614        __FUNCTION__, mId, frameNumber, resultExtras.requestId,
1615        afMode, awbMode,
1616        afState, aeState, awbState,
1617        resultExtras.afTriggerId, resultExtras.precaptureTriggerId);
1618
1619    // Got all states, so construct a minimal result to send
1620    // In addition to the above fields, this means adding in
1621    //   android.request.frameCount
1622    //   android.request.requestId
1623    //   android.quirks.partialResult (for HAL version below HAL3.2)
1624
1625    const size_t kMinimal3AResultEntries = 10;
1626
1627    Mutex::Autolock l(mOutputLock);
1628
1629    CaptureResult captureResult;
1630    captureResult.mResultExtras = resultExtras;
1631    captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0);
1632    // TODO: change this to sp<CaptureResult>. This will need other changes, including,
1633    // but not limited to CameraDeviceBase::getNextResult
1634    CaptureResult& min3AResult =
1635            *mResultQueue.insert(mResultQueue.end(), captureResult);
1636
1637    if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT,
1638            // TODO: This is problematic casting. Need to fix CameraMetadata.
1639            reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) {
1640        return false;
1641    }
1642
1643    int32_t requestId = resultExtras.requestId;
1644    if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID,
1645            &requestId, frameNumber)) {
1646        return false;
1647    }
1648
1649    if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) {
1650        static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL;
1651        if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT,
1652                &partialResult, frameNumber)) {
1653            return false;
1654        }
1655    }
1656
1657    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE,
1658            &afMode, frameNumber)) {
1659        return false;
1660    }
1661
1662    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE,
1663            &awbMode, frameNumber)) {
1664        return false;
1665    }
1666
1667    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE,
1668            &aeState, frameNumber)) {
1669        return false;
1670    }
1671
1672    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE,
1673            &afState, frameNumber)) {
1674        return false;
1675    }
1676
1677    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE,
1678            &awbState, frameNumber)) {
1679        return false;
1680    }
1681
1682    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID,
1683            &resultExtras.afTriggerId, frameNumber)) {
1684        return false;
1685    }
1686
1687    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1688            &resultExtras.precaptureTriggerId, frameNumber)) {
1689        return false;
1690    }
1691
1692    // We only send the aggregated partial when all 3A related metadata are available
1693    // For both API1 and API2.
1694    // TODO: we probably should pass through all partials to API2 unconditionally.
1695    mResultSignal.signal();
1696
1697    return true;
1698}
1699
1700template<typename T>
1701bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag,
1702        T* value, uint32_t frameNumber) {
1703    (void) frameNumber;
1704
1705    camera_metadata_ro_entry_t entry;
1706
1707    entry = result.find(tag);
1708    if (entry.count == 0) {
1709        ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__,
1710            mId, frameNumber, get_camera_metadata_tag_name(tag));
1711        return false;
1712    }
1713
1714    if (sizeof(T) == sizeof(uint8_t)) {
1715        *value = entry.data.u8[0];
1716    } else if (sizeof(T) == sizeof(int32_t)) {
1717        *value = entry.data.i32[0];
1718    } else {
1719        ALOGE("%s: Unexpected type", __FUNCTION__);
1720        return false;
1721    }
1722    return true;
1723}
1724
1725template<typename T>
1726bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,
1727        const T* value, uint32_t frameNumber) {
1728    if (result.update(tag, value, 1) != NO_ERROR) {
1729        mResultQueue.erase(--mResultQueue.end(), mResultQueue.end());
1730        SET_ERR("Frame %d: Failed to set %s in partial metadata",
1731                frameNumber, get_camera_metadata_tag_name(tag));
1732        return false;
1733    }
1734    return true;
1735}
1736
1737/**
1738 * Camera HAL device callback methods
1739 */
1740
1741void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
1742    ATRACE_CALL();
1743
1744    status_t res;
1745
1746    uint32_t frameNumber = result->frame_number;
1747    if (result->result == NULL && result->num_output_buffers == 0 &&
1748            result->input_buffer == NULL) {
1749        SET_ERR("No result data provided by HAL for frame %d",
1750                frameNumber);
1751        return;
1752    }
1753
1754    // For HAL3.2 or above, If HAL doesn't support partial, it must always set
1755    // partial_result to 1 when metadata is included in this result.
1756    if (!mUsePartialResult &&
1757            mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
1758            result->result != NULL &&
1759            result->partial_result != 1) {
1760        SET_ERR("Result is malformed for frame %d: partial_result %u must be 1"
1761                " if partial result is not supported",
1762                frameNumber, result->partial_result);
1763        return;
1764    }
1765
1766    bool isPartialResult = false;
1767    CameraMetadata collectedPartialResult;
1768    CaptureResultExtras resultExtras;
1769    bool hasInputBufferInRequest = false;
1770
1771    // Get capture timestamp and resultExtras from list of in-flight requests,
1772    // where it was added by the shutter notification for this frame.
1773    // Then update the in-flight status and remove the in-flight entry if
1774    // all result data has been received.
1775    nsecs_t timestamp = 0;
1776    {
1777        Mutex::Autolock l(mInFlightLock);
1778        ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
1779        if (idx == NAME_NOT_FOUND) {
1780            SET_ERR("Unknown frame number for capture result: %d",
1781                    frameNumber);
1782            return;
1783        }
1784        InFlightRequest &request = mInFlightMap.editValueAt(idx);
1785        ALOGVV("%s: got InFlightRequest requestId = %" PRId32 ", frameNumber = %" PRId64
1786                ", burstId = %" PRId32,
1787                __FUNCTION__, request.resultExtras.requestId, request.resultExtras.frameNumber,
1788                request.resultExtras.burstId);
1789        // Always update the partial count to the latest one. When framework aggregates adjacent
1790        // partial results into one, the latest partial count will be used.
1791        request.resultExtras.partialResultCount = result->partial_result;
1792
1793        // Check if this result carries only partial metadata
1794        if (mUsePartialResult && result->result != NULL) {
1795            if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
1796                if (result->partial_result > mNumPartialResults || result->partial_result < 1) {
1797                    SET_ERR("Result is malformed for frame %d: partial_result %u must be  in"
1798                            " the range of [1, %d] when metadata is included in the result",
1799                            frameNumber, result->partial_result, mNumPartialResults);
1800                    return;
1801                }
1802                isPartialResult = (result->partial_result < mNumPartialResults);
1803                if (isPartialResult) {
1804                    request.partialResult.collectedResult.append(result->result);
1805                }
1806            } else {
1807                camera_metadata_ro_entry_t partialResultEntry;
1808                res = find_camera_metadata_ro_entry(result->result,
1809                        ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry);
1810                if (res != NAME_NOT_FOUND &&
1811                        partialResultEntry.count > 0 &&
1812                        partialResultEntry.data.u8[0] ==
1813                        ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
1814                    // A partial result. Flag this as such, and collect this
1815                    // set of metadata into the in-flight entry.
1816                    isPartialResult = true;
1817                    request.partialResult.collectedResult.append(
1818                        result->result);
1819                    request.partialResult.collectedResult.erase(
1820                        ANDROID_QUIRKS_PARTIAL_RESULT);
1821                }
1822            }
1823
1824            if (isPartialResult) {
1825                // Fire off a 3A-only result if possible
1826                if (!request.partialResult.haveSent3A) {
1827                    request.partialResult.haveSent3A =
1828                            processPartial3AResult(frameNumber,
1829                                    request.partialResult.collectedResult,
1830                                    request.resultExtras);
1831                }
1832            }
1833        }
1834
1835        timestamp = request.captureTimestamp;
1836        resultExtras = request.resultExtras;
1837        hasInputBufferInRequest = request.hasInputBuffer;
1838
1839        /**
1840         * One of the following must happen before it's legal to call process_capture_result,
1841         * unless partial metadata is being provided:
1842         * - CAMERA3_MSG_SHUTTER (expected during normal operation)
1843         * - CAMERA3_MSG_ERROR (expected during flush)
1844         */
1845        if (request.requestStatus == OK && timestamp == 0 && !isPartialResult) {
1846            SET_ERR("Called before shutter notify for frame %d",
1847                    frameNumber);
1848            return;
1849        }
1850
1851        // Did we get the (final) result metadata for this capture?
1852        if (result->result != NULL && !isPartialResult) {
1853            if (request.haveResultMetadata) {
1854                SET_ERR("Called multiple times with metadata for frame %d",
1855                        frameNumber);
1856                return;
1857            }
1858            if (mUsePartialResult &&
1859                    !request.partialResult.collectedResult.isEmpty()) {
1860                collectedPartialResult.acquire(
1861                    request.partialResult.collectedResult);
1862            }
1863            request.haveResultMetadata = true;
1864        }
1865
1866        uint32_t numBuffersReturned = result->num_output_buffers;
1867        if (result->input_buffer != NULL) {
1868            if (hasInputBufferInRequest) {
1869                numBuffersReturned += 1;
1870            } else {
1871                ALOGW("%s: Input buffer should be NULL if there is no input"
1872                        " buffer sent in the request",
1873                        __FUNCTION__);
1874            }
1875        }
1876        request.numBuffersLeft -= numBuffersReturned;
1877        if (request.numBuffersLeft < 0) {
1878            SET_ERR("Too many buffers returned for frame %d",
1879                    frameNumber);
1880            return;
1881        }
1882
1883        // Check if everything has arrived for this result (buffers and metadata), remove it from
1884        // InFlightMap if both arrived or HAL reports error for this request (i.e. during flush).
1885        if ((request.requestStatus != OK) ||
1886                (request.haveResultMetadata && request.numBuffersLeft == 0)) {
1887            ATRACE_ASYNC_END("frame capture", frameNumber);
1888            mInFlightMap.removeItemsAt(idx, 1);
1889        }
1890
1891        // Sanity check - if we have too many in-flight frames, something has
1892        // likely gone wrong
1893        if (mInFlightMap.size() > kInFlightWarnLimit) {
1894            CLOGE("In-flight list too large: %zu", mInFlightMap.size());
1895        }
1896
1897    }
1898
1899    // Process the result metadata, if provided
1900    bool gotResult = false;
1901    if (result->result != NULL && !isPartialResult) {
1902        Mutex::Autolock l(mOutputLock);
1903
1904        gotResult = true;
1905
1906        // TODO: need to track errors for tighter bounds on expected frame number
1907        if (frameNumber < mNextResultFrameNumber) {
1908            SET_ERR("Out-of-order capture result metadata submitted! "
1909                    "(got frame number %d, expecting %d)",
1910                    frameNumber, mNextResultFrameNumber);
1911            return;
1912        }
1913        mNextResultFrameNumber = frameNumber + 1;
1914
1915        CaptureResult captureResult;
1916        captureResult.mResultExtras = resultExtras;
1917        captureResult.mMetadata = result->result;
1918
1919        if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
1920                (int32_t*)&frameNumber, 1) != OK) {
1921            SET_ERR("Failed to set frame# in metadata (%d)",
1922                    frameNumber);
1923            gotResult = false;
1924        } else {
1925            ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
1926                    __FUNCTION__, mId, frameNumber);
1927        }
1928
1929        // Append any previous partials to form a complete result
1930        if (mUsePartialResult && !collectedPartialResult.isEmpty()) {
1931            captureResult.mMetadata.append(collectedPartialResult);
1932        }
1933
1934        captureResult.mMetadata.sort();
1935
1936        // Check that there's a timestamp in the result metadata
1937
1938        camera_metadata_entry entry =
1939                captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
1940        if (entry.count == 0) {
1941            SET_ERR("No timestamp provided by HAL for frame %d!",
1942                    frameNumber);
1943            gotResult = false;
1944        } else if (timestamp != entry.data.i64[0]) {
1945            SET_ERR("Timestamp mismatch between shutter notify and result"
1946                    " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)",
1947                    frameNumber, timestamp, entry.data.i64[0]);
1948            gotResult = false;
1949        }
1950
1951        if (gotResult) {
1952            // Valid result, insert into queue
1953            List<CaptureResult>::iterator queuedResult =
1954                    mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));
1955            ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64
1956                   ", burstId = %" PRId32, __FUNCTION__,
1957                   queuedResult->mResultExtras.requestId,
1958                   queuedResult->mResultExtras.frameNumber,
1959                   queuedResult->mResultExtras.burstId);
1960        }
1961    } // scope for mOutputLock
1962
1963    // Return completed buffers to their streams with the timestamp
1964
1965    for (size_t i = 0; i < result->num_output_buffers; i++) {
1966        Camera3Stream *stream =
1967                Camera3Stream::cast(result->output_buffers[i].stream);
1968        res = stream->returnBuffer(result->output_buffers[i], timestamp);
1969        // Note: stream may be deallocated at this point, if this buffer was the
1970        // last reference to it.
1971        if (res != OK) {
1972            ALOGE("Can't return buffer %zu for frame %d to its stream: "
1973                    " %s (%d)", i, frameNumber, strerror(-res), res);
1974        }
1975    }
1976
1977    if (result->input_buffer != NULL) {
1978        if (hasInputBufferInRequest) {
1979            Camera3Stream *stream =
1980                Camera3Stream::cast(result->input_buffer->stream);
1981            res = stream->returnInputBuffer(*(result->input_buffer));
1982            // Note: stream may be deallocated at this point, if this buffer was the
1983            // last reference to it.
1984            if (res != OK) {
1985                ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
1986                      "  its stream:%s (%d)",  __FUNCTION__,
1987                      frameNumber, strerror(-res), res);
1988            }
1989        } else {
1990            ALOGW("%s: Input buffer should be NULL if there is no input"
1991                    " buffer sent in the request, skipping input buffer return.",
1992                    __FUNCTION__);
1993        }
1994    }
1995
1996    // Finally, signal any waiters for new frames
1997
1998    if (gotResult) {
1999        mResultSignal.signal();
2000    }
2001
2002}
2003
2004void Camera3Device::notify(const camera3_notify_msg *msg) {
2005    ATRACE_CALL();
2006    NotificationListener *listener;
2007    {
2008        Mutex::Autolock l(mOutputLock);
2009        listener = mListener;
2010    }
2011
2012    if (msg == NULL) {
2013        SET_ERR("HAL sent NULL notify message!");
2014        return;
2015    }
2016
2017    switch (msg->type) {
2018        case CAMERA3_MSG_ERROR: {
2019            int streamId = 0;
2020            if (msg->message.error.error_stream != NULL) {
2021                Camera3Stream *stream =
2022                        Camera3Stream::cast(
2023                                  msg->message.error.error_stream);
2024                streamId = stream->getId();
2025            }
2026            ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
2027                    mId, __FUNCTION__, msg->message.error.frame_number,
2028                    streamId, msg->message.error.error_code);
2029
2030            CaptureResultExtras resultExtras;
2031            // Set request error status for the request in the in-flight tracking
2032            {
2033                Mutex::Autolock l(mInFlightLock);
2034                ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number);
2035                if (idx >= 0) {
2036                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
2037                    r.requestStatus = msg->message.error.error_code;
2038                    resultExtras = r.resultExtras;
2039                } else {
2040                    resultExtras.frameNumber = msg->message.error.frame_number;
2041                    ALOGE("Camera %d: %s: cannot find in-flight request on frame %" PRId64
2042                          " error", mId, __FUNCTION__, resultExtras.frameNumber);
2043                }
2044            }
2045
2046            if (listener != NULL) {
2047                if (msg->message.error.error_code == CAMERA3_MSG_ERROR_DEVICE) {
2048                    listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
2049                                          resultExtras);
2050                }
2051            } else {
2052                ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__);
2053            }
2054            break;
2055        }
2056        case CAMERA3_MSG_SHUTTER: {
2057            ssize_t idx;
2058            uint32_t frameNumber = msg->message.shutter.frame_number;
2059            nsecs_t timestamp = msg->message.shutter.timestamp;
2060            // Verify ordering of shutter notifications
2061            {
2062                Mutex::Autolock l(mOutputLock);
2063                // TODO: need to track errors for tighter bounds on expected frame number.
2064                if (frameNumber < mNextShutterFrameNumber) {
2065                    SET_ERR("Shutter notification out-of-order. Expected "
2066                            "notification for frame %d, got frame %d",
2067                            mNextShutterFrameNumber, frameNumber);
2068                    break;
2069                }
2070                mNextShutterFrameNumber = frameNumber + 1;
2071            }
2072
2073            CaptureResultExtras resultExtras;
2074
2075            // Set timestamp for the request in the in-flight tracking
2076            // and get the request ID to send upstream
2077            {
2078                Mutex::Autolock l(mInFlightLock);
2079                idx = mInFlightMap.indexOfKey(frameNumber);
2080                if (idx >= 0) {
2081                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
2082                    r.captureTimestamp = timestamp;
2083                    resultExtras = r.resultExtras;
2084                }
2085            }
2086            if (idx < 0) {
2087                SET_ERR("Shutter notification for non-existent frame number %d",
2088                        frameNumber);
2089                break;
2090            }
2091            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
2092                    mId, __FUNCTION__, frameNumber, resultExtras.requestId, timestamp);
2093            // Call listener, if any
2094            if (listener != NULL) {
2095                listener->notifyShutter(resultExtras, timestamp);
2096            }
2097            break;
2098        }
2099        default:
2100            SET_ERR("Unknown notify message from HAL: %d",
2101                    msg->type);
2102    }
2103}
2104
2105CameraMetadata Camera3Device::getLatestRequestLocked() {
2106    ALOGV("%s", __FUNCTION__);
2107
2108    CameraMetadata retVal;
2109
2110    if (mRequestThread != NULL) {
2111        retVal = mRequestThread->getLatestRequest();
2112    }
2113
2114    return retVal;
2115}
2116
2117
2118/**
2119 * RequestThread inner class methods
2120 */
2121
2122Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
2123        sp<StatusTracker> statusTracker,
2124        camera3_device_t *hal3Device) :
2125        Thread(false),
2126        mParent(parent),
2127        mStatusTracker(statusTracker),
2128        mHal3Device(hal3Device),
2129        mId(getId(parent)),
2130        mReconfigured(false),
2131        mDoPause(false),
2132        mPaused(true),
2133        mFrameNumber(0),
2134        mLatestRequestId(NAME_NOT_FOUND),
2135        mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) {
2136    mStatusId = statusTracker->addComponent();
2137}
2138
2139void Camera3Device::RequestThread::configurationComplete() {
2140    Mutex::Autolock l(mRequestLock);
2141    mReconfigured = true;
2142}
2143
2144status_t Camera3Device::RequestThread::queueRequestList(
2145        List<sp<CaptureRequest> > &requests,
2146        /*out*/
2147        int64_t *lastFrameNumber) {
2148    Mutex::Autolock l(mRequestLock);
2149    for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
2150            ++it) {
2151        mRequestQueue.push_back(*it);
2152    }
2153
2154    if (lastFrameNumber != NULL) {
2155        *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
2156        ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
2157              __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
2158              *lastFrameNumber);
2159    }
2160
2161    unpauseForNewRequests();
2162
2163    return OK;
2164}
2165
2166
2167status_t Camera3Device::RequestThread::queueTrigger(
2168        RequestTrigger trigger[],
2169        size_t count) {
2170
2171    Mutex::Autolock l(mTriggerMutex);
2172    status_t ret;
2173
2174    for (size_t i = 0; i < count; ++i) {
2175        ret = queueTriggerLocked(trigger[i]);
2176
2177        if (ret != OK) {
2178            return ret;
2179        }
2180    }
2181
2182    return OK;
2183}
2184
2185int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
2186    sp<Camera3Device> d = device.promote();
2187    if (d != NULL) return d->mId;
2188    return 0;
2189}
2190
2191status_t Camera3Device::RequestThread::queueTriggerLocked(
2192        RequestTrigger trigger) {
2193
2194    uint32_t tag = trigger.metadataTag;
2195    ssize_t index = mTriggerMap.indexOfKey(tag);
2196
2197    switch (trigger.getTagType()) {
2198        case TYPE_BYTE:
2199        // fall-through
2200        case TYPE_INT32:
2201            break;
2202        default:
2203            ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
2204                    trigger.getTagType());
2205            return INVALID_OPERATION;
2206    }
2207
2208    /**
2209     * Collect only the latest trigger, since we only have 1 field
2210     * in the request settings per trigger tag, and can't send more than 1
2211     * trigger per request.
2212     */
2213    if (index != NAME_NOT_FOUND) {
2214        mTriggerMap.editValueAt(index) = trigger;
2215    } else {
2216        mTriggerMap.add(tag, trigger);
2217    }
2218
2219    return OK;
2220}
2221
2222status_t Camera3Device::RequestThread::setRepeatingRequests(
2223        const RequestList &requests,
2224        /*out*/
2225        int64_t *lastFrameNumber) {
2226    Mutex::Autolock l(mRequestLock);
2227    if (lastFrameNumber != NULL) {
2228        *lastFrameNumber = mRepeatingLastFrameNumber;
2229    }
2230    mRepeatingRequests.clear();
2231    mRepeatingRequests.insert(mRepeatingRequests.begin(),
2232            requests.begin(), requests.end());
2233
2234    unpauseForNewRequests();
2235
2236    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2237    return OK;
2238}
2239
2240bool Camera3Device::RequestThread::isRepeatingRequestLocked(const sp<CaptureRequest> requestIn) {
2241    if (mRepeatingRequests.empty()) {
2242        return false;
2243    }
2244    int32_t requestId = requestIn->mResultExtras.requestId;
2245    const RequestList &repeatRequests = mRepeatingRequests;
2246    // All repeating requests are guaranteed to have same id so only check first quest
2247    const sp<CaptureRequest> firstRequest = *repeatRequests.begin();
2248    return (firstRequest->mResultExtras.requestId == requestId);
2249}
2250
2251status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
2252    Mutex::Autolock l(mRequestLock);
2253    mRepeatingRequests.clear();
2254    if (lastFrameNumber != NULL) {
2255        *lastFrameNumber = mRepeatingLastFrameNumber;
2256    }
2257    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2258    return OK;
2259}
2260
2261status_t Camera3Device::RequestThread::clear(/*out*/int64_t *lastFrameNumber) {
2262    Mutex::Autolock l(mRequestLock);
2263    ALOGV("RequestThread::%s:", __FUNCTION__);
2264    mRepeatingRequests.clear();
2265
2266    // Decrement repeating frame count for those requests never sent to device
2267    // TODO: Remove this after we have proper error handling so these requests
2268    // will generate an error callback. This might be the only place calling
2269    // isRepeatingRequestLocked. If so, isRepeatingRequestLocked should also be removed.
2270    const RequestList &requests = mRequestQueue;
2271    for (RequestList::const_iterator it = requests.begin();
2272            it != requests.end(); ++it) {
2273        if (isRepeatingRequestLocked(*it)) {
2274            mRepeatingLastFrameNumber--;
2275        }
2276    }
2277    mRequestQueue.clear();
2278    mTriggerMap.clear();
2279    if (lastFrameNumber != NULL) {
2280        *lastFrameNumber = mRepeatingLastFrameNumber;
2281    }
2282    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2283    return OK;
2284}
2285
2286void Camera3Device::RequestThread::setPaused(bool paused) {
2287    Mutex::Autolock l(mPauseLock);
2288    mDoPause = paused;
2289    mDoPauseSignal.signal();
2290}
2291
2292status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
2293        int32_t requestId, nsecs_t timeout) {
2294    Mutex::Autolock l(mLatestRequestMutex);
2295    status_t res;
2296    while (mLatestRequestId != requestId) {
2297        nsecs_t startTime = systemTime();
2298
2299        res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
2300        if (res != OK) return res;
2301
2302        timeout -= (systemTime() - startTime);
2303    }
2304
2305    return OK;
2306}
2307
2308void Camera3Device::RequestThread::requestExit() {
2309    // Call parent to set up shutdown
2310    Thread::requestExit();
2311    // The exit from any possible waits
2312    mDoPauseSignal.signal();
2313    mRequestSignal.signal();
2314}
2315
2316bool Camera3Device::RequestThread::threadLoop() {
2317
2318    status_t res;
2319
2320    // Handle paused state.
2321    if (waitIfPaused()) {
2322        return true;
2323    }
2324
2325    // Get work to do
2326
2327    sp<CaptureRequest> nextRequest = waitForNextRequest();
2328    if (nextRequest == NULL) {
2329        return true;
2330    }
2331
2332    // Create request to HAL
2333    camera3_capture_request_t request = camera3_capture_request_t();
2334    request.frame_number = nextRequest->mResultExtras.frameNumber;
2335    Vector<camera3_stream_buffer_t> outputBuffers;
2336
2337    // Get the request ID, if any
2338    int requestId;
2339    camera_metadata_entry_t requestIdEntry =
2340            nextRequest->mSettings.find(ANDROID_REQUEST_ID);
2341    if (requestIdEntry.count > 0) {
2342        requestId = requestIdEntry.data.i32[0];
2343    } else {
2344        ALOGW("%s: Did not have android.request.id set in the request",
2345                __FUNCTION__);
2346        requestId = NAME_NOT_FOUND;
2347    }
2348
2349    // Insert any queued triggers (before metadata is locked)
2350    int32_t triggerCount;
2351    res = insertTriggers(nextRequest);
2352    if (res < 0) {
2353        SET_ERR("RequestThread: Unable to insert triggers "
2354                "(capture request %d, HAL device: %s (%d)",
2355                request.frame_number, strerror(-res), res);
2356        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2357        return false;
2358    }
2359    triggerCount = res;
2360
2361    bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
2362
2363    // If the request is the same as last, or we had triggers last time
2364    if (mPrevRequest != nextRequest || triggersMixedIn) {
2365        /**
2366         * HAL workaround:
2367         * Insert a dummy trigger ID if a trigger is set but no trigger ID is
2368         */
2369        res = addDummyTriggerIds(nextRequest);
2370        if (res != OK) {
2371            SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
2372                    "(capture request %d, HAL device: %s (%d)",
2373                    request.frame_number, strerror(-res), res);
2374            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2375            return false;
2376        }
2377
2378        /**
2379         * The request should be presorted so accesses in HAL
2380         *   are O(logn). Sidenote, sorting a sorted metadata is nop.
2381         */
2382        nextRequest->mSettings.sort();
2383        request.settings = nextRequest->mSettings.getAndLock();
2384        mPrevRequest = nextRequest;
2385        ALOGVV("%s: Request settings are NEW", __FUNCTION__);
2386
2387        IF_ALOGV() {
2388            camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
2389            find_camera_metadata_ro_entry(
2390                    request.settings,
2391                    ANDROID_CONTROL_AF_TRIGGER,
2392                    &e
2393            );
2394            if (e.count > 0) {
2395                ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
2396                      __FUNCTION__,
2397                      request.frame_number,
2398                      e.data.u8[0]);
2399            }
2400        }
2401    } else {
2402        // leave request.settings NULL to indicate 'reuse latest given'
2403        ALOGVV("%s: Request settings are REUSED",
2404               __FUNCTION__);
2405    }
2406
2407    camera3_stream_buffer_t inputBuffer;
2408    uint32_t totalNumBuffers = 0;
2409
2410    // Fill in buffers
2411
2412    if (nextRequest->mInputStream != NULL) {
2413        request.input_buffer = &inputBuffer;
2414        res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
2415        if (res != OK) {
2416            ALOGE("RequestThread: Can't get input buffer, skipping request:"
2417                    " %s (%d)", strerror(-res), res);
2418            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2419            return true;
2420        }
2421        totalNumBuffers += 1;
2422    } else {
2423        request.input_buffer = NULL;
2424    }
2425
2426    outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
2427            nextRequest->mOutputStreams.size());
2428    request.output_buffers = outputBuffers.array();
2429    for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
2430        res = nextRequest->mOutputStreams.editItemAt(i)->
2431                getBuffer(&outputBuffers.editItemAt(i));
2432        if (res != OK) {
2433            ALOGE("RequestThread: Can't get output buffer, skipping request:"
2434                    " %s (%d)", strerror(-res), res);
2435            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2436            return true;
2437        }
2438        request.num_output_buffers++;
2439    }
2440    totalNumBuffers += request.num_output_buffers;
2441
2442    // Log request in the in-flight queue
2443    sp<Camera3Device> parent = mParent.promote();
2444    if (parent == NULL) {
2445        CLOGE("RequestThread: Parent is gone");
2446        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2447        return false;
2448    }
2449
2450    res = parent->registerInFlight(request.frame_number,
2451            totalNumBuffers, nextRequest->mResultExtras,
2452            /*hasInput*/request.input_buffer != NULL);
2453    ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
2454           ", burstId = %" PRId32 ".",
2455            __FUNCTION__,
2456            nextRequest->mResultExtras.requestId, nextRequest->mResultExtras.frameNumber,
2457            nextRequest->mResultExtras.burstId);
2458    if (res != OK) {
2459        SET_ERR("RequestThread: Unable to register new in-flight request:"
2460                " %s (%d)", strerror(-res), res);
2461        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2462        return false;
2463    }
2464
2465    // Inform waitUntilRequestProcessed thread of a new request ID
2466    {
2467        Mutex::Autolock al(mLatestRequestMutex);
2468
2469        mLatestRequestId = requestId;
2470        mLatestRequestSignal.signal();
2471    }
2472
2473    // Submit request and block until ready for next one
2474    ATRACE_ASYNC_BEGIN("frame capture", request.frame_number);
2475    ATRACE_BEGIN("camera3->process_capture_request");
2476    res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
2477    ATRACE_END();
2478
2479    if (res != OK) {
2480        SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
2481                " device: %s (%d)", request.frame_number, strerror(-res), res);
2482        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2483        return false;
2484    }
2485
2486    // Update the latest request sent to HAL
2487    if (request.settings != NULL) { // Don't update them if they were unchanged
2488        Mutex::Autolock al(mLatestRequestMutex);
2489
2490        camera_metadata_t* cloned = clone_camera_metadata(request.settings);
2491        mLatestRequest.acquire(cloned);
2492    }
2493
2494    if (request.settings != NULL) {
2495        nextRequest->mSettings.unlock(request.settings);
2496    }
2497
2498    // Remove any previously queued triggers (after unlock)
2499    res = removeTriggers(mPrevRequest);
2500    if (res != OK) {
2501        SET_ERR("RequestThread: Unable to remove triggers "
2502              "(capture request %d, HAL device: %s (%d)",
2503              request.frame_number, strerror(-res), res);
2504        return false;
2505    }
2506    mPrevTriggers = triggerCount;
2507
2508    return true;
2509}
2510
2511CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
2512    Mutex::Autolock al(mLatestRequestMutex);
2513
2514    ALOGV("RequestThread::%s", __FUNCTION__);
2515
2516    return mLatestRequest;
2517}
2518
2519
2520void Camera3Device::RequestThread::cleanUpFailedRequest(
2521        camera3_capture_request_t &request,
2522        sp<CaptureRequest> &nextRequest,
2523        Vector<camera3_stream_buffer_t> &outputBuffers) {
2524
2525    if (request.settings != NULL) {
2526        nextRequest->mSettings.unlock(request.settings);
2527    }
2528    if (request.input_buffer != NULL) {
2529        request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
2530        nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
2531    }
2532    for (size_t i = 0; i < request.num_output_buffers; i++) {
2533        outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
2534        nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
2535            outputBuffers[i], 0);
2536    }
2537}
2538
2539sp<Camera3Device::CaptureRequest>
2540        Camera3Device::RequestThread::waitForNextRequest() {
2541    status_t res;
2542    sp<CaptureRequest> nextRequest;
2543
2544    // Optimized a bit for the simple steady-state case (single repeating
2545    // request), to avoid putting that request in the queue temporarily.
2546    Mutex::Autolock l(mRequestLock);
2547
2548    while (mRequestQueue.empty()) {
2549        if (!mRepeatingRequests.empty()) {
2550            // Always atomically enqueue all requests in a repeating request
2551            // list. Guarantees a complete in-sequence set of captures to
2552            // application.
2553            const RequestList &requests = mRepeatingRequests;
2554            RequestList::const_iterator firstRequest =
2555                    requests.begin();
2556            nextRequest = *firstRequest;
2557            mRequestQueue.insert(mRequestQueue.end(),
2558                    ++firstRequest,
2559                    requests.end());
2560            // No need to wait any longer
2561
2562            mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
2563
2564            break;
2565        }
2566
2567        res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
2568
2569        if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
2570                exitPending()) {
2571            Mutex::Autolock pl(mPauseLock);
2572            if (mPaused == false) {
2573                ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
2574                mPaused = true;
2575                // Let the tracker know
2576                sp<StatusTracker> statusTracker = mStatusTracker.promote();
2577                if (statusTracker != 0) {
2578                    statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2579                }
2580            }
2581            // Stop waiting for now and let thread management happen
2582            return NULL;
2583        }
2584    }
2585
2586    if (nextRequest == NULL) {
2587        // Don't have a repeating request already in hand, so queue
2588        // must have an entry now.
2589        RequestList::iterator firstRequest =
2590                mRequestQueue.begin();
2591        nextRequest = *firstRequest;
2592        mRequestQueue.erase(firstRequest);
2593    }
2594
2595    // In case we've been unpaused by setPaused clearing mDoPause, need to
2596    // update internal pause state (capture/setRepeatingRequest unpause
2597    // directly).
2598    Mutex::Autolock pl(mPauseLock);
2599    if (mPaused) {
2600        ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
2601        sp<StatusTracker> statusTracker = mStatusTracker.promote();
2602        if (statusTracker != 0) {
2603            statusTracker->markComponentActive(mStatusId);
2604        }
2605    }
2606    mPaused = false;
2607
2608    // Check if we've reconfigured since last time, and reset the preview
2609    // request if so. Can't use 'NULL request == repeat' across configure calls.
2610    if (mReconfigured) {
2611        mPrevRequest.clear();
2612        mReconfigured = false;
2613    }
2614
2615    if (nextRequest != NULL) {
2616        nextRequest->mResultExtras.frameNumber = mFrameNumber++;
2617    }
2618    return nextRequest;
2619}
2620
2621bool Camera3Device::RequestThread::waitIfPaused() {
2622    status_t res;
2623    Mutex::Autolock l(mPauseLock);
2624    while (mDoPause) {
2625        if (mPaused == false) {
2626            mPaused = true;
2627            ALOGV("%s: RequestThread: Paused", __FUNCTION__);
2628            // Let the tracker know
2629            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2630            if (statusTracker != 0) {
2631                statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2632            }
2633        }
2634
2635        res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
2636        if (res == TIMED_OUT || exitPending()) {
2637            return true;
2638        }
2639    }
2640    // We don't set mPaused to false here, because waitForNextRequest needs
2641    // to further manage the paused state in case of starvation.
2642    return false;
2643}
2644
2645void Camera3Device::RequestThread::unpauseForNewRequests() {
2646    // With work to do, mark thread as unpaused.
2647    // If paused by request (setPaused), don't resume, to avoid
2648    // extra signaling/waiting overhead to waitUntilPaused
2649    mRequestSignal.signal();
2650    Mutex::Autolock p(mPauseLock);
2651    if (!mDoPause) {
2652        ALOGV("%s: RequestThread: Going active", __FUNCTION__);
2653        if (mPaused) {
2654            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2655            if (statusTracker != 0) {
2656                statusTracker->markComponentActive(mStatusId);
2657            }
2658        }
2659        mPaused = false;
2660    }
2661}
2662
2663void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
2664    sp<Camera3Device> parent = mParent.promote();
2665    if (parent != NULL) {
2666        va_list args;
2667        va_start(args, fmt);
2668
2669        parent->setErrorStateV(fmt, args);
2670
2671        va_end(args);
2672    }
2673}
2674
2675status_t Camera3Device::RequestThread::insertTriggers(
2676        const sp<CaptureRequest> &request) {
2677
2678    Mutex::Autolock al(mTriggerMutex);
2679
2680    sp<Camera3Device> parent = mParent.promote();
2681    if (parent == NULL) {
2682        CLOGE("RequestThread: Parent is gone");
2683        return DEAD_OBJECT;
2684    }
2685
2686    CameraMetadata &metadata = request->mSettings;
2687    size_t count = mTriggerMap.size();
2688
2689    for (size_t i = 0; i < count; ++i) {
2690        RequestTrigger trigger = mTriggerMap.valueAt(i);
2691        uint32_t tag = trigger.metadataTag;
2692
2693        if (tag == ANDROID_CONTROL_AF_TRIGGER_ID || tag == ANDROID_CONTROL_AE_PRECAPTURE_ID) {
2694            bool isAeTrigger = (trigger.metadataTag == ANDROID_CONTROL_AE_PRECAPTURE_ID);
2695            uint32_t triggerId = static_cast<uint32_t>(trigger.entryValue);
2696            isAeTrigger ? request->mResultExtras.precaptureTriggerId = triggerId :
2697                          request->mResultExtras.afTriggerId = triggerId;
2698            if (parent->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
2699                continue; // Trigger ID tag is deprecated since device HAL 3.2
2700            }
2701        }
2702
2703        camera_metadata_entry entry = metadata.find(tag);
2704
2705        if (entry.count > 0) {
2706            /**
2707             * Already has an entry for this trigger in the request.
2708             * Rewrite it with our requested trigger value.
2709             */
2710            RequestTrigger oldTrigger = trigger;
2711
2712            oldTrigger.entryValue = entry.data.u8[0];
2713
2714            mTriggerReplacedMap.add(tag, oldTrigger);
2715        } else {
2716            /**
2717             * More typical, no trigger entry, so we just add it
2718             */
2719            mTriggerRemovedMap.add(tag, trigger);
2720        }
2721
2722        status_t res;
2723
2724        switch (trigger.getTagType()) {
2725            case TYPE_BYTE: {
2726                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2727                res = metadata.update(tag,
2728                                      &entryValue,
2729                                      /*count*/1);
2730                break;
2731            }
2732            case TYPE_INT32:
2733                res = metadata.update(tag,
2734                                      &trigger.entryValue,
2735                                      /*count*/1);
2736                break;
2737            default:
2738                ALOGE("%s: Type not supported: 0x%x",
2739                      __FUNCTION__,
2740                      trigger.getTagType());
2741                return INVALID_OPERATION;
2742        }
2743
2744        if (res != OK) {
2745            ALOGE("%s: Failed to update request metadata with trigger tag %s"
2746                  ", value %d", __FUNCTION__, trigger.getTagName(),
2747                  trigger.entryValue);
2748            return res;
2749        }
2750
2751        ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
2752              trigger.getTagName(),
2753              trigger.entryValue);
2754    }
2755
2756    mTriggerMap.clear();
2757
2758    return count;
2759}
2760
2761status_t Camera3Device::RequestThread::removeTriggers(
2762        const sp<CaptureRequest> &request) {
2763    Mutex::Autolock al(mTriggerMutex);
2764
2765    CameraMetadata &metadata = request->mSettings;
2766
2767    /**
2768     * Replace all old entries with their old values.
2769     */
2770    for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
2771        RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
2772
2773        status_t res;
2774
2775        uint32_t tag = trigger.metadataTag;
2776        switch (trigger.getTagType()) {
2777            case TYPE_BYTE: {
2778                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2779                res = metadata.update(tag,
2780                                      &entryValue,
2781                                      /*count*/1);
2782                break;
2783            }
2784            case TYPE_INT32:
2785                res = metadata.update(tag,
2786                                      &trigger.entryValue,
2787                                      /*count*/1);
2788                break;
2789            default:
2790                ALOGE("%s: Type not supported: 0x%x",
2791                      __FUNCTION__,
2792                      trigger.getTagType());
2793                return INVALID_OPERATION;
2794        }
2795
2796        if (res != OK) {
2797            ALOGE("%s: Failed to restore request metadata with trigger tag %s"
2798                  ", trigger value %d", __FUNCTION__,
2799                  trigger.getTagName(), trigger.entryValue);
2800            return res;
2801        }
2802    }
2803    mTriggerReplacedMap.clear();
2804
2805    /**
2806     * Remove all new entries.
2807     */
2808    for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
2809        RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
2810        status_t res = metadata.erase(trigger.metadataTag);
2811
2812        if (res != OK) {
2813            ALOGE("%s: Failed to erase metadata with trigger tag %s"
2814                  ", trigger value %d", __FUNCTION__,
2815                  trigger.getTagName(), trigger.entryValue);
2816            return res;
2817        }
2818    }
2819    mTriggerRemovedMap.clear();
2820
2821    return OK;
2822}
2823
2824status_t Camera3Device::RequestThread::addDummyTriggerIds(
2825        const sp<CaptureRequest> &request) {
2826    // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
2827    static const int32_t dummyTriggerId = 1;
2828    status_t res;
2829
2830    CameraMetadata &metadata = request->mSettings;
2831
2832    // If AF trigger is active, insert a dummy AF trigger ID if none already
2833    // exists
2834    camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
2835    camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
2836    if (afTrigger.count > 0 &&
2837            afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
2838            afId.count == 0) {
2839        res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
2840        if (res != OK) return res;
2841    }
2842
2843    // If AE precapture trigger is active, insert a dummy precapture trigger ID
2844    // if none already exists
2845    camera_metadata_entry pcTrigger =
2846            metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
2847    camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
2848    if (pcTrigger.count > 0 &&
2849            pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
2850            pcId.count == 0) {
2851        res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
2852                &dummyTriggerId, 1);
2853        if (res != OK) return res;
2854    }
2855
2856    return OK;
2857}
2858
2859
2860/**
2861 * Static callback forwarding methods from HAL to instance
2862 */
2863
2864void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
2865        const camera3_capture_result *result) {
2866    Camera3Device *d =
2867            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2868    d->processCaptureResult(result);
2869}
2870
2871void Camera3Device::sNotify(const camera3_callback_ops *cb,
2872        const camera3_notify_msg *msg) {
2873    Camera3Device *d =
2874            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2875    d->notify(msg);
2876}
2877
2878}; // namespace android
2879