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