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