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