1/*
2 * Copyright (C) 2017 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#define LOG_TAG "CameraHardwareInterface"
17//#define LOG_NDEBUG 0
18
19#include <inttypes.h>
20#include <media/hardware/HardwareAPI.h> // For VideoNativeHandleMetadata
21#include "CameraHardwareInterface.h"
22
23namespace android {
24
25using namespace hardware::camera::device::V1_0;
26using namespace hardware::camera::common::V1_0;
27using hardware::hidl_handle;
28
29CameraHardwareInterface::~CameraHardwareInterface()
30{
31    ALOGI("Destroying camera %s", mName.string());
32    if (mHidlDevice != nullptr) {
33        mHidlDevice->close();
34        mHidlDevice.clear();
35        cleanupCirculatingBuffers();
36    }
37}
38
39status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
40    ALOGI("Opening camera %s", mName.string());
41
42    status_t ret = manager->openSession(mName.string(), this, &mHidlDevice);
43    if (ret != OK) {
44        ALOGE("%s: openSession failed! %s (%d)", __FUNCTION__, strerror(-ret), ret);
45    }
46    return ret;
47}
48
49status_t CameraHardwareInterface::setPreviewScalingMode(int scalingMode)
50{
51    int rc = OK;
52    mPreviewScalingMode = scalingMode;
53    if (mPreviewWindow != nullptr) {
54        rc = native_window_set_scaling_mode(mPreviewWindow.get(),
55                scalingMode);
56    }
57    return rc;
58}
59
60status_t CameraHardwareInterface::setPreviewTransform(int transform) {
61    int rc = OK;
62    mPreviewTransform = transform;
63    if (mPreviewWindow != nullptr) {
64        rc = native_window_set_buffers_transform(mPreviewWindow.get(),
65                mPreviewTransform);
66    }
67    return rc;
68}
69
70/**
71 * Implementation of android::hardware::camera::device::V1_0::ICameraDeviceCallback
72 */
73hardware::Return<void> CameraHardwareInterface::notifyCallback(
74        NotifyCallbackMsg msgType, int32_t ext1, int32_t ext2) {
75    sNotifyCb((int32_t) msgType, ext1, ext2, (void*) this);
76    return hardware::Void();
77}
78
79hardware::Return<uint32_t> CameraHardwareInterface::registerMemory(
80        const hardware::hidl_handle& descriptor,
81        uint32_t bufferSize, uint32_t bufferCount) {
82    if (descriptor->numFds != 1) {
83        ALOGE("%s: camera memory descriptor has numFds %d (expect 1)",
84                __FUNCTION__, descriptor->numFds);
85        return 0;
86    }
87    if (descriptor->data[0] < 0) {
88        ALOGE("%s: camera memory descriptor has FD %d (expect >= 0)",
89                __FUNCTION__, descriptor->data[0]);
90        return 0;
91    }
92
93    camera_memory_t* mem = sGetMemory(descriptor->data[0], bufferSize, bufferCount, this);
94    sp<CameraHeapMemory> camMem(static_cast<CameraHeapMemory *>(mem->handle));
95    int memPoolId = camMem->mHeap->getHeapID();
96    if (memPoolId < 0) {
97        ALOGE("%s: CameraHeapMemory has FD %d (expect >= 0)", __FUNCTION__, memPoolId);
98        return 0;
99    }
100    std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
101    mHidlMemPoolMap.insert(std::make_pair(memPoolId, mem));
102    return memPoolId;
103}
104
105hardware::Return<void> CameraHardwareInterface::unregisterMemory(uint32_t memId) {
106    camera_memory_t* mem = nullptr;
107    {
108        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
109        if (mHidlMemPoolMap.count(memId) == 0) {
110            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
111            return hardware::Void();
112        }
113        mem = mHidlMemPoolMap.at(memId);
114        mHidlMemPoolMap.erase(memId);
115    }
116    sPutMemory(mem);
117    return hardware::Void();
118}
119
120hardware::Return<void> CameraHardwareInterface::dataCallback(
121        DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
122        const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) {
123    camera_memory_t* mem = nullptr;
124    {
125        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
126        if (mHidlMemPoolMap.count(data) == 0) {
127            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
128            return hardware::Void();
129        }
130        mem = mHidlMemPoolMap.at(data);
131    }
132    camera_frame_metadata_t md;
133    md.number_of_faces = metadata.faces.size();
134    md.faces = (camera_face_t*) metadata.faces.data();
135    sDataCb((int32_t) msgType, mem, bufferIndex, &md, this);
136    return hardware::Void();
137}
138
139hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
140        DataCallbackMsg msgType, uint32_t data,
141        uint32_t bufferIndex, int64_t timestamp) {
142    camera_memory_t* mem = nullptr;
143    {
144        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
145        if (mHidlMemPoolMap.count(data) == 0) {
146            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
147            return hardware::Void();
148        }
149        mem = mHidlMemPoolMap.at(data);
150    }
151    sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
152    return hardware::Void();
153}
154
155hardware::Return<void> CameraHardwareInterface::handleCallbackTimestamp(
156        DataCallbackMsg msgType, const hidl_handle& frameData, uint32_t data,
157        uint32_t bufferIndex, int64_t timestamp) {
158    camera_memory_t* mem = nullptr;
159    {
160        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
161        if (mHidlMemPoolMap.count(data) == 0) {
162            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
163            return hardware::Void();
164        }
165        mem = mHidlMemPoolMap.at(data);
166    }
167    sp<CameraHeapMemory> heapMem(static_cast<CameraHeapMemory *>(mem->handle));
168    VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
169            heapMem->mBuffers[bufferIndex]->pointer();
170    md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
171    sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
172    return hardware::Void();
173}
174
175hardware::Return<void> CameraHardwareInterface::handleCallbackTimestampBatch(
176        DataCallbackMsg msgType,
177        const hardware::hidl_vec<hardware::camera::device::V1_0::HandleTimestampMessage>& messages) {
178    std::vector<android::HandleTimestampMessage> msgs;
179    msgs.reserve(messages.size());
180    {
181        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
182        for (const auto& hidl_msg : messages) {
183            if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
184                ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
185                return hardware::Void();
186            }
187            sp<CameraHeapMemory> mem(
188                    static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
189
190            if (hidl_msg.bufferIndex >= mem->mNumBufs) {
191                ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
192                     hidl_msg.bufferIndex, mem->mNumBufs);
193                return hardware::Void();
194            }
195            VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
196                    mem->mBuffers[hidl_msg.bufferIndex]->pointer();
197            md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
198
199            msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
200        }
201    }
202    mDataCbTimestampBatch((int32_t) msgType, msgs, mCbUser);
203    return hardware::Void();
204}
205
206std::pair<bool, uint64_t> CameraHardwareInterface::getBufferId(
207        ANativeWindowBuffer* anb) {
208    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
209
210    buffer_handle_t& buf = anb->handle;
211    auto it = mBufferIdMap.find(buf);
212    if (it == mBufferIdMap.end()) {
213        uint64_t bufId = mNextBufferId++;
214        mBufferIdMap[buf] = bufId;
215        mReversedBufMap[bufId] = anb;
216        return std::make_pair(true, bufId);
217    } else {
218        return std::make_pair(false, it->second);
219    }
220}
221
222void CameraHardwareInterface::cleanupCirculatingBuffers() {
223    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
224    mBufferIdMap.clear();
225    mReversedBufMap.clear();
226}
227
228hardware::Return<void>
229CameraHardwareInterface::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
230    ANativeWindow *a = mPreviewWindow.get();
231    if (a == nullptr) {
232        ALOGE("%s: preview window is null", __FUNCTION__);
233        return hardware::Void();
234    }
235    ANativeWindowBuffer* anb;
236    int rc = native_window_dequeue_buffer_and_wait(a, &anb);
237    Status s = Status::INTERNAL_ERROR;
238    uint64_t bufferId = 0;
239    uint32_t stride = 0;
240    hidl_handle buf = nullptr;
241    if (rc == OK) {
242        s = Status::OK;
243        auto pair = getBufferId(anb);
244        buf = (pair.first) ? anb->handle : nullptr;
245        bufferId = pair.second;
246        stride = anb->stride;
247    }
248
249    _hidl_cb(s, bufferId, buf, stride);
250    return hardware::Void();
251}
252
253hardware::Return<Status>
254CameraHardwareInterface::enqueueBuffer(uint64_t bufferId) {
255    ANativeWindow *a = mPreviewWindow.get();
256    if (a == nullptr) {
257        ALOGE("%s: preview window is null", __FUNCTION__);
258        return Status::INTERNAL_ERROR;
259    }
260    if (mReversedBufMap.count(bufferId) == 0) {
261        ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
262        return Status::ILLEGAL_ARGUMENT;
263    }
264    int rc = a->queueBuffer(a, mReversedBufMap.at(bufferId), -1);
265    if (rc == 0) {
266        return Status::OK;
267    }
268    return Status::INTERNAL_ERROR;
269}
270
271hardware::Return<Status>
272CameraHardwareInterface::cancelBuffer(uint64_t bufferId) {
273    ANativeWindow *a = mPreviewWindow.get();
274    if (a == nullptr) {
275        ALOGE("%s: preview window is null", __FUNCTION__);
276        return Status::INTERNAL_ERROR;
277    }
278    if (mReversedBufMap.count(bufferId) == 0) {
279        ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
280        return Status::ILLEGAL_ARGUMENT;
281    }
282    int rc = a->cancelBuffer(a, mReversedBufMap.at(bufferId), -1);
283    if (rc == 0) {
284        return Status::OK;
285    }
286    return Status::INTERNAL_ERROR;
287}
288
289hardware::Return<Status>
290CameraHardwareInterface::setBufferCount(uint32_t count) {
291    ANativeWindow *a = mPreviewWindow.get();
292    if (a != nullptr) {
293        // Workaround for b/27039775
294        // Previously, setting the buffer count would reset the buffer
295        // queue's flag that allows for all buffers to be dequeued on the
296        // producer side, instead of just the producer's declared max count,
297        // if no filled buffers have yet been queued by the producer.  This
298        // reset no longer happens, but some HALs depend on this behavior,
299        // so it needs to be maintained for HAL backwards compatibility.
300        // Simulate the prior behavior by disconnecting/reconnecting to the
301        // window and setting the values again.  This has the drawback of
302        // actually causing memory reallocation, which may not have happened
303        // in the past.
304        native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
305        native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
306        if (mPreviewScalingMode != NOT_SET) {
307            native_window_set_scaling_mode(a, mPreviewScalingMode);
308        }
309        if (mPreviewTransform != NOT_SET) {
310            native_window_set_buffers_transform(a, mPreviewTransform);
311        }
312        if (mPreviewWidth != NOT_SET) {
313            native_window_set_buffers_dimensions(a,
314                    mPreviewWidth, mPreviewHeight);
315            native_window_set_buffers_format(a, mPreviewFormat);
316        }
317        if (mPreviewUsage != 0) {
318            native_window_set_usage(a, mPreviewUsage);
319        }
320        if (mPreviewSwapInterval != NOT_SET) {
321            a->setSwapInterval(a, mPreviewSwapInterval);
322        }
323        if (mPreviewCrop.left != NOT_SET) {
324            native_window_set_crop(a, &(mPreviewCrop));
325        }
326    }
327    int rc = native_window_set_buffer_count(a, count);
328    if (rc == OK) {
329        cleanupCirculatingBuffers();
330        return Status::OK;
331    }
332    return Status::INTERNAL_ERROR;
333}
334
335hardware::Return<Status>
336CameraHardwareInterface::setBuffersGeometry(
337        uint32_t w, uint32_t h, hardware::graphics::common::V1_0::PixelFormat format) {
338    Status s = Status::INTERNAL_ERROR;
339    ANativeWindow *a = mPreviewWindow.get();
340    if (a == nullptr) {
341        ALOGE("%s: preview window is null", __FUNCTION__);
342        return s;
343    }
344    mPreviewWidth = w;
345    mPreviewHeight = h;
346    mPreviewFormat = (int) format;
347    int rc = native_window_set_buffers_dimensions(a, w, h);
348    if (rc == OK) {
349        rc = native_window_set_buffers_format(a, mPreviewFormat);
350    }
351    if (rc == OK) {
352        cleanupCirculatingBuffers();
353        s = Status::OK;
354    }
355    return s;
356}
357
358hardware::Return<Status>
359CameraHardwareInterface::setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) {
360    Status s = Status::INTERNAL_ERROR;
361    ANativeWindow *a = mPreviewWindow.get();
362    if (a == nullptr) {
363        ALOGE("%s: preview window is null", __FUNCTION__);
364        return s;
365    }
366    mPreviewCrop.left = left;
367    mPreviewCrop.top = top;
368    mPreviewCrop.right = right;
369    mPreviewCrop.bottom = bottom;
370    int rc = native_window_set_crop(a, &mPreviewCrop);
371    if (rc == OK) {
372        s = Status::OK;
373    }
374    return s;
375}
376
377hardware::Return<Status>
378CameraHardwareInterface::setUsage(hardware::graphics::common::V1_0::BufferUsage usage) {
379    Status s = Status::INTERNAL_ERROR;
380    ANativeWindow *a = mPreviewWindow.get();
381    if (a == nullptr) {
382        ALOGE("%s: preview window is null", __FUNCTION__);
383        return s;
384    }
385    mPreviewUsage = static_cast<uint64_t> (usage);
386    int rc = native_window_set_usage(a, mPreviewUsage);
387    if (rc == OK) {
388        cleanupCirculatingBuffers();
389        s = Status::OK;
390    }
391    return s;
392}
393
394hardware::Return<Status>
395CameraHardwareInterface::setSwapInterval(int32_t interval) {
396    Status s = Status::INTERNAL_ERROR;
397    ANativeWindow *a = mPreviewWindow.get();
398    if (a == nullptr) {
399        ALOGE("%s: preview window is null", __FUNCTION__);
400        return s;
401    }
402    mPreviewSwapInterval = interval;
403    int rc = a->setSwapInterval(a, interval);
404    if (rc == OK) {
405        s = Status::OK;
406    }
407    return s;
408}
409
410hardware::Return<void>
411CameraHardwareInterface::getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb) {
412    ANativeWindow *a = mPreviewWindow.get();
413    if (a == nullptr) {
414        ALOGE("%s: preview window is null", __FUNCTION__);
415        return hardware::Void();
416    }
417    int count = 0;
418    int rc = a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
419    Status s = Status::INTERNAL_ERROR;
420    if (rc == OK) {
421        s = Status::OK;
422    }
423    _hidl_cb(s, count);
424    return hardware::Void();
425}
426
427hardware::Return<Status>
428CameraHardwareInterface::setTimestamp(int64_t timestamp) {
429    Status s = Status::INTERNAL_ERROR;
430    ANativeWindow *a = mPreviewWindow.get();
431    if (a == nullptr) {
432        ALOGE("%s: preview window is null", __FUNCTION__);
433        return s;
434    }
435    int rc = native_window_set_buffers_timestamp(a, timestamp);
436    if (rc == OK) {
437        s = Status::OK;
438    }
439    return s;
440}
441
442status_t CameraHardwareInterface::setPreviewWindow(const sp<ANativeWindow>& buf)
443{
444    ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
445    if (CC_LIKELY(mHidlDevice != nullptr)) {
446        mPreviewWindow = buf;
447        if (buf != nullptr) {
448            if (mPreviewScalingMode != NOT_SET) {
449                setPreviewScalingMode(mPreviewScalingMode);
450            }
451            if (mPreviewTransform != NOT_SET) {
452                setPreviewTransform(mPreviewTransform);
453            }
454        }
455        return CameraProviderManager::mapToStatusT(
456                mHidlDevice->setPreviewWindow(buf.get() ? this : nullptr));
457    }
458    return INVALID_OPERATION;
459}
460
461void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
462        data_callback data_cb,
463        data_callback_timestamp data_cb_timestamp,
464        data_callback_timestamp_batch data_cb_timestamp_batch,
465        void* user)
466{
467    mNotifyCb = notify_cb;
468    mDataCb = data_cb;
469    mDataCbTimestamp = data_cb_timestamp;
470    mDataCbTimestampBatch = data_cb_timestamp_batch;
471    mCbUser = user;
472
473    ALOGV("%s(%s)", __FUNCTION__, mName.string());
474}
475
476void CameraHardwareInterface::enableMsgType(int32_t msgType)
477{
478    ALOGV("%s(%s)", __FUNCTION__, mName.string());
479    if (CC_LIKELY(mHidlDevice != nullptr)) {
480        mHidlDevice->enableMsgType(msgType);
481    }
482}
483
484void CameraHardwareInterface::disableMsgType(int32_t msgType)
485{
486    ALOGV("%s(%s)", __FUNCTION__, mName.string());
487    if (CC_LIKELY(mHidlDevice != nullptr)) {
488        mHidlDevice->disableMsgType(msgType);
489    }
490}
491
492int CameraHardwareInterface::msgTypeEnabled(int32_t msgType)
493{
494    ALOGV("%s(%s)", __FUNCTION__, mName.string());
495    if (CC_LIKELY(mHidlDevice != nullptr)) {
496        return mHidlDevice->msgTypeEnabled(msgType);
497    }
498    return false;
499}
500
501status_t CameraHardwareInterface::startPreview()
502{
503    ALOGV("%s(%s)", __FUNCTION__, mName.string());
504    if (CC_LIKELY(mHidlDevice != nullptr)) {
505        return CameraProviderManager::mapToStatusT(
506                mHidlDevice->startPreview());
507    }
508    return INVALID_OPERATION;
509}
510
511void CameraHardwareInterface::stopPreview()
512{
513    ALOGV("%s(%s)", __FUNCTION__, mName.string());
514    if (CC_LIKELY(mHidlDevice != nullptr)) {
515        mHidlDevice->stopPreview();
516    }
517}
518
519int CameraHardwareInterface::previewEnabled()
520{
521    ALOGV("%s(%s)", __FUNCTION__, mName.string());
522    if (CC_LIKELY(mHidlDevice != nullptr)) {
523        return mHidlDevice->previewEnabled();
524    }
525    return false;
526}
527
528status_t CameraHardwareInterface::storeMetaDataInBuffers(int enable)
529{
530    ALOGV("%s(%s)", __FUNCTION__, mName.string());
531    if (CC_LIKELY(mHidlDevice != nullptr)) {
532        return CameraProviderManager::mapToStatusT(
533                mHidlDevice->storeMetaDataInBuffers(enable));
534    }
535    return enable ? INVALID_OPERATION: OK;
536}
537
538status_t CameraHardwareInterface::startRecording()
539{
540    ALOGV("%s(%s)", __FUNCTION__, mName.string());
541    if (CC_LIKELY(mHidlDevice != nullptr)) {
542        return CameraProviderManager::mapToStatusT(
543                mHidlDevice->startRecording());
544    }
545    return INVALID_OPERATION;
546}
547
548/**
549 * Stop a previously started recording.
550 */
551void CameraHardwareInterface::stopRecording()
552{
553    ALOGV("%s(%s)", __FUNCTION__, mName.string());
554    if (CC_LIKELY(mHidlDevice != nullptr)) {
555        mHidlDevice->stopRecording();
556    }
557}
558
559/**
560 * Returns true if recording is enabled.
561 */
562int CameraHardwareInterface::recordingEnabled()
563{
564    ALOGV("%s(%s)", __FUNCTION__, mName.string());
565    if (CC_LIKELY(mHidlDevice != nullptr)) {
566        return mHidlDevice->recordingEnabled();
567    }
568    return false;
569}
570
571void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
572{
573    ALOGV("%s(%s)", __FUNCTION__, mName.string());
574    ssize_t offset;
575    size_t size;
576    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
577    int heapId = heap->getHeapID();
578    int bufferIndex = offset / size;
579    if (CC_LIKELY(mHidlDevice != nullptr)) {
580        if (size == sizeof(VideoNativeHandleMetadata)) {
581            VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
582            // Caching the handle here because md->pHandle will be subject to HAL's edit
583            native_handle_t* nh = md->pHandle;
584            hidl_handle frame = nh;
585            mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
586            native_handle_close(nh);
587            native_handle_delete(nh);
588        } else {
589            mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
590        }
591    }
592}
593
594void CameraHardwareInterface::releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames)
595{
596    ALOGV("%s(%s)", __FUNCTION__, mName.string());
597    size_t n = frames.size();
598    std::vector<VideoFrameMessage> msgs;
599    msgs.reserve(n);
600    for (auto& mem : frames) {
601        if (CC_LIKELY(mHidlDevice != nullptr)) {
602            ssize_t offset;
603            size_t size;
604            sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
605            if (size == sizeof(VideoNativeHandleMetadata)) {
606                uint32_t heapId = heap->getHeapID();
607                uint32_t bufferIndex = offset / size;
608                VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
609                // Caching the handle here because md->pHandle will be subject to HAL's edit
610                native_handle_t* nh = md->pHandle;
611                VideoFrameMessage msg;
612                msgs.push_back({nh, heapId, bufferIndex});
613            } else {
614                ALOGE("%s only supports VideoNativeHandleMetadata mode", __FUNCTION__);
615                return;
616            }
617        }
618    }
619
620    mHidlDevice->releaseRecordingFrameHandleBatch(msgs);
621
622    for (auto& msg : msgs) {
623        native_handle_t* nh = const_cast<native_handle_t*>(msg.frameData.getNativeHandle());
624        native_handle_close(nh);
625        native_handle_delete(nh);
626    }
627}
628
629status_t CameraHardwareInterface::autoFocus()
630{
631    ALOGV("%s(%s)", __FUNCTION__, mName.string());
632    if (CC_LIKELY(mHidlDevice != nullptr)) {
633        return CameraProviderManager::mapToStatusT(
634                mHidlDevice->autoFocus());
635    }
636    return INVALID_OPERATION;
637}
638
639status_t CameraHardwareInterface::cancelAutoFocus()
640{
641    ALOGV("%s(%s)", __FUNCTION__, mName.string());
642    if (CC_LIKELY(mHidlDevice != nullptr)) {
643        return CameraProviderManager::mapToStatusT(
644                mHidlDevice->cancelAutoFocus());
645    }
646    return INVALID_OPERATION;
647}
648
649status_t CameraHardwareInterface::takePicture()
650{
651    ALOGV("%s(%s)", __FUNCTION__, mName.string());
652    if (CC_LIKELY(mHidlDevice != nullptr)) {
653        return CameraProviderManager::mapToStatusT(
654                mHidlDevice->takePicture());
655    }
656    return INVALID_OPERATION;
657}
658
659status_t CameraHardwareInterface::cancelPicture()
660{
661    ALOGV("%s(%s)", __FUNCTION__, mName.string());
662    if (CC_LIKELY(mHidlDevice != nullptr)) {
663        return CameraProviderManager::mapToStatusT(
664                mHidlDevice->cancelPicture());
665    }
666    return INVALID_OPERATION;
667}
668
669status_t CameraHardwareInterface::setParameters(const CameraParameters &params)
670{
671    ALOGV("%s(%s)", __FUNCTION__, mName.string());
672    if (CC_LIKELY(mHidlDevice != nullptr)) {
673        return CameraProviderManager::mapToStatusT(
674                mHidlDevice->setParameters(params.flatten().string()));
675    }
676    return INVALID_OPERATION;
677}
678
679CameraParameters CameraHardwareInterface::getParameters() const
680{
681    ALOGV("%s(%s)", __FUNCTION__, mName.string());
682    CameraParameters parms;
683    if (CC_LIKELY(mHidlDevice != nullptr)) {
684        hardware::hidl_string outParam;
685        mHidlDevice->getParameters(
686                [&outParam](const auto& outStr) {
687                    outParam = outStr;
688                });
689        String8 tmp(outParam.c_str());
690        parms.unflatten(tmp);
691    }
692    return parms;
693}
694
695status_t CameraHardwareInterface::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
696{
697    ALOGV("%s(%s)", __FUNCTION__, mName.string());
698    if (CC_LIKELY(mHidlDevice != nullptr)) {
699        return CameraProviderManager::mapToStatusT(
700                mHidlDevice->sendCommand((CommandType) cmd, arg1, arg2));
701    }
702    return INVALID_OPERATION;
703}
704
705/**
706 * Release the hardware resources owned by this object.  Note that this is
707 * *not* done in the destructor.
708 */
709void CameraHardwareInterface::release() {
710    ALOGV("%s(%s)", __FUNCTION__, mName.string());
711    if (CC_LIKELY(mHidlDevice != nullptr)) {
712        mHidlDevice->close();
713        mHidlDevice.clear();
714    }
715}
716
717/**
718 * Dump state of the camera hardware
719 */
720status_t CameraHardwareInterface::dump(int fd, const Vector<String16>& /*args*/) const
721{
722    ALOGV("%s(%s)", __FUNCTION__, mName.string());
723    if (CC_LIKELY(mHidlDevice != nullptr)) {
724        native_handle_t* handle = native_handle_create(1,0);
725        handle->data[0] = fd;
726        Status s = mHidlDevice->dumpState(handle);
727        native_handle_delete(handle);
728        return CameraProviderManager::mapToStatusT(s);
729    }
730    return OK; // It's fine if the HAL doesn't implement dump()
731}
732
733void CameraHardwareInterface::sNotifyCb(int32_t msg_type, int32_t ext1,
734                        int32_t ext2, void *user)
735{
736    ALOGV("%s", __FUNCTION__);
737    CameraHardwareInterface *object =
738            static_cast<CameraHardwareInterface *>(user);
739    object->mNotifyCb(msg_type, ext1, ext2, object->mCbUser);
740}
741
742void CameraHardwareInterface::sDataCb(int32_t msg_type,
743                      const camera_memory_t *data, unsigned int index,
744                      camera_frame_metadata_t *metadata,
745                      void *user)
746{
747    ALOGV("%s", __FUNCTION__);
748    CameraHardwareInterface *object =
749            static_cast<CameraHardwareInterface *>(user);
750    sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
751    if (index >= mem->mNumBufs) {
752        ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
753             index, mem->mNumBufs);
754        return;
755    }
756    object->mDataCb(msg_type, mem->mBuffers[index], metadata, object->mCbUser);
757}
758
759void CameraHardwareInterface::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
760                         const camera_memory_t *data, unsigned index,
761                         void *user)
762{
763    ALOGV("%s", __FUNCTION__);
764    CameraHardwareInterface *object =
765            static_cast<CameraHardwareInterface *>(user);
766    // Start refcounting the heap object from here on.  When the clients
767    // drop all references, it will be destroyed (as well as the enclosed
768    // MemoryHeapBase.
769    sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
770    if (index >= mem->mNumBufs) {
771        ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
772             index, mem->mNumBufs);
773        return;
774    }
775    object->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], object->mCbUser);
776}
777
778camera_memory_t* CameraHardwareInterface::sGetMemory(
779        int fd, size_t buf_size, uint_t num_bufs,
780        void *user __attribute__((unused)))
781{
782    CameraHeapMemory *mem;
783    if (fd < 0) {
784        mem = new CameraHeapMemory(buf_size, num_bufs);
785    } else {
786        mem = new CameraHeapMemory(fd, buf_size, num_bufs);
787    }
788    mem->incStrong(mem);
789    return &mem->handle;
790}
791
792void CameraHardwareInterface::sPutMemory(camera_memory_t *data)
793{
794    if (!data) {
795        return;
796    }
797
798    CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
799    mem->decStrong(mem);
800}
801
802}; // namespace android
803