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