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