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@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 
CameraDeviceSession(camera3_device_t * device,const camera_metadata_t * deviceInfo,const sp<ICameraDeviceCallback> & callback)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 
initialize()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 
shouldFreeBufEarly()154 bool CameraDeviceSession::shouldFreeBufEarly() {
155     return property_get_bool("ro.vendor.camera.free_buf_early", 0) == 1;
156 }
157 
~CameraDeviceSession()158 CameraDeviceSession::~CameraDeviceSession() {
159     if (!isClosed()) {
160         ALOGE("CameraDeviceSession deleted before close!");
161         close();
162     }
163 }
164 
isClosed()165 bool CameraDeviceSession::isClosed() {
166     Mutex::Autolock _l(mStateLock);
167     return mClosed;
168 }
169 
initStatus() const170 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 
disconnect()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 
dumpState(const native_handle_t * fd)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  */
handleAePrecaptureCancelRequestLocked(const camera3_capture_request_t & halRequest,::android::hardware::camera::common::V1_0::helper::CameraMetadata * settings,AETriggerCancelOverride * override)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  */
overrideResultForPrecaptureCancelLocked(const AETriggerCancelOverride & aeTriggerCancelOverride,::android::hardware::camera::common::V1_0::helper::CameraMetadata * settings)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 
importBuffer(int32_t streamId,uint64_t bufId,buffer_handle_t buf,buffer_handle_t ** outBufPtr,bool allowEmptyBuf)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 
importRequest(const CaptureRequest & request,hidl_vec<buffer_handle_t * > & allBufPtrs,hidl_vec<int> & allFences)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 
importRequestImpl(const CaptureRequest & request,hidl_vec<buffer_handle_t * > & allBufPtrs,hidl_vec<int> & allFences,bool allowEmptyBuf)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 
cleanupInflightFences(hidl_vec<int> & allFences,size_t numFences)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 
ResultBatcher(const sp<ICameraDeviceCallback> & callback)381 CameraDeviceSession::ResultBatcher::ResultBatcher(
382         const sp<ICameraDeviceCallback>& callback) : mCallback(callback) {};
383 
allDelivered() const384 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 
setNumPartialResults(uint32_t n)399 void CameraDeviceSession::ResultBatcher::setNumPartialResults(uint32_t n) {
400     Mutex::Autolock _l(mLock);
401     mNumPartialResults = n;
402 }
403 
setBatchedStreams(const std::vector<int> & streamsToBatch)404 void CameraDeviceSession::ResultBatcher::setBatchedStreams(
405         const std::vector<int>& streamsToBatch) {
406     Mutex::Autolock _l(mLock);
407     mStreamsToBatch = streamsToBatch;
408 }
409 
setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q)410 void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(
411         std::shared_ptr<ResultMetadataQueue> q) {
412     Mutex::Autolock _l(mLock);
413     mResultMetadataQueue = q;
414 }
415 
registerBatch(uint32_t frameNumber,uint32_t batchSize)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>>
getBatch(uint32_t frameNumber)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 
checkAndRemoveFirstBatch()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 
sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch)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 
freeReleaseFences(hidl_vec<CaptureResult> & results)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 
moveStreamBuffer(StreamBuffer && src,StreamBuffer & dst)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 
pushStreamBuffer(StreamBuffer && src,std::vector<StreamBuffer> & dst)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 
sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch)528 void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
529         std::shared_ptr<InflightBatch> batch) {
530     sendBatchBuffersLocked(batch, mStreamsToBatch);
531 }
532 
sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch,const std::vector<int> & streams)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 
sendBatchMetadataLocked(std::shared_ptr<InflightBatch> batch,uint32_t lastPartialResultIdx)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 
notifySingleMsg(NotifyMsg & msg)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 
notify(NotifyMsg & msg)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 
invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> & results,bool tryWriteFmq)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 
processOneCaptureResult(CaptureResult & result)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 
processCaptureResult(CaptureResult & result)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                 auto id = buffer.streamId;
794                 pushStreamBuffer(std::move(buffer), bb.mBuffers);
795                 filledStreams.push_back(id);
796             } else {
797                 pushStreamBuffer(std::move(buffer), nonBatchedBuffers);
798             }
799         }
800 
801         // send non-batched buffers up
802         if (nonBatchedBuffers.size() > 0 || result.inputBuffer.streamId != -1) {
803             CaptureResult nonBatchedResult;
804             nonBatchedResult.frameNumber = result.frameNumber;
805             nonBatchedResult.fmqResultSize = 0;
806             nonBatchedResult.outputBuffers.resize(nonBatchedBuffers.size());
807             for (size_t i = 0; i < nonBatchedBuffers.size(); i++) {
808                 moveStreamBuffer(
809                         std::move(nonBatchedBuffers[i]), nonBatchedResult.outputBuffers[i]);
810             }
811             moveStreamBuffer(std::move(result.inputBuffer), nonBatchedResult.inputBuffer);
812             nonBatchedResult.partialResult = 0; // 0 for buffer only results
813             processOneCaptureResult(nonBatchedResult);
814         }
815 
816         if (result.frameNumber == batch->mLastFrame) {
817             // Send data up
818             if (result.partialResult > 0) {
819                 sendBatchMetadataLocked(batch, result.partialResult);
820             }
821             // send buffer up
822             if (filledStreams.size() > 0) {
823                 sendBatchBuffersLocked(batch, filledStreams);
824             }
825         }
826     } // end of batch lock scope
827 
828     // see if the batch is complete
829     if (result.frameNumber == batch->mLastFrame) {
830         checkAndRemoveFirstBatch();
831     }
832 }
833 
834 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
constructDefaultRequestSettings(RequestTemplate type,ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)835 Return<void> CameraDeviceSession::constructDefaultRequestSettings(
836         RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)  {
837     CameraMetadata outMetadata;
838     Status status = constructDefaultRequestSettingsRaw( (int) type, &outMetadata);
839     _hidl_cb(status, outMetadata);
840     return Void();
841 }
842 
constructDefaultRequestSettingsRaw(int type,CameraMetadata * outMetadata)843 Status CameraDeviceSession::constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata) {
844     Status status = initStatus();
845     const camera_metadata_t *rawRequest;
846     if (status == Status::OK) {
847         ATRACE_BEGIN("camera3->construct_default_request_settings");
848         rawRequest = mDevice->ops->construct_default_request_settings(mDevice, (int) type);
849         ATRACE_END();
850         if (rawRequest == nullptr) {
851             ALOGI("%s: template %d is not supported on this camera device",
852                   __FUNCTION__, type);
853             status = Status::ILLEGAL_ARGUMENT;
854         } else {
855             mOverridenRequest.clear();
856             mOverridenRequest.append(rawRequest);
857             // Derive some new keys for backward compatibility
858             if (mDerivePostRawSensKey && !mOverridenRequest.exists(
859                     ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) {
860                 int32_t defaultBoost[1] = {100};
861                 mOverridenRequest.update(
862                         ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
863                         defaultBoost, 1);
864             }
865             const camera_metadata_t *metaBuffer =
866                     mOverridenRequest.getAndLock();
867             convertToHidl(metaBuffer, outMetadata);
868             mOverridenRequest.unlock(metaBuffer);
869         }
870     }
871     return status;
872 }
873 
874 /**
875  * Map Android N dataspace definitions back to Android M definitions, for
876  * use with HALv3.3 or older.
877  *
878  * Only map where correspondences exist, and otherwise preserve the value.
879  */
mapToLegacyDataspace(android_dataspace dataSpace) const880 android_dataspace CameraDeviceSession::mapToLegacyDataspace(
881         android_dataspace dataSpace) const {
882     if (mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_3) {
883         switch (dataSpace) {
884             case HAL_DATASPACE_V0_SRGB_LINEAR:
885                 return HAL_DATASPACE_SRGB_LINEAR;
886             case HAL_DATASPACE_V0_SRGB:
887                 return HAL_DATASPACE_SRGB;
888             case HAL_DATASPACE_V0_JFIF:
889                 return HAL_DATASPACE_JFIF;
890             case HAL_DATASPACE_V0_BT601_625:
891                 return HAL_DATASPACE_BT601_625;
892             case HAL_DATASPACE_V0_BT601_525:
893                 return HAL_DATASPACE_BT601_525;
894             case HAL_DATASPACE_V0_BT709:
895                 return HAL_DATASPACE_BT709;
896             default:
897                 return dataSpace;
898         }
899     }
900 
901    return dataSpace;
902 }
903 
preProcessConfigurationLocked(const StreamConfiguration & requestedConfiguration,camera3_stream_configuration_t * stream_list,hidl_vec<camera3_stream_t * > * streams)904 bool CameraDeviceSession::preProcessConfigurationLocked(
905         const StreamConfiguration& requestedConfiguration,
906         camera3_stream_configuration_t *stream_list /*out*/,
907         hidl_vec<camera3_stream_t*> *streams /*out*/) {
908 
909     if ((stream_list == nullptr) || (streams == nullptr)) {
910         return false;
911     }
912 
913     stream_list->operation_mode = (uint32_t) requestedConfiguration.operationMode;
914     stream_list->num_streams = requestedConfiguration.streams.size();
915     streams->resize(stream_list->num_streams);
916     stream_list->streams = streams->data();
917 
918     for (uint32_t i = 0; i < stream_list->num_streams; i++) {
919         int id = requestedConfiguration.streams[i].id;
920 
921         if (mStreamMap.count(id) == 0) {
922             Camera3Stream stream;
923             convertFromHidl(requestedConfiguration.streams[i], &stream);
924             mStreamMap[id] = stream;
925             mStreamMap[id].data_space = mapToLegacyDataspace(
926                     mStreamMap[id].data_space);
927             mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{});
928         } else {
929             // width/height/format must not change, but usage/rotation might need to change
930             if (mStreamMap[id].stream_type !=
931                     (int) requestedConfiguration.streams[i].streamType ||
932                     mStreamMap[id].width != requestedConfiguration.streams[i].width ||
933                     mStreamMap[id].height != requestedConfiguration.streams[i].height ||
934                     mStreamMap[id].format != (int) requestedConfiguration.streams[i].format ||
935                     mStreamMap[id].data_space !=
936                             mapToLegacyDataspace( static_cast<android_dataspace_t> (
937                                     requestedConfiguration.streams[i].dataSpace))) {
938                 ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
939                 return false;
940             }
941             mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation;
942             mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage;
943         }
944         (*streams)[i] = &mStreamMap[id];
945     }
946 
947     if (mFreeBufEarly) {
948         // Remove buffers of deleted streams
949         for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
950             int id = it->first;
951             bool found = false;
952             for (const auto& stream : requestedConfiguration.streams) {
953                 if (id == stream.id) {
954                     found = true;
955                     break;
956                 }
957             }
958             if (!found) {
959                 // Unmap all buffers of deleted stream
960                 cleanupBuffersLocked(id);
961             }
962         }
963     }
964 
965     return true;
966 }
967 
postProcessConfigurationLocked(const StreamConfiguration & requestedConfiguration)968 void CameraDeviceSession::postProcessConfigurationLocked(
969         const StreamConfiguration& requestedConfiguration) {
970     // delete unused streams, note we do this after adding new streams to ensure new stream
971     // will not have the same address as deleted stream, and HAL has a chance to reference
972     // the to be deleted stream in configure_streams call
973     for(auto it = mStreamMap.begin(); it != mStreamMap.end();) {
974         int id = it->first;
975         bool found = false;
976         for (const auto& stream : requestedConfiguration.streams) {
977             if (id == stream.id) {
978                 found = true;
979                 break;
980             }
981         }
982         if (!found) {
983             // Unmap all buffers of deleted stream
984             // in case the configuration call succeeds and HAL
985             // is able to release the corresponding resources too.
986             if (!mFreeBufEarly) {
987                 cleanupBuffersLocked(id);
988             }
989             it = mStreamMap.erase(it);
990         } else {
991             ++it;
992         }
993     }
994 
995     // Track video streams
996     mVideoStreamIds.clear();
997     for (const auto& stream : requestedConfiguration.streams) {
998         if (stream.streamType == StreamType::OUTPUT &&
999             stream.usage &
1000                 graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
1001             mVideoStreamIds.push_back(stream.id);
1002         }
1003     }
1004     mResultBatcher.setBatchedStreams(mVideoStreamIds);
1005 }
1006 
1007 
postProcessConfigurationFailureLocked(const StreamConfiguration & requestedConfiguration)1008 void CameraDeviceSession::postProcessConfigurationFailureLocked(
1009         const StreamConfiguration& requestedConfiguration) {
1010     if (mFreeBufEarly) {
1011         // Re-build the buf cache entry for deleted streams
1012         for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
1013             int id = it->first;
1014             bool found = false;
1015             for (const auto& stream : requestedConfiguration.streams) {
1016                 if (id == stream.id) {
1017                     found = true;
1018                     break;
1019                 }
1020             }
1021             if (!found) {
1022                 mCirculatingBuffers.emplace(id, CirculatingBuffers{});
1023             }
1024         }
1025     }
1026 }
1027 
configureStreams(const StreamConfiguration & requestedConfiguration,ICameraDeviceSession::configureStreams_cb _hidl_cb)1028 Return<void> CameraDeviceSession::configureStreams(
1029         const StreamConfiguration& requestedConfiguration,
1030         ICameraDeviceSession::configureStreams_cb _hidl_cb)  {
1031     Status status = initStatus();
1032     HalStreamConfiguration outStreams;
1033 
1034     // hold the inflight lock for entire configureStreams scope since there must not be any
1035     // inflight request/results during stream configuration.
1036     Mutex::Autolock _l(mInflightLock);
1037     if (!mInflightBuffers.empty()) {
1038         ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
1039                 __FUNCTION__, mInflightBuffers.size());
1040         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1041         return Void();
1042     }
1043 
1044     if (!mInflightAETriggerOverrides.empty()) {
1045         ALOGE("%s: trying to configureStreams while there are still %zu inflight"
1046                 " trigger overrides!", __FUNCTION__,
1047                 mInflightAETriggerOverrides.size());
1048         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1049         return Void();
1050     }
1051 
1052     if (!mInflightRawBoostPresent.empty()) {
1053         ALOGE("%s: trying to configureStreams while there are still %zu inflight"
1054                 " boost overrides!", __FUNCTION__,
1055                 mInflightRawBoostPresent.size());
1056         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1057         return Void();
1058     }
1059 
1060     if (status != Status::OK) {
1061         _hidl_cb(status, outStreams);
1062         return Void();
1063     }
1064 
1065     camera3_stream_configuration_t stream_list{};
1066     hidl_vec<camera3_stream_t*> streams;
1067     if (!preProcessConfigurationLocked(requestedConfiguration, &stream_list, &streams)) {
1068         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1069         return Void();
1070     }
1071 
1072     ATRACE_BEGIN("camera3->configure_streams");
1073     status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
1074     ATRACE_END();
1075 
1076     // In case Hal returns error most likely it was not able to release
1077     // the corresponding resources of the deleted streams.
1078     if (ret == OK) {
1079         postProcessConfigurationLocked(requestedConfiguration);
1080     } else {
1081         postProcessConfigurationFailureLocked(requestedConfiguration);
1082     }
1083 
1084     if (ret == -EINVAL) {
1085         status = Status::ILLEGAL_ARGUMENT;
1086     } else if (ret != OK) {
1087         status = Status::INTERNAL_ERROR;
1088     } else {
1089         convertToHidl(stream_list, &outStreams);
1090         mFirstRequest = true;
1091     }
1092 
1093     _hidl_cb(status, outStreams);
1094     return Void();
1095 }
1096 
1097 // Needs to get called after acquiring 'mInflightLock'
cleanupBuffersLocked(int id)1098 void CameraDeviceSession::cleanupBuffersLocked(int id) {
1099     for (auto& pair : mCirculatingBuffers.at(id)) {
1100         sHandleImporter.freeBuffer(pair.second);
1101     }
1102     mCirculatingBuffers[id].clear();
1103     mCirculatingBuffers.erase(id);
1104 }
1105 
updateBufferCaches(const hidl_vec<BufferCache> & cachesToRemove)1106 void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove) {
1107     Mutex::Autolock _l(mInflightLock);
1108     for (auto& cache : cachesToRemove) {
1109         auto cbsIt = mCirculatingBuffers.find(cache.streamId);
1110         if (cbsIt == mCirculatingBuffers.end()) {
1111             // The stream could have been removed
1112             continue;
1113         }
1114         CirculatingBuffers& cbs = cbsIt->second;
1115         auto it = cbs.find(cache.bufferId);
1116         if (it != cbs.end()) {
1117             sHandleImporter.freeBuffer(it->second);
1118             cbs.erase(it);
1119         } else {
1120             ALOGE("%s: stream %d buffer %" PRIu64 " is not cached",
1121                     __FUNCTION__, cache.streamId, cache.bufferId);
1122         }
1123     }
1124 }
1125 
getCaptureRequestMetadataQueue(ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb)1126 Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue(
1127     ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) {
1128     _hidl_cb(*mRequestMetadataQueue->getDesc());
1129     return Void();
1130 }
1131 
getCaptureResultMetadataQueue(ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb)1132 Return<void> CameraDeviceSession::getCaptureResultMetadataQueue(
1133     ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) {
1134     _hidl_cb(*mResultMetadataQueue->getDesc());
1135     return Void();
1136 }
1137 
processCaptureRequest(const hidl_vec<CaptureRequest> & requests,const hidl_vec<BufferCache> & cachesToRemove,ICameraDeviceSession::processCaptureRequest_cb _hidl_cb)1138 Return<void> CameraDeviceSession::processCaptureRequest(
1139         const hidl_vec<CaptureRequest>& requests,
1140         const hidl_vec<BufferCache>& cachesToRemove,
1141         ICameraDeviceSession::processCaptureRequest_cb _hidl_cb)  {
1142     updateBufferCaches(cachesToRemove);
1143 
1144     uint32_t numRequestProcessed = 0;
1145     Status s = Status::OK;
1146     for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
1147         s = processOneCaptureRequest(requests[i]);
1148         if (s != Status::OK) {
1149             break;
1150         }
1151     }
1152 
1153     if (s == Status::OK && requests.size() > 1) {
1154         mResultBatcher.registerBatch(requests[0].frameNumber, requests.size());
1155     }
1156 
1157     _hidl_cb(s, numRequestProcessed);
1158     return Void();
1159 }
1160 
processOneCaptureRequest(const CaptureRequest & request)1161 Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request)  {
1162     Status status = initStatus();
1163     if (status != Status::OK) {
1164         ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
1165         return status;
1166     }
1167 
1168     camera3_capture_request_t halRequest;
1169     halRequest.frame_number = request.frameNumber;
1170 
1171     bool converted = true;
1172     CameraMetadata settingsFmq;  // settings from FMQ
1173     if (request.fmqSettingsSize > 0) {
1174         // non-blocking read; client must write metadata before calling
1175         // processOneCaptureRequest
1176         settingsFmq.resize(request.fmqSettingsSize);
1177         bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.fmqSettingsSize);
1178         if (read) {
1179             converted = convertFromHidl(settingsFmq, &halRequest.settings);
1180         } else {
1181             ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
1182             converted = false;
1183         }
1184     } else {
1185         converted = convertFromHidl(request.settings, &halRequest.settings);
1186     }
1187 
1188     if (!converted) {
1189         ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
1190         return Status::ILLEGAL_ARGUMENT;
1191     }
1192 
1193     if (mFirstRequest && halRequest.settings == nullptr) {
1194         ALOGE("%s: capture request settings must not be null for first request!",
1195                 __FUNCTION__);
1196         return Status::ILLEGAL_ARGUMENT;
1197     }
1198 
1199     hidl_vec<buffer_handle_t*> allBufPtrs;
1200     hidl_vec<int> allFences;
1201     bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
1202             request.inputBuffer.bufferId != 0);
1203     size_t numOutputBufs = request.outputBuffers.size();
1204     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
1205 
1206     if (numOutputBufs == 0) {
1207         ALOGE("%s: capture request must have at least one output buffer!", __FUNCTION__);
1208         return Status::ILLEGAL_ARGUMENT;
1209     }
1210 
1211     status = importRequest(request, allBufPtrs, allFences);
1212     if (status != Status::OK) {
1213         return status;
1214     }
1215 
1216     hidl_vec<camera3_stream_buffer_t> outHalBufs;
1217     outHalBufs.resize(numOutputBufs);
1218     bool aeCancelTriggerNeeded = false;
1219     ::android::hardware::camera::common::V1_0::helper::CameraMetadata settingsOverride;
1220     {
1221         Mutex::Autolock _l(mInflightLock);
1222         if (hasInputBuf) {
1223             auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
1224             auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
1225             convertFromHidl(
1226                     allBufPtrs[numOutputBufs], request.inputBuffer.status,
1227                     &mStreamMap[request.inputBuffer.streamId], allFences[numOutputBufs],
1228                     &bufCache);
1229             halRequest.input_buffer = &bufCache;
1230         } else {
1231             halRequest.input_buffer = nullptr;
1232         }
1233 
1234         halRequest.num_output_buffers = numOutputBufs;
1235         for (size_t i = 0; i < numOutputBufs; i++) {
1236             auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
1237             auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
1238             convertFromHidl(
1239                     allBufPtrs[i], request.outputBuffers[i].status,
1240                     &mStreamMap[request.outputBuffers[i].streamId], allFences[i],
1241                     &bufCache);
1242             outHalBufs[i] = bufCache;
1243         }
1244         halRequest.output_buffers = outHalBufs.data();
1245 
1246         AETriggerCancelOverride triggerOverride;
1247         aeCancelTriggerNeeded = handleAePrecaptureCancelRequestLocked(
1248                 halRequest, &settingsOverride /*out*/, &triggerOverride/*out*/);
1249         if (aeCancelTriggerNeeded) {
1250             mInflightAETriggerOverrides[halRequest.frame_number] =
1251                     triggerOverride;
1252             halRequest.settings = settingsOverride.getAndLock();
1253         }
1254     }
1255     halRequest.num_physcam_settings = 0;
1256 
1257     ATRACE_ASYNC_BEGIN("frame capture", request.frameNumber);
1258     ATRACE_BEGIN("camera3->process_capture_request");
1259     status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
1260     ATRACE_END();
1261     if (aeCancelTriggerNeeded) {
1262         settingsOverride.unlock(halRequest.settings);
1263     }
1264     if (ret != OK) {
1265         Mutex::Autolock _l(mInflightLock);
1266         ALOGE("%s: HAL process_capture_request call failed!", __FUNCTION__);
1267 
1268         cleanupInflightFences(allFences, numBufs);
1269         if (hasInputBuf) {
1270             auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
1271             mInflightBuffers.erase(key);
1272         }
1273         for (size_t i = 0; i < numOutputBufs; i++) {
1274             auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
1275             mInflightBuffers.erase(key);
1276         }
1277         if (aeCancelTriggerNeeded) {
1278             mInflightAETriggerOverrides.erase(request.frameNumber);
1279         }
1280         return Status::INTERNAL_ERROR;
1281     }
1282 
1283     mFirstRequest = false;
1284     return Status::OK;
1285 }
1286 
flush()1287 Return<Status> CameraDeviceSession::flush()  {
1288     Status status = initStatus();
1289     if (status == Status::OK) {
1290         // Flush is always supported on device 3.1 or later
1291         status_t ret = mDevice->ops->flush(mDevice);
1292         if (ret != OK) {
1293             status = Status::INTERNAL_ERROR;
1294         }
1295     }
1296     return status;
1297 }
1298 
close()1299 Return<void> CameraDeviceSession::close()  {
1300     Mutex::Autolock _l(mStateLock);
1301     if (!mClosed) {
1302         {
1303             Mutex::Autolock _l(mInflightLock);
1304             if (!mInflightBuffers.empty()) {
1305                 ALOGE("%s: trying to close while there are still %zu inflight buffers!",
1306                         __FUNCTION__, mInflightBuffers.size());
1307             }
1308             if (!mInflightAETriggerOverrides.empty()) {
1309                 ALOGE("%s: trying to close while there are still %zu inflight "
1310                         "trigger overrides!", __FUNCTION__,
1311                         mInflightAETriggerOverrides.size());
1312             }
1313             if (!mInflightRawBoostPresent.empty()) {
1314                 ALOGE("%s: trying to close while there are still %zu inflight "
1315                         " RAW boost overrides!", __FUNCTION__,
1316                         mInflightRawBoostPresent.size());
1317             }
1318 
1319         }
1320 
1321         ATRACE_BEGIN("camera3->close");
1322         mDevice->common.close(&mDevice->common);
1323         ATRACE_END();
1324 
1325         // free all imported buffers
1326         Mutex::Autolock _l(mInflightLock);
1327         for(auto& pair : mCirculatingBuffers) {
1328             CirculatingBuffers& buffers = pair.second;
1329             for (auto& p2 : buffers) {
1330                 sHandleImporter.freeBuffer(p2.second);
1331             }
1332             buffers.clear();
1333         }
1334         mCirculatingBuffers.clear();
1335 
1336         mClosed = true;
1337     }
1338     return Void();
1339 }
1340 
getCapResultBufferId(const buffer_handle_t &,int)1341 uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t&, int) {
1342     // No need to fill in bufferId by default
1343     return BUFFER_ID_NO_BUFFER;
1344 }
1345 
constructCaptureResult(CaptureResult & result,const camera3_capture_result * hal_result)1346 status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result,
1347                                                  const camera3_capture_result *hal_result) {
1348     uint32_t frameNumber = hal_result->frame_number;
1349     bool hasInputBuf = (hal_result->input_buffer != nullptr);
1350     size_t numOutputBufs = hal_result->num_output_buffers;
1351     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
1352     if (numBufs > 0) {
1353         Mutex::Autolock _l(mInflightLock);
1354         if (hasInputBuf) {
1355             int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
1356             // validate if buffer is inflight
1357             auto key = std::make_pair(streamId, frameNumber);
1358             if (mInflightBuffers.count(key) != 1) {
1359                 ALOGE("%s: input buffer for stream %d frame %d is not inflight!",
1360                         __FUNCTION__, streamId, frameNumber);
1361                 return -EINVAL;
1362             }
1363         }
1364 
1365         for (size_t i = 0; i < numOutputBufs; i++) {
1366             int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
1367             // validate if buffer is inflight
1368             auto key = std::make_pair(streamId, frameNumber);
1369             if (mInflightBuffers.count(key) != 1) {
1370                 ALOGE("%s: output buffer for stream %d frame %d is not inflight!",
1371                         __FUNCTION__, streamId, frameNumber);
1372                 return -EINVAL;
1373             }
1374         }
1375     }
1376     // We don't need to validate/import fences here since we will be passing them to camera service
1377     // within the scope of this function
1378     result.frameNumber = frameNumber;
1379     result.fmqResultSize = 0;
1380     result.partialResult = hal_result->partial_result;
1381     convertToHidl(hal_result->result, &result.result);
1382     if (nullptr != hal_result->result) {
1383         bool resultOverriden = false;
1384         Mutex::Autolock _l(mInflightLock);
1385 
1386         // Derive some new keys for backward compatibility
1387         if (mDerivePostRawSensKey) {
1388             camera_metadata_ro_entry entry;
1389             if (find_camera_metadata_ro_entry(hal_result->result,
1390                     ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &entry) == 0) {
1391                 mInflightRawBoostPresent[frameNumber] = true;
1392             } else {
1393                 auto entry = mInflightRawBoostPresent.find(frameNumber);
1394                 if (mInflightRawBoostPresent.end() == entry) {
1395                     mInflightRawBoostPresent[frameNumber] = false;
1396                 }
1397             }
1398 
1399             if ((hal_result->partial_result == mNumPartialResults)) {
1400                 if (!mInflightRawBoostPresent[frameNumber]) {
1401                     if (!resultOverriden) {
1402                         mOverridenResult.clear();
1403                         mOverridenResult.append(hal_result->result);
1404                         resultOverriden = true;
1405                     }
1406                     int32_t defaultBoost[1] = {100};
1407                     mOverridenResult.update(
1408                             ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
1409                             defaultBoost, 1);
1410                 }
1411 
1412                 mInflightRawBoostPresent.erase(frameNumber);
1413             }
1414         }
1415 
1416         auto entry = mInflightAETriggerOverrides.find(frameNumber);
1417         if (mInflightAETriggerOverrides.end() != entry) {
1418             if (!resultOverriden) {
1419                 mOverridenResult.clear();
1420                 mOverridenResult.append(hal_result->result);
1421                 resultOverriden = true;
1422             }
1423             overrideResultForPrecaptureCancelLocked(entry->second,
1424                     &mOverridenResult);
1425             if (hal_result->partial_result == mNumPartialResults) {
1426                 mInflightAETriggerOverrides.erase(frameNumber);
1427             }
1428         }
1429 
1430         if (resultOverriden) {
1431             const camera_metadata_t *metaBuffer =
1432                     mOverridenResult.getAndLock();
1433             convertToHidl(metaBuffer, &result.result);
1434             mOverridenResult.unlock(metaBuffer);
1435         }
1436     }
1437     if (hasInputBuf) {
1438         result.inputBuffer.streamId =
1439                 static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
1440         result.inputBuffer.buffer = nullptr;
1441         result.inputBuffer.status = (BufferStatus) hal_result->input_buffer->status;
1442         // skip acquire fence since it's no use to camera service
1443         if (hal_result->input_buffer->release_fence != -1) {
1444             native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
1445             handle->data[0] = hal_result->input_buffer->release_fence;
1446             result.inputBuffer.releaseFence = handle;
1447         } else {
1448             result.inputBuffer.releaseFence = nullptr;
1449         }
1450     } else {
1451         result.inputBuffer.streamId = -1;
1452     }
1453 
1454     result.outputBuffers.resize(numOutputBufs);
1455     for (size_t i = 0; i < numOutputBufs; i++) {
1456         result.outputBuffers[i].streamId =
1457                 static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
1458         result.outputBuffers[i].buffer = nullptr;
1459         if (hal_result->output_buffers[i].buffer != nullptr) {
1460             result.outputBuffers[i].bufferId = getCapResultBufferId(
1461                     *(hal_result->output_buffers[i].buffer),
1462                     result.outputBuffers[i].streamId);
1463         } else {
1464             result.outputBuffers[i].bufferId = 0;
1465         }
1466 
1467         result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
1468         // skip acquire fence since it's of no use to camera service
1469         if (hal_result->output_buffers[i].release_fence != -1) {
1470             native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
1471             handle->data[0] = hal_result->output_buffers[i].release_fence;
1472             result.outputBuffers[i].releaseFence = handle;
1473         } else {
1474             result.outputBuffers[i].releaseFence = nullptr;
1475         }
1476     }
1477 
1478     // Free inflight record/fences.
1479     // Do this before call back to camera service because camera service might jump to
1480     // configure_streams right after the processCaptureResult call so we need to finish
1481     // updating inflight queues first
1482     if (numBufs > 0) {
1483         Mutex::Autolock _l(mInflightLock);
1484         if (hasInputBuf) {
1485             int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
1486             auto key = std::make_pair(streamId, frameNumber);
1487             mInflightBuffers.erase(key);
1488         }
1489 
1490         for (size_t i = 0; i < numOutputBufs; i++) {
1491             int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
1492             auto key = std::make_pair(streamId, frameNumber);
1493             mInflightBuffers.erase(key);
1494         }
1495 
1496         if (mInflightBuffers.empty()) {
1497             ALOGV("%s: inflight buffer queue is now empty!", __FUNCTION__);
1498         }
1499     }
1500     return OK;
1501 }
1502 
1503 // Static helper method to copy/shrink capture result metadata sent by HAL
sShrinkCaptureResult(camera3_capture_result * dst,const camera3_capture_result * src,std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> * mds,std::vector<const camera_metadata_t * > * physCamMdArray,bool handlePhysCam)1504 void CameraDeviceSession::sShrinkCaptureResult(
1505         camera3_capture_result* dst, const camera3_capture_result* src,
1506         std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
1507         std::vector<const camera_metadata_t*>* physCamMdArray,
1508         bool handlePhysCam) {
1509     *dst = *src;
1510     // Reserve maximum number of entries to avoid metadata re-allocation.
1511     mds->reserve(1 + (handlePhysCam ? src->num_physcam_metadata : 0));
1512     if (sShouldShrink(src->result)) {
1513         mds->emplace_back(sCreateCompactCopy(src->result));
1514         dst->result = mds->back().getAndLock();
1515     }
1516 
1517     if (handlePhysCam) {
1518         // First determine if we need to create new camera_metadata_t* array
1519         bool needShrink = false;
1520         for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
1521             if (sShouldShrink(src->physcam_metadata[i])) {
1522                 needShrink = true;
1523             }
1524         }
1525 
1526         if (!needShrink) return;
1527 
1528         physCamMdArray->reserve(src->num_physcam_metadata);
1529         dst->physcam_metadata = physCamMdArray->data();
1530         for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
1531             if (sShouldShrink(src->physcam_metadata[i])) {
1532                 mds->emplace_back(sCreateCompactCopy(src->physcam_metadata[i]));
1533                 dst->physcam_metadata[i] = mds->back().getAndLock();
1534             } else {
1535                 dst->physcam_metadata[i] = src->physcam_metadata[i];
1536             }
1537         }
1538     }
1539 }
1540 
sShouldShrink(const camera_metadata_t * md)1541 bool CameraDeviceSession::sShouldShrink(const camera_metadata_t* md) {
1542     size_t compactSize = get_camera_metadata_compact_size(md);
1543     size_t totalSize = get_camera_metadata_size(md);
1544     if (totalSize >= compactSize + METADATA_SHRINK_ABS_THRESHOLD &&
1545             totalSize >= compactSize * METADATA_SHRINK_REL_THRESHOLD) {
1546         ALOGV("Camera metadata should be shrunk from %zu to %zu", totalSize, compactSize);
1547         return true;
1548     }
1549     return false;
1550 }
1551 
sCreateCompactCopy(const camera_metadata_t * src)1552 camera_metadata_t* CameraDeviceSession::sCreateCompactCopy(const camera_metadata_t* src) {
1553     size_t compactSize = get_camera_metadata_compact_size(src);
1554     void* buffer = calloc(1, compactSize);
1555     if (buffer == nullptr) {
1556         ALOGE("%s: Allocating %zu bytes failed", __FUNCTION__, compactSize);
1557     }
1558     return copy_camera_metadata(buffer, compactSize, src);
1559 }
1560 
1561 /**
1562  * Static callback forwarding methods from HAL to instance
1563  */
sProcessCaptureResult(const camera3_callback_ops * cb,const camera3_capture_result * hal_result)1564 void CameraDeviceSession::sProcessCaptureResult(
1565         const camera3_callback_ops *cb,
1566         const camera3_capture_result *hal_result) {
1567     CameraDeviceSession *d =
1568             const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
1569 
1570     CaptureResult result = {};
1571     camera3_capture_result shadowResult;
1572     bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
1573     std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
1574     std::vector<const camera_metadata_t*> physCamMdArray;
1575     sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
1576 
1577     status_t ret = d->constructCaptureResult(result, &shadowResult);
1578     if (ret == OK) {
1579         d->mResultBatcher.processCaptureResult(result);
1580     }
1581 }
1582 
sNotify(const camera3_callback_ops * cb,const camera3_notify_msg * msg)1583 void CameraDeviceSession::sNotify(
1584         const camera3_callback_ops *cb,
1585         const camera3_notify_msg *msg) {
1586     CameraDeviceSession *d =
1587             const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
1588     NotifyMsg hidlMsg;
1589     convertToHidl(msg, &hidlMsg);
1590 
1591     if (hidlMsg.type == (MsgType) CAMERA3_MSG_ERROR &&
1592             hidlMsg.msg.error.errorStreamId != -1) {
1593         if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
1594             ALOGE("%s: unknown stream ID %d reports an error!",
1595                     __FUNCTION__, hidlMsg.msg.error.errorStreamId);
1596             return;
1597         }
1598     }
1599 
1600     if (static_cast<camera3_msg_type_t>(hidlMsg.type) == CAMERA3_MSG_ERROR) {
1601         switch (hidlMsg.msg.error.errorCode) {
1602             case ErrorCode::ERROR_DEVICE:
1603             case ErrorCode::ERROR_REQUEST:
1604             case ErrorCode::ERROR_RESULT: {
1605                 Mutex::Autolock _l(d->mInflightLock);
1606                 auto entry = d->mInflightAETriggerOverrides.find(
1607                         hidlMsg.msg.error.frameNumber);
1608                 if (d->mInflightAETriggerOverrides.end() != entry) {
1609                     d->mInflightAETriggerOverrides.erase(
1610                             hidlMsg.msg.error.frameNumber);
1611                 }
1612 
1613                 auto boostEntry = d->mInflightRawBoostPresent.find(
1614                         hidlMsg.msg.error.frameNumber);
1615                 if (d->mInflightRawBoostPresent.end() != boostEntry) {
1616                     d->mInflightRawBoostPresent.erase(
1617                             hidlMsg.msg.error.frameNumber);
1618                 }
1619 
1620             }
1621                 break;
1622             case ErrorCode::ERROR_BUFFER:
1623             default:
1624                 break;
1625         }
1626 
1627     }
1628 
1629     d->mResultBatcher.notify(hidlMsg);
1630 }
1631 
1632 } // namespace implementation
1633 }  // namespace V3_2
1634 }  // namespace device
1635 }  // namespace camera
1636 }  // namespace hardware
1637 }  // namespace android
1638