Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2016 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 "CamDevSession (at) 3.2-impl"
     18 #include <android/log.h>
     19 
     20 #include <set>
     21 #include <cutils/properties.h>
     22 #include <utils/Trace.h>
     23 #include <hardware/gralloc.h>
     24 #include <hardware/gralloc1.h>
     25 #include "CameraDeviceSession.h"
     26 
     27 namespace android {
     28 namespace hardware {
     29 namespace camera {
     30 namespace device {
     31 namespace V3_2 {
     32 namespace implementation {
     33 
     34 // Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer.
     35 static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
     36 // Size of result metadata fast message queue. Change to 0 to always use hwbinder buffer.
     37 static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE  = 1 << 20 /* 1MB */;
     38 
     39 // Metadata sent by HAL will be replaced by a compact copy
     40 // if their (total size >= compact size + METADATA_SHRINK_ABS_THRESHOLD &&
     41 //           total_size >= compact size * METADATA_SHRINK_REL_THRESHOLD)
     42 // Heuristically picked by size of one page
     43 static constexpr int METADATA_SHRINK_ABS_THRESHOLD = 4096;
     44 static constexpr int METADATA_SHRINK_REL_THRESHOLD = 2;
     45 
     46 HandleImporter CameraDeviceSession::sHandleImporter;
     47 buffer_handle_t CameraDeviceSession::sEmptyBuffer = nullptr;
     48 
     49 const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
     50 
     51 CameraDeviceSession::CameraDeviceSession(
     52     camera3_device_t* device,
     53     const camera_metadata_t* deviceInfo,
     54     const sp<ICameraDeviceCallback>& callback) :
     55         camera3_callback_ops({&sProcessCaptureResult, &sNotify, nullptr, nullptr}),
     56         mDevice(device),
     57         mDeviceVersion(device->common.version),
     58         mFreeBufEarly(shouldFreeBufEarly()),
     59         mIsAELockAvailable(false),
     60         mDerivePostRawSensKey(false),
     61         mNumPartialResults(1),
     62         mResultBatcher(callback) {
     63     mDeviceInfo = deviceInfo;
     64     camera_metadata_entry partialResultsCount =
     65             mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
     66     if (partialResultsCount.count > 0) {
     67         mNumPartialResults = partialResultsCount.data.i32[0];
     68     }
     69     mResultBatcher.setNumPartialResults(mNumPartialResults);
     70 
     71     camera_metadata_entry aeLockAvailableEntry = mDeviceInfo.find(
     72             ANDROID_CONTROL_AE_LOCK_AVAILABLE);
     73     if (aeLockAvailableEntry.count > 0) {
     74         mIsAELockAvailable = (aeLockAvailableEntry.data.u8[0] ==
     75                 ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE);
     76     }
     77 
     78     // Determine whether we need to derive sensitivity boost values for older devices.
     79     // If post-RAW sensitivity boost range is listed, so should post-raw sensitivity control
     80     // be listed (as the default value 100)
     81     if (mDeviceInfo.exists(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE)) {
     82         mDerivePostRawSensKey = true;
     83     }
     84 
     85     mInitFail = initialize();
     86 }
     87 
     88 bool CameraDeviceSession::initialize() {
     89     /** Initialize device with callback functions */
     90     ATRACE_BEGIN("camera3->initialize");
     91     status_t res = mDevice->ops->initialize(mDevice, this);
     92     ATRACE_END();
     93 
     94     if (res != OK) {
     95         ALOGE("%s: Unable to initialize HAL device: %s (%d)",
     96                 __FUNCTION__, strerror(-res), res);
     97         mDevice->common.close(&mDevice->common);
     98         mClosed = true;
     99         return true;
    100     }
    101 
    102     // "ro.camera" properties are no longer supported on vendor side.
    103     //  Support a fall back for the fmq size override that uses "ro.vendor.camera"
    104     //  properties.
    105     int32_t reqFMQSize = property_get_int32("ro.vendor.camera.req.fmq.size", /*default*/-1);
    106     if (reqFMQSize < 0) {
    107         reqFMQSize = property_get_int32("ro.camera.req.fmq.size", /*default*/-1);
    108         if (reqFMQSize < 0) {
    109             reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
    110         } else {
    111             ALOGV("%s: request FMQ size overridden to %d", __FUNCTION__, reqFMQSize);
    112         }
    113     } else {
    114         ALOGV("%s: request FMQ size overridden to %d via fallback property", __FUNCTION__,
    115                 reqFMQSize);
    116     }
    117 
    118     mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>(
    119             static_cast<size_t>(reqFMQSize),
    120             false /* non blocking */);
    121     if (!mRequestMetadataQueue->isValid()) {
    122         ALOGE("%s: invalid request fmq", __FUNCTION__);
    123         return true;
    124     }
    125 
    126     // "ro.camera" properties are no longer supported on vendor side.
    127     //  Support a fall back for the fmq size override that uses "ro.vendor.camera"
    128     //  properties.
    129     int32_t resFMQSize = property_get_int32("ro.vendor.camera.res.fmq.size", /*default*/-1);
    130     if (resFMQSize < 0) {
    131         resFMQSize = property_get_int32("ro.camera.res.fmq.size", /*default*/-1);
    132         if (resFMQSize < 0) {
    133             resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
    134         } else {
    135             ALOGV("%s: result FMQ size overridden to %d", __FUNCTION__, resFMQSize);
    136         }
    137     } else {
    138         ALOGV("%s: result FMQ size overridden to %d via fallback property", __FUNCTION__,
    139                 resFMQSize);
    140     }
    141 
    142     mResultMetadataQueue = std::make_shared<RequestMetadataQueue>(
    143             static_cast<size_t>(resFMQSize),
    144             false /* non blocking */);
    145     if (!mResultMetadataQueue->isValid()) {
    146         ALOGE("%s: invalid result fmq", __FUNCTION__);
    147         return true;
    148     }
    149     mResultBatcher.setResultMetadataQueue(mResultMetadataQueue);
    150 
    151     return false;
    152 }
    153 
    154 bool CameraDeviceSession::shouldFreeBufEarly() {
    155     return property_get_bool("ro.vendor.camera.free_buf_early", 0) == 1;
    156 }
    157 
    158 CameraDeviceSession::~CameraDeviceSession() {
    159     if (!isClosed()) {
    160         ALOGE("CameraDeviceSession deleted before close!");
    161         close();
    162     }
    163 }
    164 
    165 bool CameraDeviceSession::isClosed() {
    166     Mutex::Autolock _l(mStateLock);
    167     return mClosed;
    168 }
    169 
    170 Status CameraDeviceSession::initStatus() const {
    171     Mutex::Autolock _l(mStateLock);
    172     Status status = Status::OK;
    173     if (mInitFail) {
    174         status = Status::INTERNAL_ERROR;
    175     } else if (mDisconnected) {
    176         status = Status::CAMERA_DISCONNECTED;
    177     } else if (mClosed) {
    178         status = Status::INTERNAL_ERROR;
    179     }
    180     return status;
    181 }
    182 
    183 void CameraDeviceSession::disconnect() {
    184     Mutex::Autolock _l(mStateLock);
    185     mDisconnected = true;
    186     ALOGW("%s: Camera device is disconnected. Closing.", __FUNCTION__);
    187     if (!mClosed) {
    188         mDevice->common.close(&mDevice->common);
    189         mClosed = true;
    190     }
    191 }
    192 
    193 void CameraDeviceSession::dumpState(const native_handle_t* fd) {
    194     if (!isClosed()) {
    195         mDevice->ops->dump(mDevice, fd->data[0]);
    196     }
    197 }
    198 
    199 /**
    200  * For devices <= CAMERA_DEVICE_API_VERSION_3_2, AE_PRECAPTURE_TRIGGER_CANCEL is not supported so
    201  * we need to override AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE and AE_LOCK_OFF
    202  * to AE_LOCK_ON to start cancelling AE precapture. If AE lock is not available, it still overrides
    203  * AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE but doesn't add AE_LOCK_ON to the
    204  * request.
    205  */
    206 bool CameraDeviceSession::handleAePrecaptureCancelRequestLocked(
    207         const camera3_capture_request_t &halRequest,
    208         ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/,
    209          AETriggerCancelOverride *override /*out*/) {
    210     if ((mDeviceVersion > CAMERA_DEVICE_API_VERSION_3_2) ||
    211             (nullptr == halRequest.settings) || (nullptr == settings) ||
    212             (0 == get_camera_metadata_entry_count(halRequest.settings))) {
    213         return false;
    214     }
    215 
    216     settings->clear();
    217     settings->append(halRequest.settings);
    218     camera_metadata_entry_t aePrecaptureTrigger =
    219             settings->find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
    220     if (aePrecaptureTrigger.count > 0 &&
    221             aePrecaptureTrigger.data.u8[0] ==
    222                     ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL) {
    223         // Always override CANCEL to IDLE
    224         uint8_t aePrecaptureTrigger =
    225                 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
    226         settings->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
    227                 &aePrecaptureTrigger, 1);
    228         *override = { false, ANDROID_CONTROL_AE_LOCK_OFF,
    229                 true, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL };
    230 
    231         if (mIsAELockAvailable == true) {
    232             camera_metadata_entry_t aeLock = settings->find(
    233                     ANDROID_CONTROL_AE_LOCK);
    234             if (aeLock.count == 0 || aeLock.data.u8[0] ==
    235                     ANDROID_CONTROL_AE_LOCK_OFF) {
    236                 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_ON;
    237                 settings->update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
    238                 override->applyAeLock = true;
    239                 override->aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
    240             }
    241         }
    242 
    243         return true;
    244     }
    245 
    246     return false;
    247 }
    248 
    249 /**
    250  * Override result metadata for cancelling AE precapture trigger applied in
    251  * handleAePrecaptureCancelRequestLocked().
    252  */
    253 void CameraDeviceSession::overrideResultForPrecaptureCancelLocked(
    254         const AETriggerCancelOverride &aeTriggerCancelOverride,
    255         ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/) {
    256     if (aeTriggerCancelOverride.applyAeLock) {
    257         // Only devices <= v3.2 should have this override
    258         assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
    259         settings->update(ANDROID_CONTROL_AE_LOCK, &aeTriggerCancelOverride.aeLock, 1);
    260     }
    261 
    262     if (aeTriggerCancelOverride.applyAePrecaptureTrigger) {
    263         // Only devices <= v3.2 should have this override
    264         assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
    265         settings->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
    266                 &aeTriggerCancelOverride.aePrecaptureTrigger, 1);
    267     }
    268 }
    269 
    270 Status CameraDeviceSession::importBuffer(int32_t streamId,
    271         uint64_t bufId, buffer_handle_t buf,
    272         /*out*/buffer_handle_t** outBufPtr,
    273         bool allowEmptyBuf) {
    274 
    275     if (buf == nullptr && bufId == BUFFER_ID_NO_BUFFER) {
    276         if (allowEmptyBuf) {
    277             *outBufPtr = &sEmptyBuffer;
    278             return Status::OK;
    279         } else {
    280             ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
    281             return Status::ILLEGAL_ARGUMENT;
    282         }
    283     }
    284 
    285     Mutex::Autolock _l(mInflightLock);
    286     CirculatingBuffers& cbs = mCirculatingBuffers[streamId];
    287     if (cbs.count(bufId) == 0) {
    288         // Register a newly seen buffer
    289         buffer_handle_t importedBuf = buf;
    290         sHandleImporter.importBuffer(importedBuf);
    291         if (importedBuf == nullptr) {
    292             ALOGE("%s: output buffer for stream %d is invalid!", __FUNCTION__, streamId);
    293             return Status::INTERNAL_ERROR;
    294         } else {
    295             cbs[bufId] = importedBuf;
    296         }
    297     }
    298     *outBufPtr = &cbs[bufId];
    299     return Status::OK;
    300 }
    301 
    302 Status CameraDeviceSession::importRequest(
    303         const CaptureRequest& request,
    304         hidl_vec<buffer_handle_t*>& allBufPtrs,
    305         hidl_vec<int>& allFences) {
    306     return importRequestImpl(request, allBufPtrs, allFences);
    307 }
    308 
    309 Status CameraDeviceSession::importRequestImpl(
    310         const CaptureRequest& request,
    311         hidl_vec<buffer_handle_t*>& allBufPtrs,
    312         hidl_vec<int>& allFences,
    313         bool allowEmptyBuf) {
    314     bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
    315             request.inputBuffer.bufferId != 0);
    316     size_t numOutputBufs = request.outputBuffers.size();
    317     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
    318     // Validate all I/O buffers
    319     hidl_vec<buffer_handle_t> allBufs;
    320     hidl_vec<uint64_t> allBufIds;
    321     allBufs.resize(numBufs);
    322     allBufIds.resize(numBufs);
    323     allBufPtrs.resize(numBufs);
    324     allFences.resize(numBufs);
    325     std::vector<int32_t> streamIds(numBufs);
    326 
    327     for (size_t i = 0; i < numOutputBufs; i++) {
    328         allBufs[i] = request.outputBuffers[i].buffer.getNativeHandle();
    329         allBufIds[i] = request.outputBuffers[i].bufferId;
    330         allBufPtrs[i] = &allBufs[i];
    331         streamIds[i] = request.outputBuffers[i].streamId;
    332     }
    333     if (hasInputBuf) {
    334         allBufs[numOutputBufs] = request.inputBuffer.buffer.getNativeHandle();
    335         allBufIds[numOutputBufs] = request.inputBuffer.bufferId;
    336         allBufPtrs[numOutputBufs] = &allBufs[numOutputBufs];
    337         streamIds[numOutputBufs] = request.inputBuffer.streamId;
    338     }
    339 
    340     for (size_t i = 0; i < numBufs; i++) {
    341         Status st = importBuffer(
    342                 streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i],
    343                 // Disallow empty buf for input stream, otherwise follow
    344                 // the allowEmptyBuf argument.
    345                 (hasInputBuf && i == numOutputBufs) ? false : allowEmptyBuf);
    346         if (st != Status::OK) {
    347             // Detailed error logs printed in importBuffer
    348             return st;
    349         }
    350     }
    351 
    352     // All buffers are imported. Now validate output buffer acquire fences
    353     for (size_t i = 0; i < numOutputBufs; i++) {
    354         if (!sHandleImporter.importFence(
    355                 request.outputBuffers[i].acquireFence, allFences[i])) {
    356             ALOGE("%s: output buffer %zu acquire fence is invalid", __FUNCTION__, i);
    357             cleanupInflightFences(allFences, i);
    358             return Status::INTERNAL_ERROR;
    359         }
    360     }
    361 
    362     // Validate input buffer acquire fences
    363     if (hasInputBuf) {
    364         if (!sHandleImporter.importFence(
    365                 request.inputBuffer.acquireFence, allFences[numOutputBufs])) {
    366             ALOGE("%s: input buffer acquire fence is invalid", __FUNCTION__);
    367             cleanupInflightFences(allFences, numOutputBufs);
    368             return Status::INTERNAL_ERROR;
    369         }
    370     }
    371     return Status::OK;
    372 }
    373 
    374 void CameraDeviceSession::cleanupInflightFences(
    375         hidl_vec<int>& allFences, size_t numFences) {
    376     for (size_t j = 0; j < numFences; j++) {
    377         sHandleImporter.closeFence(allFences[j]);
    378     }
    379 }
    380 
    381 CameraDeviceSession::ResultBatcher::ResultBatcher(
    382         const sp<ICameraDeviceCallback>& callback) : mCallback(callback) {};
    383 
    384 bool CameraDeviceSession::ResultBatcher::InflightBatch::allDelivered() const {
    385     if (!mShutterDelivered) return false;
    386 
    387     if (mPartialResultProgress < mNumPartialResults) {
    388         return false;
    389     }
    390 
    391     for (const auto& pair : mBatchBufs) {
    392         if (!pair.second.mDelivered) {
    393             return false;
    394         }
    395     }
    396     return true;
    397 }
    398 
    399 void CameraDeviceSession::ResultBatcher::setNumPartialResults(uint32_t n) {
    400     Mutex::Autolock _l(mLock);
    401     mNumPartialResults = n;
    402 }
    403 
    404 void CameraDeviceSession::ResultBatcher::setBatchedStreams(
    405         const std::vector<int>& streamsToBatch) {
    406     Mutex::Autolock _l(mLock);
    407     mStreamsToBatch = streamsToBatch;
    408 }
    409 
    410 void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(
    411         std::shared_ptr<ResultMetadataQueue> q) {
    412     Mutex::Autolock _l(mLock);
    413     mResultMetadataQueue = q;
    414 }
    415 
    416 void CameraDeviceSession::ResultBatcher::registerBatch(uint32_t frameNumber, uint32_t batchSize) {
    417     auto batch = std::make_shared<InflightBatch>();
    418     batch->mFirstFrame = frameNumber;
    419     batch->mBatchSize = batchSize;
    420     batch->mLastFrame = batch->mFirstFrame + batch->mBatchSize - 1;
    421     batch->mNumPartialResults = mNumPartialResults;
    422     for (int id : mStreamsToBatch) {
    423         batch->mBatchBufs.emplace(id, batch->mBatchSize);
    424     }
    425     Mutex::Autolock _l(mLock);
    426     mInflightBatches.push_back(batch);
    427 }
    428 
    429 std::pair<int, std::shared_ptr<CameraDeviceSession::ResultBatcher::InflightBatch>>
    430 CameraDeviceSession::ResultBatcher::getBatch(
    431         uint32_t frameNumber) {
    432     Mutex::Autolock _l(mLock);
    433     int numBatches = mInflightBatches.size();
    434     if (numBatches == 0) {
    435         return std::make_pair(NOT_BATCHED, nullptr);
    436     }
    437     uint32_t frameMin = mInflightBatches[0]->mFirstFrame;
    438     uint32_t frameMax = mInflightBatches[numBatches - 1]->mLastFrame;
    439     if (frameNumber < frameMin || frameNumber > frameMax) {
    440         return std::make_pair(NOT_BATCHED, nullptr);
    441     }
    442     for (int i = 0; i < numBatches; i++) {
    443         if (frameNumber >= mInflightBatches[i]->mFirstFrame &&
    444                 frameNumber <= mInflightBatches[i]->mLastFrame) {
    445             return std::make_pair(i, mInflightBatches[i]);
    446         }
    447     }
    448     return std::make_pair(NOT_BATCHED, nullptr);
    449 }
    450 
    451 void CameraDeviceSession::ResultBatcher::checkAndRemoveFirstBatch() {
    452     Mutex::Autolock _l(mLock);
    453     if (mInflightBatches.size() > 0) {
    454         std::shared_ptr<InflightBatch> batch = mInflightBatches[0];
    455         bool shouldRemove = false;
    456         {
    457             Mutex::Autolock _l(batch->mLock);
    458             if (batch->allDelivered()) {
    459                 batch->mRemoved = true;
    460                 shouldRemove = true;
    461             }
    462         }
    463         if (shouldRemove) {
    464             mInflightBatches.pop_front();
    465         }
    466     }
    467 }
    468 
    469 void CameraDeviceSession::ResultBatcher::sendBatchShutterCbsLocked(
    470         std::shared_ptr<InflightBatch> batch) {
    471     if (batch->mShutterDelivered) {
    472         ALOGW("%s: batch shutter callback already sent!", __FUNCTION__);
    473         return;
    474     }
    475 
    476     auto ret = mCallback->notify(batch->mShutterMsgs);
    477     if (!ret.isOk()) {
    478         ALOGE("%s: notify shutter transaction failed: %s",
    479                 __FUNCTION__, ret.description().c_str());
    480     }
    481     batch->mShutterDelivered = true;
    482     batch->mShutterMsgs.clear();
    483 }
    484 
    485 void CameraDeviceSession::ResultBatcher::freeReleaseFences(hidl_vec<CaptureResult>& results) {
    486     for (auto& result : results) {
    487         if (result.inputBuffer.releaseFence.getNativeHandle() != nullptr) {
    488             native_handle_t* handle = const_cast<native_handle_t*>(
    489                     result.inputBuffer.releaseFence.getNativeHandle());
    490             native_handle_close(handle);
    491             native_handle_delete(handle);
    492         }
    493         for (auto& buf : result.outputBuffers) {
    494             if (buf.releaseFence.getNativeHandle() != nullptr) {
    495                 native_handle_t* handle = const_cast<native_handle_t*>(
    496                         buf.releaseFence.getNativeHandle());
    497                 native_handle_close(handle);
    498                 native_handle_delete(handle);
    499             }
    500         }
    501     }
    502     return;
    503 }
    504 
    505 void CameraDeviceSession::ResultBatcher::moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst) {
    506     // Only dealing with releaseFence here. Assume buffer/acquireFence are null
    507     const native_handle_t* handle = src.releaseFence.getNativeHandle();
    508     src.releaseFence = nullptr;
    509     dst = src;
    510     dst.releaseFence = handle;
    511     if (handle != dst.releaseFence.getNativeHandle()) {
    512         ALOGE("%s: native handle cloned!", __FUNCTION__);
    513     }
    514 }
    515 
    516 void CameraDeviceSession::ResultBatcher::pushStreamBuffer(
    517         StreamBuffer&& src, std::vector<StreamBuffer>& dst) {
    518     // Only dealing with releaseFence here. Assume buffer/acquireFence are null
    519     const native_handle_t* handle = src.releaseFence.getNativeHandle();
    520     src.releaseFence = nullptr;
    521     dst.push_back(src);
    522     dst.back().releaseFence = handle;
    523     if (handle != dst.back().releaseFence.getNativeHandle()) {
    524         ALOGE("%s: native handle cloned!", __FUNCTION__);
    525     }
    526 }
    527 
    528 void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
    529         std::shared_ptr<InflightBatch> batch) {
    530     sendBatchBuffersLocked(batch, mStreamsToBatch);
    531 }
    532 
    533 void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
    534         std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams) {
    535     size_t batchSize = 0;
    536     for (int streamId : streams) {
    537         auto it = batch->mBatchBufs.find(streamId);
    538         if (it != batch->mBatchBufs.end()) {
    539             InflightBatch::BufferBatch& bb = it->second;
    540             if (bb.mDelivered) {
    541                 continue;
    542             }
    543             if (bb.mBuffers.size() > batchSize) {
    544                 batchSize = bb.mBuffers.size();
    545             }
    546         } else {
    547             ALOGE("%s: stream ID %d is not batched!", __FUNCTION__, streamId);
    548             return;
    549         }
    550     }
    551 
    552     if (batchSize == 0) {
    553         ALOGW("%s: there is no buffer to be delivered for this batch.", __FUNCTION__);
    554         for (int streamId : streams) {
    555             auto it = batch->mBatchBufs.find(streamId);
    556             if (it == batch->mBatchBufs.end()) {
    557                 ALOGE("%s: cannot find stream %d in batched buffers!", __FUNCTION__, streamId);
    558                 return;
    559             }
    560             InflightBatch::BufferBatch& bb = it->second;
    561             bb.mDelivered = true;
    562         }
    563         return;
    564     }
    565 
    566     hidl_vec<CaptureResult> results;
    567     results.resize(batchSize);
    568     for (size_t i = 0; i < batchSize; i++) {
    569         results[i].frameNumber = batch->mFirstFrame + i;
    570         results[i].fmqResultSize = 0;
    571         results[i].partialResult = 0; // 0 for buffer only results
    572         results[i].inputBuffer.streamId = -1;
    573         results[i].inputBuffer.bufferId = 0;
    574         results[i].inputBuffer.buffer = nullptr;
    575         std::vector<StreamBuffer> outBufs;
    576         outBufs.reserve(streams.size());
    577         for (int streamId : streams) {
    578             auto it = batch->mBatchBufs.find(streamId);
    579             if (it == batch->mBatchBufs.end()) {
    580                 ALOGE("%s: cannot find stream %d in batched buffers!", __FUNCTION__, streamId);
    581                 return;
    582             }
    583             InflightBatch::BufferBatch& bb = it->second;
    584             if (bb.mDelivered) {
    585                 continue;
    586             }
    587             if (i < bb.mBuffers.size()) {
    588                 pushStreamBuffer(std::move(bb.mBuffers[i]), outBufs);
    589             }
    590         }
    591         results[i].outputBuffers.resize(outBufs.size());
    592         for (size_t j = 0; j < outBufs.size(); j++) {
    593             moveStreamBuffer(std::move(outBufs[j]), results[i].outputBuffers[j]);
    594         }
    595     }
    596     invokeProcessCaptureResultCallback(results, /* tryWriteFmq */false);
    597     freeReleaseFences(results);
    598     for (int streamId : streams) {
    599         auto it = batch->mBatchBufs.find(streamId);
    600         if (it == batch->mBatchBufs.end()) {
    601             ALOGE("%s: cannot find stream %d in batched buffers!", __FUNCTION__, streamId);
    602             return;
    603         }
    604         InflightBatch::BufferBatch& bb = it->second;
    605         bb.mDelivered = true;
    606         bb.mBuffers.clear();
    607     }
    608 }
    609 
    610 void CameraDeviceSession::ResultBatcher::sendBatchMetadataLocked(
    611     std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx) {
    612     if (lastPartialResultIdx <= batch->mPartialResultProgress) {
    613         // Result has been delivered. Return
    614         ALOGW("%s: partial result %u has been delivered", __FUNCTION__, lastPartialResultIdx);
    615         return;
    616     }
    617 
    618     std::vector<CaptureResult> results;
    619     std::vector<uint32_t> toBeRemovedIdxes;
    620     for (auto& pair : batch->mResultMds) {
    621         uint32_t partialIdx = pair.first;
    622         if (partialIdx > lastPartialResultIdx) {
    623             continue;
    624         }
    625         toBeRemovedIdxes.push_back(partialIdx);
    626         InflightBatch::MetadataBatch& mb = pair.second;
    627         for (const auto& p : mb.mMds) {
    628             CaptureResult result;
    629             result.frameNumber = p.first;
    630             result.result = std::move(p.second);
    631             result.fmqResultSize = 0;
    632             result.inputBuffer.streamId = -1;
    633             result.inputBuffer.bufferId = 0;
    634             result.inputBuffer.buffer = nullptr;
    635             result.partialResult = partialIdx;
    636             results.push_back(std::move(result));
    637         }
    638         mb.mMds.clear();
    639     }
    640     hidl_vec<CaptureResult> hResults;
    641     hResults.setToExternal(results.data(), results.size());
    642     invokeProcessCaptureResultCallback(hResults, /* tryWriteFmq */true);
    643     batch->mPartialResultProgress = lastPartialResultIdx;
    644     for (uint32_t partialIdx : toBeRemovedIdxes) {
    645         batch->mResultMds.erase(partialIdx);
    646     }
    647 }
    648 
    649 void CameraDeviceSession::ResultBatcher::notifySingleMsg(NotifyMsg& msg) {
    650     auto ret = mCallback->notify({msg});
    651     if (!ret.isOk()) {
    652         ALOGE("%s: notify transaction failed: %s",
    653                 __FUNCTION__, ret.description().c_str());
    654     }
    655     return;
    656 }
    657 
    658 void CameraDeviceSession::ResultBatcher::notify(NotifyMsg& msg) {
    659     uint32_t frameNumber;
    660     if (CC_LIKELY(msg.type == MsgType::SHUTTER)) {
    661         frameNumber = msg.msg.shutter.frameNumber;
    662     } else {
    663         frameNumber = msg.msg.error.frameNumber;
    664     }
    665 
    666     auto pair = getBatch(frameNumber);
    667     int batchIdx = pair.first;
    668     if (batchIdx == NOT_BATCHED) {
    669         notifySingleMsg(msg);
    670         return;
    671     }
    672 
    673     // When error happened, stop batching for all batches earlier
    674     if (CC_UNLIKELY(msg.type == MsgType::ERROR)) {
    675         Mutex::Autolock _l(mLock);
    676         for (int i = 0; i <= batchIdx; i++) {
    677             // Send batched data up
    678             std::shared_ptr<InflightBatch> batch = mInflightBatches[0];
    679             {
    680                 Mutex::Autolock _l(batch->mLock);
    681                 sendBatchShutterCbsLocked(batch);
    682                 sendBatchBuffersLocked(batch);
    683                 sendBatchMetadataLocked(batch, mNumPartialResults);
    684                 if (!batch->allDelivered()) {
    685                     ALOGE("%s: error: some batch data not sent back to framework!",
    686                             __FUNCTION__);
    687                 }
    688                 batch->mRemoved = true;
    689             }
    690             mInflightBatches.pop_front();
    691         }
    692         // Send the error up
    693         notifySingleMsg(msg);
    694         return;
    695     }
    696     // Queue shutter callbacks for future delivery
    697     std::shared_ptr<InflightBatch> batch = pair.second;
    698     {
    699         Mutex::Autolock _l(batch->mLock);
    700         // Check if the batch is removed (mostly by notify error) before lock was acquired
    701         if (batch->mRemoved) {
    702             // Fall back to non-batch path
    703             notifySingleMsg(msg);
    704             return;
    705         }
    706 
    707         batch->mShutterMsgs.push_back(msg);
    708         if (frameNumber == batch->mLastFrame) {
    709             sendBatchShutterCbsLocked(batch);
    710         }
    711     } // end of batch lock scope
    712 
    713     // see if the batch is complete
    714     if (frameNumber == batch->mLastFrame) {
    715         checkAndRemoveFirstBatch();
    716     }
    717 }
    718 
    719 void CameraDeviceSession::ResultBatcher::invokeProcessCaptureResultCallback(
    720         hidl_vec<CaptureResult> &results, bool tryWriteFmq) {
    721     if (mProcessCaptureResultLock.tryLock() != OK) {
    722         ALOGV("%s: previous call is not finished! waiting 1s...", __FUNCTION__);
    723         if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
    724             ALOGE("%s: cannot acquire lock in 1s, cannot proceed",
    725                     __FUNCTION__);
    726             return;
    727         }
    728     }
    729     if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
    730         for (CaptureResult &result : results) {
    731             if (result.result.size() > 0) {
    732                 if (mResultMetadataQueue->write(result.result.data(), result.result.size())) {
    733                     result.fmqResultSize = result.result.size();
    734                     result.result.resize(0);
    735                 } else {
    736                     ALOGW("%s: couldn't utilize fmq, fall back to hwbinder, result size: %zu,"
    737                     "shared message queue available size: %zu",
    738                         __FUNCTION__, result.result.size(),
    739                         mResultMetadataQueue->availableToWrite());
    740                     result.fmqResultSize = 0;
    741                 }
    742             }
    743         }
    744     }
    745     auto ret = mCallback->processCaptureResult(results);
    746     if (!ret.isOk()) {
    747         ALOGE("%s: processCaptureResult transaction failed: %s",
    748                 __FUNCTION__, ret.description().c_str());
    749     }
    750     mProcessCaptureResultLock.unlock();
    751 }
    752 
    753 void CameraDeviceSession::ResultBatcher::processOneCaptureResult(CaptureResult& result) {
    754     hidl_vec<CaptureResult> results;
    755     results.resize(1);
    756     results[0] = std::move(result);
    757     invokeProcessCaptureResultCallback(results, /* tryWriteFmq */true);
    758     freeReleaseFences(results);
    759     return;
    760 }
    761 
    762 void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& result) {
    763     auto pair = getBatch(result.frameNumber);
    764     int batchIdx = pair.first;
    765     if (batchIdx == NOT_BATCHED) {
    766         processOneCaptureResult(result);
    767         return;
    768     }
    769     std::shared_ptr<InflightBatch> batch = pair.second;
    770     {
    771         Mutex::Autolock _l(batch->mLock);
    772         // Check if the batch is removed (mostly by notify error) before lock was acquired
    773         if (batch->mRemoved) {
    774             // Fall back to non-batch path
    775             processOneCaptureResult(result);
    776             return;
    777         }
    778 
    779         // queue metadata
    780         if (result.result.size() != 0) {
    781             // Save a copy of metadata
    782             batch->mResultMds[result.partialResult].mMds.push_back(
    783                     std::make_pair(result.frameNumber, result.result));
    784         }
    785 
    786         // queue buffer
    787         std::vector<int> filledStreams;
    788         std::vector<StreamBuffer> nonBatchedBuffers;
    789         for (auto& buffer : result.outputBuffers) {
    790             auto it = batch->mBatchBufs.find(buffer.streamId);
    791             if (it != batch->mBatchBufs.end()) {
    792                 InflightBatch::BufferBatch& bb = it->second;
    793                 pushStreamBuffer(std::move(buffer), bb.mBuffers);
    794                 filledStreams.push_back(buffer.streamId);
    795             } else {
    796                 pushStreamBuffer(std::move(buffer), nonBatchedBuffers);
    797             }
    798         }
    799 
    800         // send non-batched buffers up
    801         if (nonBatchedBuffers.size() > 0 || result.inputBuffer.streamId != -1) {
    802             CaptureResult nonBatchedResult;
    803             nonBatchedResult.frameNumber = result.frameNumber;
    804             nonBatchedResult.fmqResultSize = 0;
    805             nonBatchedResult.outputBuffers.resize(nonBatchedBuffers.size());
    806             for (size_t i = 0; i < nonBatchedBuffers.size(); i++) {
    807                 moveStreamBuffer(
    808                         std::move(nonBatchedBuffers[i]), nonBatchedResult.outputBuffers[i]);
    809             }
    810             moveStreamBuffer(std::move(result.inputBuffer), nonBatchedResult.inputBuffer);
    811             nonBatchedResult.partialResult = 0; // 0 for buffer only results
    812             processOneCaptureResult(nonBatchedResult);
    813         }
    814 
    815         if (result.frameNumber == batch->mLastFrame) {
    816             // Send data up
    817             if (result.partialResult > 0) {
    818                 sendBatchMetadataLocked(batch, result.partialResult);
    819             }
    820             // send buffer up
    821             if (filledStreams.size() > 0) {
    822                 sendBatchBuffersLocked(batch, filledStreams);
    823             }
    824         }
    825     } // end of batch lock scope
    826 
    827     // see if the batch is complete
    828     if (result.frameNumber == batch->mLastFrame) {
    829         checkAndRemoveFirstBatch();
    830     }
    831 }
    832 
    833 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
    834 Return<void> CameraDeviceSession::constructDefaultRequestSettings(
    835         RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)  {
    836     CameraMetadata outMetadata;
    837     Status status = constructDefaultRequestSettingsRaw( (int) type, &outMetadata);
    838     _hidl_cb(status, outMetadata);
    839     return Void();
    840 }
    841 
    842 Status CameraDeviceSession::constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata) {
    843     Status status = initStatus();
    844     const camera_metadata_t *rawRequest;
    845     if (status == Status::OK) {
    846         ATRACE_BEGIN("camera3->construct_default_request_settings");
    847         rawRequest = mDevice->ops->construct_default_request_settings(mDevice, (int) type);
    848         ATRACE_END();
    849         if (rawRequest == nullptr) {
    850             ALOGI("%s: template %d is not supported on this camera device",
    851                   __FUNCTION__, type);
    852             status = Status::ILLEGAL_ARGUMENT;
    853         } else {
    854             mOverridenRequest.clear();
    855             mOverridenRequest.append(rawRequest);
    856             // Derive some new keys for backward compatibility
    857             if (mDerivePostRawSensKey && !mOverridenRequest.exists(
    858                     ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) {
    859                 int32_t defaultBoost[1] = {100};
    860                 mOverridenRequest.update(
    861                         ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
    862                         defaultBoost, 1);
    863             }
    864             const camera_metadata_t *metaBuffer =
    865                     mOverridenRequest.getAndLock();
    866             convertToHidl(metaBuffer, outMetadata);
    867             mOverridenRequest.unlock(metaBuffer);
    868         }
    869     }
    870     return status;
    871 }
    872 
    873 /**
    874  * Map Android N dataspace definitions back to Android M definitions, for
    875  * use with HALv3.3 or older.
    876  *
    877  * Only map where correspondences exist, and otherwise preserve the value.
    878  */
    879 android_dataspace CameraDeviceSession::mapToLegacyDataspace(
    880         android_dataspace dataSpace) const {
    881     if (mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_3) {
    882         switch (dataSpace) {
    883             case HAL_DATASPACE_V0_SRGB_LINEAR:
    884                 return HAL_DATASPACE_SRGB_LINEAR;
    885             case HAL_DATASPACE_V0_SRGB:
    886                 return HAL_DATASPACE_SRGB;
    887             case HAL_DATASPACE_V0_JFIF:
    888                 return HAL_DATASPACE_JFIF;
    889             case HAL_DATASPACE_V0_BT601_625:
    890                 return HAL_DATASPACE_BT601_625;
    891             case HAL_DATASPACE_V0_BT601_525:
    892                 return HAL_DATASPACE_BT601_525;
    893             case HAL_DATASPACE_V0_BT709:
    894                 return HAL_DATASPACE_BT709;
    895             default:
    896                 return dataSpace;
    897         }
    898     }
    899 
    900    return dataSpace;
    901 }
    902 
    903 bool CameraDeviceSession::preProcessConfigurationLocked(
    904         const StreamConfiguration& requestedConfiguration,
    905         camera3_stream_configuration_t *stream_list /*out*/,
    906         hidl_vec<camera3_stream_t*> *streams /*out*/) {
    907 
    908     if ((stream_list == nullptr) || (streams == nullptr)) {
    909         return false;
    910     }
    911 
    912     stream_list->operation_mode = (uint32_t) requestedConfiguration.operationMode;
    913     stream_list->num_streams = requestedConfiguration.streams.size();
    914     streams->resize(stream_list->num_streams);
    915     stream_list->streams = streams->data();
    916 
    917     for (uint32_t i = 0; i < stream_list->num_streams; i++) {
    918         int id = requestedConfiguration.streams[i].id;
    919 
    920         if (mStreamMap.count(id) == 0) {
    921             Camera3Stream stream;
    922             convertFromHidl(requestedConfiguration.streams[i], &stream);
    923             mStreamMap[id] = stream;
    924             mStreamMap[id].data_space = mapToLegacyDataspace(
    925                     mStreamMap[id].data_space);
    926             mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{});
    927         } else {
    928             // width/height/format must not change, but usage/rotation might need to change
    929             if (mStreamMap[id].stream_type !=
    930                     (int) requestedConfiguration.streams[i].streamType ||
    931                     mStreamMap[id].width != requestedConfiguration.streams[i].width ||
    932                     mStreamMap[id].height != requestedConfiguration.streams[i].height ||
    933                     mStreamMap[id].format != (int) requestedConfiguration.streams[i].format ||
    934                     mStreamMap[id].data_space !=
    935                             mapToLegacyDataspace( static_cast<android_dataspace_t> (
    936                                     requestedConfiguration.streams[i].dataSpace))) {
    937                 ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
    938                 return false;
    939             }
    940             mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation;
    941             mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage;
    942         }
    943         (*streams)[i] = &mStreamMap[id];
    944     }
    945 
    946     if (mFreeBufEarly) {
    947         // Remove buffers of deleted streams
    948         for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
    949             int id = it->first;
    950             bool found = false;
    951             for (const auto& stream : requestedConfiguration.streams) {
    952                 if (id == stream.id) {
    953                     found = true;
    954                     break;
    955                 }
    956             }
    957             if (!found) {
    958                 // Unmap all buffers of deleted stream
    959                 cleanupBuffersLocked(id);
    960             }
    961         }
    962     }
    963 
    964     return true;
    965 }
    966 
    967 void CameraDeviceSession::postProcessConfigurationLocked(
    968         const StreamConfiguration& requestedConfiguration) {
    969     // delete unused streams, note we do this after adding new streams to ensure new stream
    970     // will not have the same address as deleted stream, and HAL has a chance to reference
    971     // the to be deleted stream in configure_streams call
    972     for(auto it = mStreamMap.begin(); it != mStreamMap.end();) {
    973         int id = it->first;
    974         bool found = false;
    975         for (const auto& stream : requestedConfiguration.streams) {
    976             if (id == stream.id) {
    977                 found = true;
    978                 break;
    979             }
    980         }
    981         if (!found) {
    982             // Unmap all buffers of deleted stream
    983             // in case the configuration call succeeds and HAL
    984             // is able to release the corresponding resources too.
    985             if (!mFreeBufEarly) {
    986                 cleanupBuffersLocked(id);
    987             }
    988             it = mStreamMap.erase(it);
    989         } else {
    990             ++it;
    991         }
    992     }
    993 
    994     // Track video streams
    995     mVideoStreamIds.clear();
    996     for (const auto& stream : requestedConfiguration.streams) {
    997         if (stream.streamType == StreamType::OUTPUT &&
    998             stream.usage &
    999                 graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
   1000             mVideoStreamIds.push_back(stream.id);
   1001         }
   1002     }
   1003     mResultBatcher.setBatchedStreams(mVideoStreamIds);
   1004 }
   1005 
   1006 
   1007 void CameraDeviceSession::postProcessConfigurationFailureLocked(
   1008         const StreamConfiguration& requestedConfiguration) {
   1009     if (mFreeBufEarly) {
   1010         // Re-build the buf cache entry for deleted streams
   1011         for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
   1012             int id = it->first;
   1013             bool found = false;
   1014             for (const auto& stream : requestedConfiguration.streams) {
   1015                 if (id == stream.id) {
   1016                     found = true;
   1017                     break;
   1018                 }
   1019             }
   1020             if (!found) {
   1021                 mCirculatingBuffers.emplace(id, CirculatingBuffers{});
   1022             }
   1023         }
   1024     }
   1025 }
   1026 
   1027 Return<void> CameraDeviceSession::configureStreams(
   1028         const StreamConfiguration& requestedConfiguration,
   1029         ICameraDeviceSession::configureStreams_cb _hidl_cb)  {
   1030     Status status = initStatus();
   1031     HalStreamConfiguration outStreams;
   1032 
   1033     // hold the inflight lock for entire configureStreams scope since there must not be any
   1034     // inflight request/results during stream configuration.
   1035     Mutex::Autolock _l(mInflightLock);
   1036     if (!mInflightBuffers.empty()) {
   1037         ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
   1038                 __FUNCTION__, mInflightBuffers.size());
   1039         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
   1040         return Void();
   1041     }
   1042 
   1043     if (!mInflightAETriggerOverrides.empty()) {
   1044         ALOGE("%s: trying to configureStreams while there are still %zu inflight"
   1045                 " trigger overrides!", __FUNCTION__,
   1046                 mInflightAETriggerOverrides.size());
   1047         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
   1048         return Void();
   1049     }
   1050 
   1051     if (!mInflightRawBoostPresent.empty()) {
   1052         ALOGE("%s: trying to configureStreams while there are still %zu inflight"
   1053                 " boost overrides!", __FUNCTION__,
   1054                 mInflightRawBoostPresent.size());
   1055         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
   1056         return Void();
   1057     }
   1058 
   1059     if (status != Status::OK) {
   1060         _hidl_cb(status, outStreams);
   1061         return Void();
   1062     }
   1063 
   1064     camera3_stream_configuration_t stream_list{};
   1065     hidl_vec<camera3_stream_t*> streams;
   1066     if (!preProcessConfigurationLocked(requestedConfiguration, &stream_list, &streams)) {
   1067         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
   1068         return Void();
   1069     }
   1070 
   1071     ATRACE_BEGIN("camera3->configure_streams");
   1072     status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
   1073     ATRACE_END();
   1074 
   1075     // In case Hal returns error most likely it was not able to release
   1076     // the corresponding resources of the deleted streams.
   1077     if (ret == OK) {
   1078         postProcessConfigurationLocked(requestedConfiguration);
   1079     } else {
   1080         postProcessConfigurationFailureLocked(requestedConfiguration);
   1081     }
   1082 
   1083     if (ret == -EINVAL) {
   1084         status = Status::ILLEGAL_ARGUMENT;
   1085     } else if (ret != OK) {
   1086         status = Status::INTERNAL_ERROR;
   1087     } else {
   1088         convertToHidl(stream_list, &outStreams);
   1089         mFirstRequest = true;
   1090     }
   1091 
   1092     _hidl_cb(status, outStreams);
   1093     return Void();
   1094 }
   1095 
   1096 // Needs to get called after acquiring 'mInflightLock'
   1097 void CameraDeviceSession::cleanupBuffersLocked(int id) {
   1098     for (auto& pair : mCirculatingBuffers.at(id)) {
   1099         sHandleImporter.freeBuffer(pair.second);
   1100     }
   1101     mCirculatingBuffers[id].clear();
   1102     mCirculatingBuffers.erase(id);
   1103 }
   1104 
   1105 void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove) {
   1106     Mutex::Autolock _l(mInflightLock);
   1107     for (auto& cache : cachesToRemove) {
   1108         auto cbsIt = mCirculatingBuffers.find(cache.streamId);
   1109         if (cbsIt == mCirculatingBuffers.end()) {
   1110             // The stream could have been removed
   1111             continue;
   1112         }
   1113         CirculatingBuffers& cbs = cbsIt->second;
   1114         auto it = cbs.find(cache.bufferId);
   1115         if (it != cbs.end()) {
   1116             sHandleImporter.freeBuffer(it->second);
   1117             cbs.erase(it);
   1118         } else {
   1119             ALOGE("%s: stream %d buffer %" PRIu64 " is not cached",
   1120                     __FUNCTION__, cache.streamId, cache.bufferId);
   1121         }
   1122     }
   1123 }
   1124 
   1125 Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue(
   1126     ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) {
   1127     _hidl_cb(*mRequestMetadataQueue->getDesc());
   1128     return Void();
   1129 }
   1130 
   1131 Return<void> CameraDeviceSession::getCaptureResultMetadataQueue(
   1132     ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) {
   1133     _hidl_cb(*mResultMetadataQueue->getDesc());
   1134     return Void();
   1135 }
   1136 
   1137 Return<void> CameraDeviceSession::processCaptureRequest(
   1138         const hidl_vec<CaptureRequest>& requests,
   1139         const hidl_vec<BufferCache>& cachesToRemove,
   1140         ICameraDeviceSession::processCaptureRequest_cb _hidl_cb)  {
   1141     updateBufferCaches(cachesToRemove);
   1142 
   1143     uint32_t numRequestProcessed = 0;
   1144     Status s = Status::OK;
   1145     for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
   1146         s = processOneCaptureRequest(requests[i]);
   1147         if (s != Status::OK) {
   1148             break;
   1149         }
   1150     }
   1151 
   1152     if (s == Status::OK && requests.size() > 1) {
   1153         mResultBatcher.registerBatch(requests[0].frameNumber, requests.size());
   1154     }
   1155 
   1156     _hidl_cb(s, numRequestProcessed);
   1157     return Void();
   1158 }
   1159 
   1160 Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request)  {
   1161     Status status = initStatus();
   1162     if (status != Status::OK) {
   1163         ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
   1164         return status;
   1165     }
   1166 
   1167     camera3_capture_request_t halRequest;
   1168     halRequest.frame_number = request.frameNumber;
   1169 
   1170     bool converted = true;
   1171     CameraMetadata settingsFmq;  // settings from FMQ
   1172     if (request.fmqSettingsSize > 0) {
   1173         // non-blocking read; client must write metadata before calling
   1174         // processOneCaptureRequest
   1175         settingsFmq.resize(request.fmqSettingsSize);
   1176         bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.fmqSettingsSize);
   1177         if (read) {
   1178             converted = convertFromHidl(settingsFmq, &halRequest.settings);
   1179         } else {
   1180             ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
   1181             converted = false;
   1182         }
   1183     } else {
   1184         converted = convertFromHidl(request.settings, &halRequest.settings);
   1185     }
   1186 
   1187     if (!converted) {
   1188         ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
   1189         return Status::ILLEGAL_ARGUMENT;
   1190     }
   1191 
   1192     if (mFirstRequest && halRequest.settings == nullptr) {
   1193         ALOGE("%s: capture request settings must not be null for first request!",
   1194                 __FUNCTION__);
   1195         return Status::ILLEGAL_ARGUMENT;
   1196     }
   1197 
   1198     hidl_vec<buffer_handle_t*> allBufPtrs;
   1199     hidl_vec<int> allFences;
   1200     bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
   1201             request.inputBuffer.bufferId != 0);
   1202     size_t numOutputBufs = request.outputBuffers.size();
   1203     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
   1204 
   1205     if (numOutputBufs == 0) {
   1206         ALOGE("%s: capture request must have at least one output buffer!", __FUNCTION__);
   1207         return Status::ILLEGAL_ARGUMENT;
   1208     }
   1209 
   1210     status = importRequest(request, allBufPtrs, allFences);
   1211     if (status != Status::OK) {
   1212         return status;
   1213     }
   1214 
   1215     hidl_vec<camera3_stream_buffer_t> outHalBufs;
   1216     outHalBufs.resize(numOutputBufs);
   1217     bool aeCancelTriggerNeeded = false;
   1218     ::android::hardware::camera::common::V1_0::helper::CameraMetadata settingsOverride;
   1219     {
   1220         Mutex::Autolock _l(mInflightLock);
   1221         if (hasInputBuf) {
   1222             auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
   1223             auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
   1224             convertFromHidl(
   1225                     allBufPtrs[numOutputBufs], request.inputBuffer.status,
   1226                     &mStreamMap[request.inputBuffer.streamId], allFences[numOutputBufs],
   1227                     &bufCache);
   1228             halRequest.input_buffer = &bufCache;
   1229         } else {
   1230             halRequest.input_buffer = nullptr;
   1231         }
   1232 
   1233         halRequest.num_output_buffers = numOutputBufs;
   1234         for (size_t i = 0; i < numOutputBufs; i++) {
   1235             auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
   1236             auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
   1237             convertFromHidl(
   1238                     allBufPtrs[i], request.outputBuffers[i].status,
   1239                     &mStreamMap[request.outputBuffers[i].streamId], allFences[i],
   1240                     &bufCache);
   1241             outHalBufs[i] = bufCache;
   1242         }
   1243         halRequest.output_buffers = outHalBufs.data();
   1244 
   1245         AETriggerCancelOverride triggerOverride;
   1246         aeCancelTriggerNeeded = handleAePrecaptureCancelRequestLocked(
   1247                 halRequest, &settingsOverride /*out*/, &triggerOverride/*out*/);
   1248         if (aeCancelTriggerNeeded) {
   1249             mInflightAETriggerOverrides[halRequest.frame_number] =
   1250                     triggerOverride;
   1251             halRequest.settings = settingsOverride.getAndLock();
   1252         }
   1253     }
   1254     halRequest.num_physcam_settings = 0;
   1255 
   1256     ATRACE_ASYNC_BEGIN("frame capture", request.frameNumber);
   1257     ATRACE_BEGIN("camera3->process_capture_request");
   1258     status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
   1259     ATRACE_END();
   1260     if (aeCancelTriggerNeeded) {
   1261         settingsOverride.unlock(halRequest.settings);
   1262     }
   1263     if (ret != OK) {
   1264         Mutex::Autolock _l(mInflightLock);
   1265         ALOGE("%s: HAL process_capture_request call failed!", __FUNCTION__);
   1266 
   1267         cleanupInflightFences(allFences, numBufs);
   1268         if (hasInputBuf) {
   1269             auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
   1270             mInflightBuffers.erase(key);
   1271         }
   1272         for (size_t i = 0; i < numOutputBufs; i++) {
   1273             auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
   1274             mInflightBuffers.erase(key);
   1275         }
   1276         if (aeCancelTriggerNeeded) {
   1277             mInflightAETriggerOverrides.erase(request.frameNumber);
   1278         }
   1279         return Status::INTERNAL_ERROR;
   1280     }
   1281 
   1282     mFirstRequest = false;
   1283     return Status::OK;
   1284 }
   1285 
   1286 Return<Status> CameraDeviceSession::flush()  {
   1287     Status status = initStatus();
   1288     if (status == Status::OK) {
   1289         // Flush is always supported on device 3.1 or later
   1290         status_t ret = mDevice->ops->flush(mDevice);
   1291         if (ret != OK) {
   1292             status = Status::INTERNAL_ERROR;
   1293         }
   1294     }
   1295     return status;
   1296 }
   1297 
   1298 Return<void> CameraDeviceSession::close()  {
   1299     Mutex::Autolock _l(mStateLock);
   1300     if (!mClosed) {
   1301         {
   1302             Mutex::Autolock _l(mInflightLock);
   1303             if (!mInflightBuffers.empty()) {
   1304                 ALOGE("%s: trying to close while there are still %zu inflight buffers!",
   1305                         __FUNCTION__, mInflightBuffers.size());
   1306             }
   1307             if (!mInflightAETriggerOverrides.empty()) {
   1308                 ALOGE("%s: trying to close while there are still %zu inflight "
   1309                         "trigger overrides!", __FUNCTION__,
   1310                         mInflightAETriggerOverrides.size());
   1311             }
   1312             if (!mInflightRawBoostPresent.empty()) {
   1313                 ALOGE("%s: trying to close while there are still %zu inflight "
   1314                         " RAW boost overrides!", __FUNCTION__,
   1315                         mInflightRawBoostPresent.size());
   1316             }
   1317 
   1318         }
   1319 
   1320         ATRACE_BEGIN("camera3->close");
   1321         mDevice->common.close(&mDevice->common);
   1322         ATRACE_END();
   1323 
   1324         // free all imported buffers
   1325         Mutex::Autolock _l(mInflightLock);
   1326         for(auto& pair : mCirculatingBuffers) {
   1327             CirculatingBuffers& buffers = pair.second;
   1328             for (auto& p2 : buffers) {
   1329                 sHandleImporter.freeBuffer(p2.second);
   1330             }
   1331             buffers.clear();
   1332         }
   1333         mCirculatingBuffers.clear();
   1334 
   1335         mClosed = true;
   1336     }
   1337     return Void();
   1338 }
   1339 
   1340 uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t&, int) {
   1341     // No need to fill in bufferId by default
   1342     return BUFFER_ID_NO_BUFFER;
   1343 }
   1344 
   1345 status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result,
   1346                                                  const camera3_capture_result *hal_result) {
   1347     uint32_t frameNumber = hal_result->frame_number;
   1348     bool hasInputBuf = (hal_result->input_buffer != nullptr);
   1349     size_t numOutputBufs = hal_result->num_output_buffers;
   1350     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
   1351     if (numBufs > 0) {
   1352         Mutex::Autolock _l(mInflightLock);
   1353         if (hasInputBuf) {
   1354             int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
   1355             // validate if buffer is inflight
   1356             auto key = std::make_pair(streamId, frameNumber);
   1357             if (mInflightBuffers.count(key) != 1) {
   1358                 ALOGE("%s: input buffer for stream %d frame %d is not inflight!",
   1359                         __FUNCTION__, streamId, frameNumber);
   1360                 return -EINVAL;
   1361             }
   1362         }
   1363 
   1364         for (size_t i = 0; i < numOutputBufs; i++) {
   1365             int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
   1366             // validate if buffer is inflight
   1367             auto key = std::make_pair(streamId, frameNumber);
   1368             if (mInflightBuffers.count(key) != 1) {
   1369                 ALOGE("%s: output buffer for stream %d frame %d is not inflight!",
   1370                         __FUNCTION__, streamId, frameNumber);
   1371                 return -EINVAL;
   1372             }
   1373         }
   1374     }
   1375     // We don't need to validate/import fences here since we will be passing them to camera service
   1376     // within the scope of this function
   1377     result.frameNumber = frameNumber;
   1378     result.fmqResultSize = 0;
   1379     result.partialResult = hal_result->partial_result;
   1380     convertToHidl(hal_result->result, &result.result);
   1381     if (nullptr != hal_result->result) {
   1382         bool resultOverriden = false;
   1383         Mutex::Autolock _l(mInflightLock);
   1384 
   1385         // Derive some new keys for backward compatibility
   1386         if (mDerivePostRawSensKey) {
   1387             camera_metadata_ro_entry entry;
   1388             if (find_camera_metadata_ro_entry(hal_result->result,
   1389                     ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &entry) == 0) {
   1390                 mInflightRawBoostPresent[frameNumber] = true;
   1391             } else {
   1392                 auto entry = mInflightRawBoostPresent.find(frameNumber);
   1393                 if (mInflightRawBoostPresent.end() == entry) {
   1394                     mInflightRawBoostPresent[frameNumber] = false;
   1395                 }
   1396             }
   1397 
   1398             if ((hal_result->partial_result == mNumPartialResults)) {
   1399                 if (!mInflightRawBoostPresent[frameNumber]) {
   1400                     if (!resultOverriden) {
   1401                         mOverridenResult.clear();
   1402                         mOverridenResult.append(hal_result->result);
   1403                         resultOverriden = true;
   1404                     }
   1405                     int32_t defaultBoost[1] = {100};
   1406                     mOverridenResult.update(
   1407                             ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
   1408                             defaultBoost, 1);
   1409                 }
   1410 
   1411                 mInflightRawBoostPresent.erase(frameNumber);
   1412             }
   1413         }
   1414 
   1415         auto entry = mInflightAETriggerOverrides.find(frameNumber);
   1416         if (mInflightAETriggerOverrides.end() != entry) {
   1417             if (!resultOverriden) {
   1418                 mOverridenResult.clear();
   1419                 mOverridenResult.append(hal_result->result);
   1420                 resultOverriden = true;
   1421             }
   1422             overrideResultForPrecaptureCancelLocked(entry->second,
   1423                     &mOverridenResult);
   1424             if (hal_result->partial_result == mNumPartialResults) {
   1425                 mInflightAETriggerOverrides.erase(frameNumber);
   1426             }
   1427         }
   1428 
   1429         if (resultOverriden) {
   1430             const camera_metadata_t *metaBuffer =
   1431                     mOverridenResult.getAndLock();
   1432             convertToHidl(metaBuffer, &result.result);
   1433             mOverridenResult.unlock(metaBuffer);
   1434         }
   1435     }
   1436     if (hasInputBuf) {
   1437         result.inputBuffer.streamId =
   1438                 static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
   1439         result.inputBuffer.buffer = nullptr;
   1440         result.inputBuffer.status = (BufferStatus) hal_result->input_buffer->status;
   1441         // skip acquire fence since it's no use to camera service
   1442         if (hal_result->input_buffer->release_fence != -1) {
   1443             native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
   1444             handle->data[0] = hal_result->input_buffer->release_fence;
   1445             result.inputBuffer.releaseFence = handle;
   1446         } else {
   1447             result.inputBuffer.releaseFence = nullptr;
   1448         }
   1449     } else {
   1450         result.inputBuffer.streamId = -1;
   1451     }
   1452 
   1453     result.outputBuffers.resize(numOutputBufs);
   1454     for (size_t i = 0; i < numOutputBufs; i++) {
   1455         result.outputBuffers[i].streamId =
   1456                 static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
   1457         result.outputBuffers[i].buffer = nullptr;
   1458         if (hal_result->output_buffers[i].buffer != nullptr) {
   1459             result.outputBuffers[i].bufferId = getCapResultBufferId(
   1460                     *(hal_result->output_buffers[i].buffer),
   1461                     result.outputBuffers[i].streamId);
   1462         } else {
   1463             result.outputBuffers[i].bufferId = 0;
   1464         }
   1465 
   1466         result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
   1467         // skip acquire fence since it's of no use to camera service
   1468         if (hal_result->output_buffers[i].release_fence != -1) {
   1469             native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
   1470             handle->data[0] = hal_result->output_buffers[i].release_fence;
   1471             result.outputBuffers[i].releaseFence = handle;
   1472         } else {
   1473             result.outputBuffers[i].releaseFence = nullptr;
   1474         }
   1475     }
   1476 
   1477     // Free inflight record/fences.
   1478     // Do this before call back to camera service because camera service might jump to
   1479     // configure_streams right after the processCaptureResult call so we need to finish
   1480     // updating inflight queues first
   1481     if (numBufs > 0) {
   1482         Mutex::Autolock _l(mInflightLock);
   1483         if (hasInputBuf) {
   1484             int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
   1485             auto key = std::make_pair(streamId, frameNumber);
   1486             mInflightBuffers.erase(key);
   1487         }
   1488 
   1489         for (size_t i = 0; i < numOutputBufs; i++) {
   1490             int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
   1491             auto key = std::make_pair(streamId, frameNumber);
   1492             mInflightBuffers.erase(key);
   1493         }
   1494 
   1495         if (mInflightBuffers.empty()) {
   1496             ALOGV("%s: inflight buffer queue is now empty!", __FUNCTION__);
   1497         }
   1498     }
   1499     return OK;
   1500 }
   1501 
   1502 // Static helper method to copy/shrink capture result metadata sent by HAL
   1503 void CameraDeviceSession::sShrinkCaptureResult(
   1504         camera3_capture_result* dst, const camera3_capture_result* src,
   1505         std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
   1506         std::vector<const camera_metadata_t*>* physCamMdArray,
   1507         bool handlePhysCam) {
   1508     *dst = *src;
   1509     // Reserve maximum number of entries to avoid metadata re-allocation.
   1510     mds->reserve(1 + (handlePhysCam ? src->num_physcam_metadata : 0));
   1511     if (sShouldShrink(src->result)) {
   1512         mds->emplace_back(sCreateCompactCopy(src->result));
   1513         dst->result = mds->back().getAndLock();
   1514     }
   1515 
   1516     if (handlePhysCam) {
   1517         // First determine if we need to create new camera_metadata_t* array
   1518         bool needShrink = false;
   1519         for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
   1520             if (sShouldShrink(src->physcam_metadata[i])) {
   1521                 needShrink = true;
   1522             }
   1523         }
   1524 
   1525         if (!needShrink) return;
   1526 
   1527         physCamMdArray->reserve(src->num_physcam_metadata);
   1528         dst->physcam_metadata = physCamMdArray->data();
   1529         for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
   1530             if (sShouldShrink(src->physcam_metadata[i])) {
   1531                 mds->emplace_back(sCreateCompactCopy(src->physcam_metadata[i]));
   1532                 dst->physcam_metadata[i] = mds->back().getAndLock();
   1533             } else {
   1534                 dst->physcam_metadata[i] = src->physcam_metadata[i];
   1535             }
   1536         }
   1537     }
   1538 }
   1539 
   1540 bool CameraDeviceSession::sShouldShrink(const camera_metadata_t* md) {
   1541     size_t compactSize = get_camera_metadata_compact_size(md);
   1542     size_t totalSize = get_camera_metadata_size(md);
   1543     if (totalSize >= compactSize + METADATA_SHRINK_ABS_THRESHOLD &&
   1544             totalSize >= compactSize * METADATA_SHRINK_REL_THRESHOLD) {
   1545         ALOGV("Camera metadata should be shrunk from %zu to %zu", totalSize, compactSize);
   1546         return true;
   1547     }
   1548     return false;
   1549 }
   1550 
   1551 camera_metadata_t* CameraDeviceSession::sCreateCompactCopy(const camera_metadata_t* src) {
   1552     size_t compactSize = get_camera_metadata_compact_size(src);
   1553     void* buffer = calloc(1, compactSize);
   1554     if (buffer == nullptr) {
   1555         ALOGE("%s: Allocating %zu bytes failed", __FUNCTION__, compactSize);
   1556     }
   1557     return copy_camera_metadata(buffer, compactSize, src);
   1558 }
   1559 
   1560 /**
   1561  * Static callback forwarding methods from HAL to instance
   1562  */
   1563 void CameraDeviceSession::sProcessCaptureResult(
   1564         const camera3_callback_ops *cb,
   1565         const camera3_capture_result *hal_result) {
   1566     CameraDeviceSession *d =
   1567             const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
   1568 
   1569     CaptureResult result = {};
   1570     camera3_capture_result shadowResult;
   1571     bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
   1572     std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
   1573     std::vector<const camera_metadata_t*> physCamMdArray;
   1574     sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
   1575 
   1576     status_t ret = d->constructCaptureResult(result, &shadowResult);
   1577     if (ret == OK) {
   1578         d->mResultBatcher.processCaptureResult(result);
   1579     }
   1580 }
   1581 
   1582 void CameraDeviceSession::sNotify(
   1583         const camera3_callback_ops *cb,
   1584         const camera3_notify_msg *msg) {
   1585     CameraDeviceSession *d =
   1586             const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
   1587     NotifyMsg hidlMsg;
   1588     convertToHidl(msg, &hidlMsg);
   1589 
   1590     if (hidlMsg.type == (MsgType) CAMERA3_MSG_ERROR &&
   1591             hidlMsg.msg.error.errorStreamId != -1) {
   1592         if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
   1593             ALOGE("%s: unknown stream ID %d reports an error!",
   1594                     __FUNCTION__, hidlMsg.msg.error.errorStreamId);
   1595             return;
   1596         }
   1597     }
   1598 
   1599     if (static_cast<camera3_msg_type_t>(hidlMsg.type) == CAMERA3_MSG_ERROR) {
   1600         switch (hidlMsg.msg.error.errorCode) {
   1601             case ErrorCode::ERROR_DEVICE:
   1602             case ErrorCode::ERROR_REQUEST:
   1603             case ErrorCode::ERROR_RESULT: {
   1604                 Mutex::Autolock _l(d->mInflightLock);
   1605                 auto entry = d->mInflightAETriggerOverrides.find(
   1606                         hidlMsg.msg.error.frameNumber);
   1607                 if (d->mInflightAETriggerOverrides.end() != entry) {
   1608                     d->mInflightAETriggerOverrides.erase(
   1609                             hidlMsg.msg.error.frameNumber);
   1610                 }
   1611 
   1612                 auto boostEntry = d->mInflightRawBoostPresent.find(
   1613                         hidlMsg.msg.error.frameNumber);
   1614                 if (d->mInflightRawBoostPresent.end() != boostEntry) {
   1615                     d->mInflightRawBoostPresent.erase(
   1616                             hidlMsg.msg.error.frameNumber);
   1617                 }
   1618 
   1619             }
   1620                 break;
   1621             case ErrorCode::ERROR_BUFFER:
   1622             default:
   1623                 break;
   1624         }
   1625 
   1626     }
   1627 
   1628     d->mResultBatcher.notify(hidlMsg);
   1629 }
   1630 
   1631 } // namespace implementation
   1632 }  // namespace V3_2
   1633 }  // namespace device
   1634 }  // namespace camera
   1635 }  // namespace hardware
   1636 }  // namespace android
   1637