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
26namespace android {
27namespace hardware {
28namespace camera {
29namespace device {
30namespace V3_2 {
31namespace implementation {
32
33// Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer.
34static 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.
36static constexpr size_t CAMERA_RESULT_METADATA_QUEUE_SIZE  = 1 << 20 /* 1MB */;
37
38HandleImporter CameraDeviceSession::sHandleImporter;
39const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
40
41CameraDeviceSession::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
78bool 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
109CameraDeviceSession::~CameraDeviceSession() {
110    if (!isClosed()) {
111        ALOGE("CameraDeviceSession deleted before close!");
112        close();
113    }
114}
115
116bool CameraDeviceSession::isClosed() {
117    Mutex::Autolock _l(mStateLock);
118    return mClosed;
119}
120
121Status 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
134void 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
144void 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 */
157bool 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 */
204void 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
221Status 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
295void 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
302CameraDeviceSession::ResultBatcher::ResultBatcher(
303        const sp<ICameraDeviceCallback>& callback) : mCallback(callback) {};
304
305bool 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
320void CameraDeviceSession::ResultBatcher::setNumPartialResults(uint32_t n) {
321    Mutex::Autolock _l(mLock);
322    mNumPartialResults = n;
323}
324
325void CameraDeviceSession::ResultBatcher::setBatchedStreams(
326        const std::vector<int>& streamsToBatch) {
327    Mutex::Autolock _l(mLock);
328    mStreamsToBatch = streamsToBatch;
329}
330
331void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q) {
332    Mutex::Autolock _l(mLock);
333    mResultMetadataQueue = q;
334}
335
336void 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
350std::pair<int, std::shared_ptr<CameraDeviceSession::ResultBatcher::InflightBatch>>
351CameraDeviceSession::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
372void 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
390void 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
401void 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
421void 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
432void 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
444void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch) {
445    sendBatchBuffersLocked(batch, mStreamsToBatch);
446}
447
448void 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
525void 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
564void CameraDeviceSession::ResultBatcher::notifySingleMsg(NotifyMsg& msg) {
565    mCallback->notify({msg});
566    return;
567}
568
569void 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
630void 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
657void 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
666void 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.
738Return<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 */
780android_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
804Return<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'
933void 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
941void 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
961Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue(
962    getCaptureRequestMetadataQueue_cb _hidl_cb) {
963    _hidl_cb(*mRequestMetadataQueue->getDesc());
964    return Void();
965}
966
967Return<void> CameraDeviceSession::getCaptureResultMetadataQueue(
968    getCaptureResultMetadataQueue_cb _hidl_cb) {
969    _hidl_cb(*mResultMetadataQueue->getDesc());
970    return Void();
971}
972
973Return<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
996Status 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
1108Return<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
1120Return<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 */
1162void 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
1317void 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