Camera3Device.cpp revision 2b07e0207da44d7b3cc63c369fd10c9f12a5e2cd
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    status_t res;
1003    Mutex::Autolock l(mOutputLock);
1004
1005    while (mResultQueue.empty()) {
1006        res = mResultSignal.waitRelative(mOutputLock, timeout);
1007        if (res == TIMED_OUT) {
1008            return res;
1009        } else if (res != OK) {
1010            ALOGW("%s: Camera %d: No frame in %lld ns: %s (%d)",
1011                    __FUNCTION__, mId, timeout, strerror(-res), res);
1012            return res;
1013        }
1014    }
1015    return OK;
1016}
1017
1018status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
1019    ATRACE_CALL();
1020    Mutex::Autolock l(mOutputLock);
1021
1022    if (mResultQueue.empty()) {
1023        return NOT_ENOUGH_DATA;
1024    }
1025
1026    CameraMetadata &result = *(mResultQueue.begin());
1027    frame->acquire(result);
1028    mResultQueue.erase(mResultQueue.begin());
1029
1030    return OK;
1031}
1032
1033status_t Camera3Device::triggerAutofocus(uint32_t id) {
1034    ATRACE_CALL();
1035    Mutex::Autolock il(mInterfaceLock);
1036
1037    ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
1038    // Mix-in this trigger into the next request and only the next request.
1039    RequestTrigger trigger[] = {
1040        {
1041            ANDROID_CONTROL_AF_TRIGGER,
1042            ANDROID_CONTROL_AF_TRIGGER_START
1043        },
1044        {
1045            ANDROID_CONTROL_AF_TRIGGER_ID,
1046            static_cast<int32_t>(id)
1047        },
1048    };
1049
1050    return mRequestThread->queueTrigger(trigger,
1051                                        sizeof(trigger)/sizeof(trigger[0]));
1052}
1053
1054status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
1055    ATRACE_CALL();
1056    Mutex::Autolock il(mInterfaceLock);
1057
1058    ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
1059    // Mix-in this trigger into the next request and only the next request.
1060    RequestTrigger trigger[] = {
1061        {
1062            ANDROID_CONTROL_AF_TRIGGER,
1063            ANDROID_CONTROL_AF_TRIGGER_CANCEL
1064        },
1065        {
1066            ANDROID_CONTROL_AF_TRIGGER_ID,
1067            static_cast<int32_t>(id)
1068        },
1069    };
1070
1071    return mRequestThread->queueTrigger(trigger,
1072                                        sizeof(trigger)/sizeof(trigger[0]));
1073}
1074
1075status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
1076    ATRACE_CALL();
1077    Mutex::Autolock il(mInterfaceLock);
1078
1079    ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
1080    // Mix-in this trigger into the next request and only the next request.
1081    RequestTrigger trigger[] = {
1082        {
1083            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1084            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
1085        },
1086        {
1087            ANDROID_CONTROL_AE_PRECAPTURE_ID,
1088            static_cast<int32_t>(id)
1089        },
1090    };
1091
1092    return mRequestThread->queueTrigger(trigger,
1093                                        sizeof(trigger)/sizeof(trigger[0]));
1094}
1095
1096status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
1097        buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
1098    ATRACE_CALL();
1099    (void)reprocessStreamId; (void)buffer; (void)listener;
1100
1101    CLOGE("Unimplemented");
1102    return INVALID_OPERATION;
1103}
1104
1105status_t Camera3Device::flush() {
1106    ATRACE_CALL();
1107    ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
1108    Mutex::Autolock il(mInterfaceLock);
1109    Mutex::Autolock l(mLock);
1110
1111    mRequestThread->clear();
1112    return mHal3Device->ops->flush(mHal3Device);
1113}
1114
1115/**
1116 * Methods called by subclasses
1117 */
1118
1119void Camera3Device::notifyStatus(bool idle) {
1120    {
1121        // Need mLock to safely update state and synchronize to current
1122        // state of methods in flight.
1123        Mutex::Autolock l(mLock);
1124        // We can get various system-idle notices from the status tracker
1125        // while starting up. Only care about them if we've actually sent
1126        // in some requests recently.
1127        if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
1128            return;
1129        }
1130        ALOGV("%s: Camera %d: Now %s", __FUNCTION__, mId,
1131                idle ? "idle" : "active");
1132        mStatus = idle ? STATUS_CONFIGURED : STATUS_ACTIVE;
1133        mRecentStatusUpdates.add(mStatus);
1134        mStatusChanged.signal();
1135
1136        // Skip notifying listener if we're doing some user-transparent
1137        // state changes
1138        if (mPauseStateNotify) return;
1139    }
1140    NotificationListener *listener;
1141    {
1142        Mutex::Autolock l(mOutputLock);
1143        listener = mListener;
1144    }
1145    if (idle && listener != NULL) {
1146        listener->notifyIdle();
1147    }
1148}
1149
1150/**
1151 * Camera3Device private methods
1152 */
1153
1154sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
1155        const CameraMetadata &request) {
1156    ATRACE_CALL();
1157    status_t res;
1158
1159    sp<CaptureRequest> newRequest = new CaptureRequest;
1160    newRequest->mSettings = request;
1161
1162    camera_metadata_entry_t inputStreams =
1163            newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
1164    if (inputStreams.count > 0) {
1165        if (mInputStream == NULL ||
1166                mInputStream->getId() != inputStreams.data.i32[0]) {
1167            CLOGE("Request references unknown input stream %d",
1168                    inputStreams.data.u8[0]);
1169            return NULL;
1170        }
1171        // Lazy completion of stream configuration (allocation/registration)
1172        // on first use
1173        if (mInputStream->isConfiguring()) {
1174            res = mInputStream->finishConfiguration(mHal3Device);
1175            if (res != OK) {
1176                SET_ERR_L("Unable to finish configuring input stream %d:"
1177                        " %s (%d)",
1178                        mInputStream->getId(), strerror(-res), res);
1179                return NULL;
1180            }
1181        }
1182
1183        newRequest->mInputStream = mInputStream;
1184        newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
1185    }
1186
1187    camera_metadata_entry_t streams =
1188            newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
1189    if (streams.count == 0) {
1190        CLOGE("Zero output streams specified!");
1191        return NULL;
1192    }
1193
1194    for (size_t i = 0; i < streams.count; i++) {
1195        int idx = mOutputStreams.indexOfKey(streams.data.i32[i]);
1196        if (idx == NAME_NOT_FOUND) {
1197            CLOGE("Request references unknown stream %d",
1198                    streams.data.u8[i]);
1199            return NULL;
1200        }
1201        sp<Camera3OutputStreamInterface> stream =
1202                mOutputStreams.editValueAt(idx);
1203
1204        // Lazy completion of stream configuration (allocation/registration)
1205        // on first use
1206        if (stream->isConfiguring()) {
1207            res = stream->finishConfiguration(mHal3Device);
1208            if (res != OK) {
1209                SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
1210                        stream->getId(), strerror(-res), res);
1211                return NULL;
1212            }
1213        }
1214
1215        newRequest->mOutputStreams.push(stream);
1216    }
1217    newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
1218
1219    return newRequest;
1220}
1221
1222status_t Camera3Device::configureStreamsLocked() {
1223    ATRACE_CALL();
1224    status_t res;
1225
1226    if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
1227        CLOGE("Not idle");
1228        return INVALID_OPERATION;
1229    }
1230
1231    if (!mNeedConfig) {
1232        ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
1233        return OK;
1234    }
1235
1236    // Start configuring the streams
1237    ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId);
1238
1239    camera3_stream_configuration config;
1240
1241    config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
1242
1243    Vector<camera3_stream_t*> streams;
1244    streams.setCapacity(config.num_streams);
1245
1246    if (mInputStream != NULL) {
1247        camera3_stream_t *inputStream;
1248        inputStream = mInputStream->startConfiguration();
1249        if (inputStream == NULL) {
1250            SET_ERR_L("Can't start input stream configuration");
1251            return INVALID_OPERATION;
1252        }
1253        streams.add(inputStream);
1254    }
1255
1256    for (size_t i = 0; i < mOutputStreams.size(); i++) {
1257
1258        // Don't configure bidi streams twice, nor add them twice to the list
1259        if (mOutputStreams[i].get() ==
1260            static_cast<Camera3StreamInterface*>(mInputStream.get())) {
1261
1262            config.num_streams--;
1263            continue;
1264        }
1265
1266        camera3_stream_t *outputStream;
1267        outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
1268        if (outputStream == NULL) {
1269            SET_ERR_L("Can't start output stream configuration");
1270            return INVALID_OPERATION;
1271        }
1272        streams.add(outputStream);
1273    }
1274
1275    config.streams = streams.editArray();
1276
1277    // Do the HAL configuration; will potentially touch stream
1278    // max_buffers, usage, priv fields.
1279    ATRACE_BEGIN("camera3->configure_streams");
1280    res = mHal3Device->ops->configure_streams(mHal3Device, &config);
1281    ATRACE_END();
1282
1283    if (res != OK) {
1284        SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
1285                strerror(-res), res);
1286        return res;
1287    }
1288
1289    // Finish all stream configuration immediately.
1290    // TODO: Try to relax this later back to lazy completion, which should be
1291    // faster
1292
1293    if (mInputStream != NULL && mInputStream->isConfiguring()) {
1294        res = mInputStream->finishConfiguration(mHal3Device);
1295        if (res != OK) {
1296            SET_ERR_L("Can't finish configuring input stream %d: %s (%d)",
1297                    mInputStream->getId(), strerror(-res), res);
1298            return res;
1299        }
1300    }
1301
1302    for (size_t i = 0; i < mOutputStreams.size(); i++) {
1303        sp<Camera3OutputStreamInterface> outputStream =
1304            mOutputStreams.editValueAt(i);
1305        if (outputStream->isConfiguring()) {
1306            res = outputStream->finishConfiguration(mHal3Device);
1307            if (res != OK) {
1308                SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
1309                        outputStream->getId(), strerror(-res), res);
1310                return res;
1311            }
1312        }
1313    }
1314
1315    // Request thread needs to know to avoid using repeat-last-settings protocol
1316    // across configure_streams() calls
1317    mRequestThread->configurationComplete();
1318
1319    // Update device state
1320
1321    mNeedConfig = false;
1322
1323    if (config.num_streams > 0) {
1324        mStatus = STATUS_CONFIGURED;
1325    } else {
1326        mStatus = STATUS_UNCONFIGURED;
1327    }
1328
1329    ALOGV("%s: Camera %d: Stream configuration complete", __FUNCTION__, mId);
1330
1331    return OK;
1332}
1333
1334void Camera3Device::setErrorState(const char *fmt, ...) {
1335    Mutex::Autolock l(mLock);
1336    va_list args;
1337    va_start(args, fmt);
1338
1339    setErrorStateLockedV(fmt, args);
1340
1341    va_end(args);
1342}
1343
1344void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
1345    Mutex::Autolock l(mLock);
1346    setErrorStateLockedV(fmt, args);
1347}
1348
1349void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
1350    va_list args;
1351    va_start(args, fmt);
1352
1353    setErrorStateLockedV(fmt, args);
1354
1355    va_end(args);
1356}
1357
1358void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
1359    // Print out all error messages to log
1360    String8 errorCause = String8::formatV(fmt, args);
1361    ALOGE("Camera %d: %s", mId, errorCause.string());
1362
1363    // But only do error state transition steps for the first error
1364    if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
1365
1366    mErrorCause = errorCause;
1367
1368    mRequestThread->setPaused(true);
1369    mStatus = STATUS_ERROR;
1370}
1371
1372/**
1373 * In-flight request management
1374 */
1375
1376status_t Camera3Device::registerInFlight(int32_t frameNumber,
1377        int32_t requestId, int32_t numBuffers) {
1378    ATRACE_CALL();
1379    Mutex::Autolock l(mInFlightLock);
1380
1381    ssize_t res;
1382    res = mInFlightMap.add(frameNumber, InFlightRequest(requestId, numBuffers));
1383    if (res < 0) return res;
1384
1385    return OK;
1386}
1387
1388/**
1389 * Camera HAL device callback methods
1390 */
1391
1392void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
1393    ATRACE_CALL();
1394
1395    status_t res;
1396
1397    uint32_t frameNumber = result->frame_number;
1398    if (result->result == NULL && result->num_output_buffers == 0) {
1399        SET_ERR("No result data provided by HAL for frame %d",
1400                frameNumber);
1401        return;
1402    }
1403
1404    // Get capture timestamp from list of in-flight requests, where it was added
1405    // by the shutter notification for this frame. Then update the in-flight
1406    // status and remove the in-flight entry if all result data has been
1407    // received.
1408    nsecs_t timestamp = 0;
1409    {
1410        Mutex::Autolock l(mInFlightLock);
1411        ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
1412        if (idx == NAME_NOT_FOUND) {
1413            SET_ERR("Unknown frame number for capture result: %d",
1414                    frameNumber);
1415            return;
1416        }
1417        InFlightRequest &request = mInFlightMap.editValueAt(idx);
1418        timestamp = request.captureTimestamp;
1419        /**
1420         * One of the following must happen before it's legal to call process_capture_result:
1421         * - CAMERA3_MSG_SHUTTER (expected during normal operation)
1422         * - CAMERA3_MSG_ERROR (expected during flush)
1423         */
1424        if (request.requestStatus == OK && timestamp == 0) {
1425            SET_ERR("Called before shutter notify for frame %d",
1426                    frameNumber);
1427            return;
1428        }
1429
1430        if (result->result != NULL) {
1431            if (request.haveResultMetadata) {
1432                SET_ERR("Called multiple times with metadata for frame %d",
1433                        frameNumber);
1434                return;
1435            }
1436            request.haveResultMetadata = true;
1437        }
1438
1439        request.numBuffersLeft -= result->num_output_buffers;
1440
1441        if (request.numBuffersLeft < 0) {
1442            SET_ERR("Too many buffers returned for frame %d",
1443                    frameNumber);
1444            return;
1445        }
1446
1447        if (request.haveResultMetadata && request.numBuffersLeft == 0) {
1448            ATRACE_ASYNC_END("frame capture", frameNumber);
1449            mInFlightMap.removeItemsAt(idx, 1);
1450        }
1451
1452        // Sanity check - if we have too many in-flight frames, something has
1453        // likely gone wrong
1454        if (mInFlightMap.size() > kInFlightWarnLimit) {
1455            CLOGE("In-flight list too large: %d", mInFlightMap.size());
1456        }
1457
1458    }
1459
1460    // Process the result metadata, if provided
1461    if (result->result != NULL) {
1462        Mutex::Autolock l(mOutputLock);
1463
1464        if (frameNumber != mNextResultFrameNumber) {
1465            SET_ERR("Out-of-order capture result metadata submitted! "
1466                    "(got frame number %d, expecting %d)",
1467                    frameNumber, mNextResultFrameNumber);
1468            return;
1469        }
1470        mNextResultFrameNumber++;
1471
1472        CameraMetadata &captureResult =
1473                *mResultQueue.insert(mResultQueue.end(), CameraMetadata());
1474
1475        captureResult = result->result;
1476        if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
1477                        (int32_t*)&frameNumber, 1) != OK) {
1478            SET_ERR("Failed to set frame# in metadata (%d)",
1479                    frameNumber);
1480        } else {
1481            ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
1482                    __FUNCTION__, mId, frameNumber);
1483        }
1484
1485        // Check that there's a timestamp in the result metadata
1486
1487        camera_metadata_entry entry =
1488                captureResult.find(ANDROID_SENSOR_TIMESTAMP);
1489        if (entry.count == 0) {
1490            SET_ERR("No timestamp provided by HAL for frame %d!",
1491                    frameNumber);
1492        } else if (timestamp != entry.data.i64[0]) {
1493            SET_ERR("Timestamp mismatch between shutter notify and result"
1494                    " metadata for frame %d (%lld vs %lld respectively)",
1495                    frameNumber, timestamp, entry.data.i64[0]);
1496        }
1497    } // scope for mOutputLock
1498
1499    // Return completed buffers to their streams with the timestamp
1500
1501    for (size_t i = 0; i < result->num_output_buffers; i++) {
1502        Camera3Stream *stream =
1503                Camera3Stream::cast(result->output_buffers[i].stream);
1504        res = stream->returnBuffer(result->output_buffers[i], timestamp);
1505        // Note: stream may be deallocated at this point, if this buffer was the
1506        // last reference to it.
1507        if (res != OK) {
1508            ALOGE("Can't return buffer %d for frame %d to its stream: "
1509                    " %s (%d)", i, frameNumber, strerror(-res), res);
1510        }
1511    }
1512
1513    // Finally, signal any waiters for new frames
1514
1515    if (result->result != NULL) {
1516        mResultSignal.signal();
1517    }
1518
1519}
1520
1521
1522
1523void Camera3Device::notify(const camera3_notify_msg *msg) {
1524    ATRACE_CALL();
1525    NotificationListener *listener;
1526    {
1527        Mutex::Autolock l(mOutputLock);
1528        listener = mListener;
1529    }
1530
1531    if (msg == NULL) {
1532        SET_ERR("HAL sent NULL notify message!");
1533        return;
1534    }
1535
1536    switch (msg->type) {
1537        case CAMERA3_MSG_ERROR: {
1538            int streamId = 0;
1539            if (msg->message.error.error_stream != NULL) {
1540                Camera3Stream *stream =
1541                        Camera3Stream::cast(
1542                                  msg->message.error.error_stream);
1543                streamId = stream->getId();
1544            }
1545            ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
1546                    mId, __FUNCTION__, msg->message.error.frame_number,
1547                    streamId, msg->message.error.error_code);
1548
1549            // Set request error status for the request in the in-flight tracking
1550            {
1551                Mutex::Autolock l(mInFlightLock);
1552                ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number);
1553                if (idx >= 0) {
1554                    mInFlightMap.editValueAt(idx).requestStatus = msg->message.error.error_code;
1555                }
1556            }
1557
1558            if (listener != NULL) {
1559                listener->notifyError(msg->message.error.error_code,
1560                        msg->message.error.frame_number, streamId);
1561            }
1562            break;
1563        }
1564        case CAMERA3_MSG_SHUTTER: {
1565            ssize_t idx;
1566            uint32_t frameNumber = msg->message.shutter.frame_number;
1567            nsecs_t timestamp = msg->message.shutter.timestamp;
1568            // Verify ordering of shutter notifications
1569            {
1570                Mutex::Autolock l(mOutputLock);
1571                if (frameNumber != mNextShutterFrameNumber) {
1572                    SET_ERR("Shutter notification out-of-order. Expected "
1573                            "notification for frame %d, got frame %d",
1574                            mNextShutterFrameNumber, frameNumber);
1575                    break;
1576                }
1577                mNextShutterFrameNumber++;
1578            }
1579
1580            int32_t requestId = -1;
1581
1582            // Set timestamp for the request in the in-flight tracking
1583            // and get the request ID to send upstream
1584            {
1585                Mutex::Autolock l(mInFlightLock);
1586                idx = mInFlightMap.indexOfKey(frameNumber);
1587                if (idx >= 0) {
1588                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
1589                    r.captureTimestamp = timestamp;
1590                    requestId = r.requestId;
1591                }
1592            }
1593            if (idx < 0) {
1594                SET_ERR("Shutter notification for non-existent frame number %d",
1595                        frameNumber);
1596                break;
1597            }
1598            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %lld",
1599                    mId, __FUNCTION__, frameNumber, requestId, timestamp);
1600            // Call listener, if any
1601            if (listener != NULL) {
1602                listener->notifyShutter(requestId, timestamp);
1603            }
1604            break;
1605        }
1606        default:
1607            SET_ERR("Unknown notify message from HAL: %d",
1608                    msg->type);
1609    }
1610}
1611
1612CameraMetadata Camera3Device::getLatestRequestLocked() {
1613    ALOGV("%s", __FUNCTION__);
1614
1615    CameraMetadata retVal;
1616
1617    if (mRequestThread != NULL) {
1618        retVal = mRequestThread->getLatestRequest();
1619    }
1620
1621    return retVal;
1622}
1623
1624/**
1625 * RequestThread inner class methods
1626 */
1627
1628Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
1629        sp<StatusTracker> statusTracker,
1630        camera3_device_t *hal3Device) :
1631        Thread(false),
1632        mParent(parent),
1633        mStatusTracker(statusTracker),
1634        mHal3Device(hal3Device),
1635        mId(getId(parent)),
1636        mReconfigured(false),
1637        mDoPause(false),
1638        mPaused(true),
1639        mFrameNumber(0),
1640        mLatestRequestId(NAME_NOT_FOUND) {
1641    mStatusId = statusTracker->addComponent();
1642}
1643
1644void Camera3Device::RequestThread::configurationComplete() {
1645    Mutex::Autolock l(mRequestLock);
1646    mReconfigured = true;
1647}
1648
1649status_t Camera3Device::RequestThread::queueRequest(
1650         sp<CaptureRequest> request) {
1651    Mutex::Autolock l(mRequestLock);
1652    mRequestQueue.push_back(request);
1653
1654    unpauseForNewRequests();
1655
1656    return OK;
1657}
1658
1659
1660status_t Camera3Device::RequestThread::queueTrigger(
1661        RequestTrigger trigger[],
1662        size_t count) {
1663
1664    Mutex::Autolock l(mTriggerMutex);
1665    status_t ret;
1666
1667    for (size_t i = 0; i < count; ++i) {
1668        ret = queueTriggerLocked(trigger[i]);
1669
1670        if (ret != OK) {
1671            return ret;
1672        }
1673    }
1674
1675    return OK;
1676}
1677
1678int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
1679    sp<Camera3Device> d = device.promote();
1680    if (d != NULL) return d->mId;
1681    return 0;
1682}
1683
1684status_t Camera3Device::RequestThread::queueTriggerLocked(
1685        RequestTrigger trigger) {
1686
1687    uint32_t tag = trigger.metadataTag;
1688    ssize_t index = mTriggerMap.indexOfKey(tag);
1689
1690    switch (trigger.getTagType()) {
1691        case TYPE_BYTE:
1692        // fall-through
1693        case TYPE_INT32:
1694            break;
1695        default:
1696            ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
1697                    trigger.getTagType());
1698            return INVALID_OPERATION;
1699    }
1700
1701    /**
1702     * Collect only the latest trigger, since we only have 1 field
1703     * in the request settings per trigger tag, and can't send more than 1
1704     * trigger per request.
1705     */
1706    if (index != NAME_NOT_FOUND) {
1707        mTriggerMap.editValueAt(index) = trigger;
1708    } else {
1709        mTriggerMap.add(tag, trigger);
1710    }
1711
1712    return OK;
1713}
1714
1715status_t Camera3Device::RequestThread::setRepeatingRequests(
1716        const RequestList &requests) {
1717    Mutex::Autolock l(mRequestLock);
1718    mRepeatingRequests.clear();
1719    mRepeatingRequests.insert(mRepeatingRequests.begin(),
1720            requests.begin(), requests.end());
1721
1722    unpauseForNewRequests();
1723
1724    return OK;
1725}
1726
1727status_t Camera3Device::RequestThread::clearRepeatingRequests() {
1728    Mutex::Autolock l(mRequestLock);
1729    mRepeatingRequests.clear();
1730    return OK;
1731}
1732
1733status_t Camera3Device::RequestThread::clear() {
1734    Mutex::Autolock l(mRequestLock);
1735    mRepeatingRequests.clear();
1736    mRequestQueue.clear();
1737    mTriggerMap.clear();
1738    return OK;
1739}
1740
1741void Camera3Device::RequestThread::setPaused(bool paused) {
1742    Mutex::Autolock l(mPauseLock);
1743    mDoPause = paused;
1744    mDoPauseSignal.signal();
1745}
1746
1747status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
1748        int32_t requestId, nsecs_t timeout) {
1749    Mutex::Autolock l(mLatestRequestMutex);
1750    status_t res;
1751    while (mLatestRequestId != requestId) {
1752        nsecs_t startTime = systemTime();
1753
1754        res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
1755        if (res != OK) return res;
1756
1757        timeout -= (systemTime() - startTime);
1758    }
1759
1760    return OK;
1761}
1762
1763void Camera3Device::RequestThread::requestExit() {
1764    // Call parent to set up shutdown
1765    Thread::requestExit();
1766    // The exit from any possible waits
1767    mDoPauseSignal.signal();
1768    mRequestSignal.signal();
1769}
1770
1771bool Camera3Device::RequestThread::threadLoop() {
1772
1773    status_t res;
1774
1775    // Handle paused state.
1776    if (waitIfPaused()) {
1777        return true;
1778    }
1779
1780    // Get work to do
1781
1782    sp<CaptureRequest> nextRequest = waitForNextRequest();
1783    if (nextRequest == NULL) {
1784        return true;
1785    }
1786
1787    // Create request to HAL
1788    camera3_capture_request_t request = camera3_capture_request_t();
1789    Vector<camera3_stream_buffer_t> outputBuffers;
1790
1791    // Get the request ID, if any
1792    int requestId;
1793    camera_metadata_entry_t requestIdEntry =
1794            nextRequest->mSettings.find(ANDROID_REQUEST_ID);
1795    if (requestIdEntry.count > 0) {
1796        requestId = requestIdEntry.data.i32[0];
1797    } else {
1798        ALOGW("%s: Did not have android.request.id set in the request",
1799                __FUNCTION__);
1800        requestId = NAME_NOT_FOUND;
1801    }
1802
1803    // Insert any queued triggers (before metadata is locked)
1804    int32_t triggerCount;
1805    res = insertTriggers(nextRequest);
1806    if (res < 0) {
1807        SET_ERR("RequestThread: Unable to insert triggers "
1808                "(capture request %d, HAL device: %s (%d)",
1809                (mFrameNumber+1), strerror(-res), res);
1810        cleanUpFailedRequest(request, nextRequest, outputBuffers);
1811        return false;
1812    }
1813    triggerCount = res;
1814
1815    bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
1816
1817    // If the request is the same as last, or we had triggers last time
1818    if (mPrevRequest != nextRequest || triggersMixedIn) {
1819        /**
1820         * HAL workaround:
1821         * Insert a dummy trigger ID if a trigger is set but no trigger ID is
1822         */
1823        res = addDummyTriggerIds(nextRequest);
1824        if (res != OK) {
1825            SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
1826                    "(capture request %d, HAL device: %s (%d)",
1827                    (mFrameNumber+1), strerror(-res), res);
1828            cleanUpFailedRequest(request, nextRequest, outputBuffers);
1829            return false;
1830        }
1831
1832        /**
1833         * The request should be presorted so accesses in HAL
1834         *   are O(logn). Sidenote, sorting a sorted metadata is nop.
1835         */
1836        nextRequest->mSettings.sort();
1837        request.settings = nextRequest->mSettings.getAndLock();
1838        mPrevRequest = nextRequest;
1839        ALOGVV("%s: Request settings are NEW", __FUNCTION__);
1840
1841        IF_ALOGV() {
1842            camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
1843            find_camera_metadata_ro_entry(
1844                    request.settings,
1845                    ANDROID_CONTROL_AF_TRIGGER,
1846                    &e
1847            );
1848            if (e.count > 0) {
1849                ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
1850                      __FUNCTION__,
1851                      mFrameNumber+1,
1852                      e.data.u8[0]);
1853            }
1854        }
1855    } else {
1856        // leave request.settings NULL to indicate 'reuse latest given'
1857        ALOGVV("%s: Request settings are REUSED",
1858               __FUNCTION__);
1859    }
1860
1861    camera3_stream_buffer_t inputBuffer;
1862
1863    // Fill in buffers
1864
1865    if (nextRequest->mInputStream != NULL) {
1866        request.input_buffer = &inputBuffer;
1867        res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
1868        if (res != OK) {
1869            ALOGE("RequestThread: Can't get input buffer, skipping request:"
1870                    " %s (%d)", strerror(-res), res);
1871            cleanUpFailedRequest(request, nextRequest, outputBuffers);
1872            return true;
1873        }
1874    } else {
1875        request.input_buffer = NULL;
1876    }
1877
1878    outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
1879            nextRequest->mOutputStreams.size());
1880    request.output_buffers = outputBuffers.array();
1881    for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
1882        res = nextRequest->mOutputStreams.editItemAt(i)->
1883                getBuffer(&outputBuffers.editItemAt(i));
1884        if (res != OK) {
1885            ALOGE("RequestThread: Can't get output buffer, skipping request:"
1886                    " %s (%d)", strerror(-res), res);
1887            cleanUpFailedRequest(request, nextRequest, outputBuffers);
1888            return true;
1889        }
1890        request.num_output_buffers++;
1891    }
1892
1893    request.frame_number = mFrameNumber++;
1894
1895    // Log request in the in-flight queue
1896    sp<Camera3Device> parent = mParent.promote();
1897    if (parent == NULL) {
1898        CLOGE("RequestThread: Parent is gone");
1899        cleanUpFailedRequest(request, nextRequest, outputBuffers);
1900        return false;
1901    }
1902
1903    res = parent->registerInFlight(request.frame_number, requestId,
1904            request.num_output_buffers);
1905    if (res != OK) {
1906        SET_ERR("RequestThread: Unable to register new in-flight request:"
1907                " %s (%d)", strerror(-res), res);
1908        cleanUpFailedRequest(request, nextRequest, outputBuffers);
1909        return false;
1910    }
1911
1912    // Submit request and block until ready for next one
1913    ATRACE_ASYNC_BEGIN("frame capture", request.frame_number);
1914    ATRACE_BEGIN("camera3->process_capture_request");
1915    res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
1916    ATRACE_END();
1917
1918    if (res != OK) {
1919        SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
1920                " device: %s (%d)", request.frame_number, strerror(-res), res);
1921        cleanUpFailedRequest(request, nextRequest, outputBuffers);
1922        return false;
1923    }
1924
1925    // Update the latest request sent to HAL
1926    if (request.settings != NULL) { // Don't update them if they were unchanged
1927        Mutex::Autolock al(mLatestRequestMutex);
1928
1929        camera_metadata_t* cloned = clone_camera_metadata(request.settings);
1930        mLatestRequest.acquire(cloned);
1931    }
1932
1933    if (request.settings != NULL) {
1934        nextRequest->mSettings.unlock(request.settings);
1935    }
1936
1937    // Remove any previously queued triggers (after unlock)
1938    res = removeTriggers(mPrevRequest);
1939    if (res != OK) {
1940        SET_ERR("RequestThread: Unable to remove triggers "
1941              "(capture request %d, HAL device: %s (%d)",
1942              request.frame_number, strerror(-res), res);
1943        return false;
1944    }
1945    mPrevTriggers = triggerCount;
1946
1947    // Read android.request.id from the request settings metadata
1948    // - inform waitUntilRequestProcessed thread of a new request ID
1949    {
1950        Mutex::Autolock al(mLatestRequestMutex);
1951
1952        mLatestRequestId = requestId;
1953        mLatestRequestSignal.signal();
1954    }
1955
1956    // Return input buffer back to framework
1957    if (request.input_buffer != NULL) {
1958        Camera3Stream *stream =
1959            Camera3Stream::cast(request.input_buffer->stream);
1960        res = stream->returnInputBuffer(*(request.input_buffer));
1961        // Note: stream may be deallocated at this point, if this buffer was the
1962        // last reference to it.
1963        if (res != OK) {
1964            ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
1965                    "  its stream:%s (%d)",  __FUNCTION__,
1966                    request.frame_number, strerror(-res), res);
1967            // TODO: Report error upstream
1968        }
1969    }
1970
1971    return true;
1972}
1973
1974CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
1975    Mutex::Autolock al(mLatestRequestMutex);
1976
1977    ALOGV("RequestThread::%s", __FUNCTION__);
1978
1979    return mLatestRequest;
1980}
1981
1982void Camera3Device::RequestThread::cleanUpFailedRequest(
1983        camera3_capture_request_t &request,
1984        sp<CaptureRequest> &nextRequest,
1985        Vector<camera3_stream_buffer_t> &outputBuffers) {
1986
1987    if (request.settings != NULL) {
1988        nextRequest->mSettings.unlock(request.settings);
1989    }
1990    if (request.input_buffer != NULL) {
1991        request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
1992        nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
1993    }
1994    for (size_t i = 0; i < request.num_output_buffers; i++) {
1995        outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
1996        nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
1997            outputBuffers[i], 0);
1998    }
1999}
2000
2001sp<Camera3Device::CaptureRequest>
2002        Camera3Device::RequestThread::waitForNextRequest() {
2003    status_t res;
2004    sp<CaptureRequest> nextRequest;
2005
2006    // Optimized a bit for the simple steady-state case (single repeating
2007    // request), to avoid putting that request in the queue temporarily.
2008    Mutex::Autolock l(mRequestLock);
2009
2010    while (mRequestQueue.empty()) {
2011        if (!mRepeatingRequests.empty()) {
2012            // Always atomically enqueue all requests in a repeating request
2013            // list. Guarantees a complete in-sequence set of captures to
2014            // application.
2015            const RequestList &requests = mRepeatingRequests;
2016            RequestList::const_iterator firstRequest =
2017                    requests.begin();
2018            nextRequest = *firstRequest;
2019            mRequestQueue.insert(mRequestQueue.end(),
2020                    ++firstRequest,
2021                    requests.end());
2022            // No need to wait any longer
2023            break;
2024        }
2025
2026        res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
2027
2028        if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
2029                exitPending()) {
2030            Mutex::Autolock pl(mPauseLock);
2031            if (mPaused == false) {
2032                ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
2033                mPaused = true;
2034                // Let the tracker know
2035                sp<StatusTracker> statusTracker = mStatusTracker.promote();
2036                if (statusTracker != 0) {
2037                    statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2038                }
2039            }
2040            // Stop waiting for now and let thread management happen
2041            return NULL;
2042        }
2043    }
2044
2045    if (nextRequest == NULL) {
2046        // Don't have a repeating request already in hand, so queue
2047        // must have an entry now.
2048        RequestList::iterator firstRequest =
2049                mRequestQueue.begin();
2050        nextRequest = *firstRequest;
2051        mRequestQueue.erase(firstRequest);
2052    }
2053
2054    // In case we've been unpaused by setPaused clearing mDoPause, need to
2055    // update internal pause state (capture/setRepeatingRequest unpause
2056    // directly).
2057    Mutex::Autolock pl(mPauseLock);
2058    if (mPaused) {
2059        ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
2060        sp<StatusTracker> statusTracker = mStatusTracker.promote();
2061        if (statusTracker != 0) {
2062            statusTracker->markComponentActive(mStatusId);
2063        }
2064    }
2065    mPaused = false;
2066
2067    // Check if we've reconfigured since last time, and reset the preview
2068    // request if so. Can't use 'NULL request == repeat' across configure calls.
2069    if (mReconfigured) {
2070        mPrevRequest.clear();
2071        mReconfigured = false;
2072    }
2073
2074    return nextRequest;
2075}
2076
2077bool Camera3Device::RequestThread::waitIfPaused() {
2078    status_t res;
2079    Mutex::Autolock l(mPauseLock);
2080    while (mDoPause) {
2081        if (mPaused == false) {
2082            mPaused = true;
2083            ALOGV("%s: RequestThread: Paused", __FUNCTION__);
2084            // Let the tracker know
2085            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2086            if (statusTracker != 0) {
2087                statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2088            }
2089        }
2090
2091        res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
2092        if (res == TIMED_OUT || exitPending()) {
2093            return true;
2094        }
2095    }
2096    // We don't set mPaused to false here, because waitForNextRequest needs
2097    // to further manage the paused state in case of starvation.
2098    return false;
2099}
2100
2101void Camera3Device::RequestThread::unpauseForNewRequests() {
2102    // With work to do, mark thread as unpaused.
2103    // If paused by request (setPaused), don't resume, to avoid
2104    // extra signaling/waiting overhead to waitUntilPaused
2105    mRequestSignal.signal();
2106    Mutex::Autolock p(mPauseLock);
2107    if (!mDoPause) {
2108        ALOGV("%s: RequestThread: Going active", __FUNCTION__);
2109        if (mPaused) {
2110            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2111            if (statusTracker != 0) {
2112                statusTracker->markComponentActive(mStatusId);
2113            }
2114        }
2115        mPaused = false;
2116    }
2117}
2118
2119void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
2120    sp<Camera3Device> parent = mParent.promote();
2121    if (parent != NULL) {
2122        va_list args;
2123        va_start(args, fmt);
2124
2125        parent->setErrorStateV(fmt, args);
2126
2127        va_end(args);
2128    }
2129}
2130
2131status_t Camera3Device::RequestThread::insertTriggers(
2132        const sp<CaptureRequest> &request) {
2133
2134    Mutex::Autolock al(mTriggerMutex);
2135
2136    CameraMetadata &metadata = request->mSettings;
2137    size_t count = mTriggerMap.size();
2138
2139    for (size_t i = 0; i < count; ++i) {
2140        RequestTrigger trigger = mTriggerMap.valueAt(i);
2141
2142        uint32_t tag = trigger.metadataTag;
2143        camera_metadata_entry entry = metadata.find(tag);
2144
2145        if (entry.count > 0) {
2146            /**
2147             * Already has an entry for this trigger in the request.
2148             * Rewrite it with our requested trigger value.
2149             */
2150            RequestTrigger oldTrigger = trigger;
2151
2152            oldTrigger.entryValue = entry.data.u8[0];
2153
2154            mTriggerReplacedMap.add(tag, oldTrigger);
2155        } else {
2156            /**
2157             * More typical, no trigger entry, so we just add it
2158             */
2159            mTriggerRemovedMap.add(tag, trigger);
2160        }
2161
2162        status_t res;
2163
2164        switch (trigger.getTagType()) {
2165            case TYPE_BYTE: {
2166                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2167                res = metadata.update(tag,
2168                                      &entryValue,
2169                                      /*count*/1);
2170                break;
2171            }
2172            case TYPE_INT32:
2173                res = metadata.update(tag,
2174                                      &trigger.entryValue,
2175                                      /*count*/1);
2176                break;
2177            default:
2178                ALOGE("%s: Type not supported: 0x%x",
2179                      __FUNCTION__,
2180                      trigger.getTagType());
2181                return INVALID_OPERATION;
2182        }
2183
2184        if (res != OK) {
2185            ALOGE("%s: Failed to update request metadata with trigger tag %s"
2186                  ", value %d", __FUNCTION__, trigger.getTagName(),
2187                  trigger.entryValue);
2188            return res;
2189        }
2190
2191        ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
2192              trigger.getTagName(),
2193              trigger.entryValue);
2194    }
2195
2196    mTriggerMap.clear();
2197
2198    return count;
2199}
2200
2201status_t Camera3Device::RequestThread::removeTriggers(
2202        const sp<CaptureRequest> &request) {
2203    Mutex::Autolock al(mTriggerMutex);
2204
2205    CameraMetadata &metadata = request->mSettings;
2206
2207    /**
2208     * Replace all old entries with their old values.
2209     */
2210    for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
2211        RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
2212
2213        status_t res;
2214
2215        uint32_t tag = trigger.metadataTag;
2216        switch (trigger.getTagType()) {
2217            case TYPE_BYTE: {
2218                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2219                res = metadata.update(tag,
2220                                      &entryValue,
2221                                      /*count*/1);
2222                break;
2223            }
2224            case TYPE_INT32:
2225                res = metadata.update(tag,
2226                                      &trigger.entryValue,
2227                                      /*count*/1);
2228                break;
2229            default:
2230                ALOGE("%s: Type not supported: 0x%x",
2231                      __FUNCTION__,
2232                      trigger.getTagType());
2233                return INVALID_OPERATION;
2234        }
2235
2236        if (res != OK) {
2237            ALOGE("%s: Failed to restore request metadata with trigger tag %s"
2238                  ", trigger value %d", __FUNCTION__,
2239                  trigger.getTagName(), trigger.entryValue);
2240            return res;
2241        }
2242    }
2243    mTriggerReplacedMap.clear();
2244
2245    /**
2246     * Remove all new entries.
2247     */
2248    for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
2249        RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
2250        status_t res = metadata.erase(trigger.metadataTag);
2251
2252        if (res != OK) {
2253            ALOGE("%s: Failed to erase metadata with trigger tag %s"
2254                  ", trigger value %d", __FUNCTION__,
2255                  trigger.getTagName(), trigger.entryValue);
2256            return res;
2257        }
2258    }
2259    mTriggerRemovedMap.clear();
2260
2261    return OK;
2262}
2263
2264status_t Camera3Device::RequestThread::addDummyTriggerIds(
2265        const sp<CaptureRequest> &request) {
2266    // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
2267    static const int32_t dummyTriggerId = 1;
2268    status_t res;
2269
2270    CameraMetadata &metadata = request->mSettings;
2271
2272    // If AF trigger is active, insert a dummy AF trigger ID if none already
2273    // exists
2274    camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
2275    camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
2276    if (afTrigger.count > 0 &&
2277            afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
2278            afId.count == 0) {
2279        res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
2280        if (res != OK) return res;
2281    }
2282
2283    // If AE precapture trigger is active, insert a dummy precapture trigger ID
2284    // if none already exists
2285    camera_metadata_entry pcTrigger =
2286            metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
2287    camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
2288    if (pcTrigger.count > 0 &&
2289            pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
2290            pcId.count == 0) {
2291        res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
2292                &dummyTriggerId, 1);
2293        if (res != OK) return res;
2294    }
2295
2296    return OK;
2297}
2298
2299
2300/**
2301 * Static callback forwarding methods from HAL to instance
2302 */
2303
2304void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
2305        const camera3_capture_result *result) {
2306    Camera3Device *d =
2307            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2308    d->processCaptureResult(result);
2309}
2310
2311void Camera3Device::sNotify(const camera3_callback_ops *cb,
2312        const camera3_notify_msg *msg) {
2313    Camera3Device *d =
2314            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2315    d->notify(msg);
2316}
2317
2318}; // namespace android
2319