1248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh/*
2248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh * Copyright (C) 2017 The Android Open Source Project
3248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh *
4248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh * Licensed under the Apache License, Version 2.0 (the "License");
5248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh * you may not use this file except in compliance with the License.
6248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh * You may obtain a copy of the License at
7248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh *
8248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh *      http://www.apache.org/licenses/LICENSE-2.0
9248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh *
10248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh * Unless required by applicable law or agreed to in writing, software
11248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh * distributed under the License is distributed on an "AS IS" BASIS,
12248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh * See the License for the specific language governing permissions and
14248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh * limitations under the License.
15248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh */
16248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
17248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh#define LOG_TAG "CamDev@1.0-impl"
18248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh#include <hardware/camera.h>
19248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh#include <hardware/gralloc1.h>
2012b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh#include <hidlmemory/mapping.h>
214e7a3077309d33a21b08e9380573019cc7a8cffbSteven Moreland#include <log/log.h>
22248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh#include <utils/Trace.h>
23248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
241ee279df205218fb7372baf031fb93d2a0d6a821Yin-Chia Yeh#include <media/hardware/HardwareAPI.h> // For VideoNativeHandleMetadata
25248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh#include "CameraDevice_1_0.h"
26248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
27248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehnamespace android {
28248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehnamespace hardware {
29248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehnamespace camera {
30248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehnamespace device {
31248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehnamespace V1_0 {
32248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehnamespace implementation {
33248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
3479d13ff0f5cd3c4242445baf5b2f01a52f0ed06fChia-I Wuusing ::android::hardware::graphics::common::V1_0::BufferUsage;
35248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehusing ::android::hardware::graphics::common::V1_0::PixelFormat;
36248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
37519c1675c3a489677354e8a3d2666bf1b41df6f0Yin-Chia YehHandleImporter CameraDevice::sHandleImporter;
38248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
39248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehStatus CameraDevice::getHidlStatus(const int& status) {
40248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    switch (status) {
41248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case 0: return Status::OK;
42248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case -ENOSYS: return Status::OPERATION_NOT_SUPPORTED;
43248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case -EBUSY : return Status::CAMERA_IN_USE;
44248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case -EUSERS: return Status::MAX_CAMERAS_IN_USE;
45248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case -ENODEV: return Status::INTERNAL_ERROR;
46248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case -EINVAL: return Status::ILLEGAL_ARGUMENT;
47248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        default:
48248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
49248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return Status::INTERNAL_ERROR;
50248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
51248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
52248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
53248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehstatus_t CameraDevice::getStatusT(const Status& s)  {
54248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    switch(s) {
55248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case Status::OK:
56248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return OK;
57248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case Status::ILLEGAL_ARGUMENT:
58248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return BAD_VALUE;
59248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case Status::CAMERA_IN_USE:
60248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return -EBUSY;
61248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case Status::MAX_CAMERAS_IN_USE:
62248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return -EUSERS;
63248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case Status::METHOD_NOT_SUPPORTED:
64248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return UNKNOWN_TRANSACTION;
65248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case Status::OPERATION_NOT_SUPPORTED:
66248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return INVALID_OPERATION;
67248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case Status::CAMERA_DISCONNECTED:
68248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return DEAD_OBJECT;
69248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        case Status::INTERNAL_ERROR:
70248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return INVALID_OPERATION;
71248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
72248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGW("Unexpected HAL status code %d", s);
73248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return INVALID_OPERATION;
74248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
75248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
76248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehStatus CameraDevice::initStatus() const {
77248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
78248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Status status = Status::OK;
79248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mInitFail) {
80248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        status = Status::INTERNAL_ERROR;
81248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    } else if (mDisconnected) {
82248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        status = Status::CAMERA_DISCONNECTED;
83248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
84248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return status;
85248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
86248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
87248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehCameraDevice::CameraDevice(
88248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    sp<CameraModule> module, const std::string& cameraId,
89248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames) :
90248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mModule(module),
91248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mCameraId(cameraId),
92248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mDisconnected(false),
93248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mCameraDeviceNames(cameraDeviceNames) {
94248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mCameraIdInt = atoi(mCameraId.c_str());
95248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    // Should not reach here as provider also validate ID
96248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mCameraIdInt < 0 || mCameraIdInt >= module->getNumberOfCameras()) {
97248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: Invalid camera id: %s", __FUNCTION__, mCameraId.c_str());
98248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mInitFail = true;
99248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
100248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
101248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mDeviceVersion = mModule->getDeviceVersion(mCameraIdInt);
102248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDeviceVersion != CAMERA_DEVICE_API_VERSION_1_0 && !mModule->isOpenLegacyDefined()) {
103248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGI("%s: Camera id %s does not support HAL1.0",
104248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                __FUNCTION__, mCameraId.c_str());
105248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mInitFail = true;
106248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
10712b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh
10812b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    mAshmemAllocator = IAllocator::getService("ashmem");
10912b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    if (mAshmemAllocator == nullptr) {
11012b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        ALOGI("%s: cannot get ashmemAllocator", __FUNCTION__);
11112b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        mInitFail = true;
11212b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    }
113248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
114248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
115248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehCameraDevice::~CameraDevice() {
116248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
117248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice != nullptr) {
118248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGW("%s: camera %s is deleted while open", __FUNCTION__, mCameraId.c_str());
11977dd4aaad3d71a31a8b546758d8ee09e9b50d6e0Yahan Zhou        closeLocked();
120248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
121248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.cleanUpCirculatingBuffers();
122248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
123248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
124248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
125248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehvoid CameraDevice::setConnectionStatus(bool connected) {
126248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
127248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mDisconnected = !connected;
128248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice == nullptr) {
129248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return;
130248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
131248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!connected) {
132248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGW("%s: camera %s is disconneted. Closing", __FUNCTION__, mCameraId.c_str());
13377dd4aaad3d71a31a8b546758d8ee09e9b50d6e0Yahan Zhou        closeLocked();
134248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
135248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return;
136248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
137248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
138248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehvoid CameraDevice::CameraPreviewWindow::cleanUpCirculatingBuffers() {
139248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
140248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    for (auto pair : mCirculatingBuffers) {
141248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        sHandleImporter.freeBuffer(pair.second);
142248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
143248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mCirculatingBuffers.clear();
144248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mBufferIdMap.clear();
145248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
146248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
147248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sDequeueBuffer(struct preview_stream_ops* w,
148248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                                   buffer_handle_t** buffer, int *stride) {
149248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
150248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
151248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
152248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
153248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
154248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
155248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (buffer == nullptr || stride == nullptr) {
156248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: buffer (%p) and stride (%p) must not be null!", __FUNCTION__, buffer, stride);
157248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return BAD_VALUE;
158248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
159248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
160248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Status s;
161248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    object->mPreviewCallback->dequeueBuffer(
162248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        [&](auto status, uint64_t bufferId, const auto& buf, uint32_t strd) {
163248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            s = status;
164248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            if (s == Status::OK) {
165248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                Mutex::Autolock _l(object->mLock);
166248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                if (object->mCirculatingBuffers.count(bufferId) == 0) {
167248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    buffer_handle_t importedBuf = buf.getNativeHandle();
168248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    sHandleImporter.importBuffer(importedBuf);
169248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    if (importedBuf == nullptr) {
170248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                        ALOGE("%s: preview buffer import failed!", __FUNCTION__);
171248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                        s = Status::INTERNAL_ERROR;
172248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                        return;
173248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    } else {
174248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                        object->mCirculatingBuffers[bufferId] = importedBuf;
175248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                        object->mBufferIdMap[&(object->mCirculatingBuffers[bufferId])] = bufferId;
176248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    }
177248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                }
178248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                *buffer = &(object->mCirculatingBuffers[bufferId]);
179248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                *stride = strd;
180248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            }
181248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        });
182248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getStatusT(s);
183248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
184248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
185248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sLockBuffer(struct preview_stream_ops*, buffer_handle_t*) {
186248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return 0;
187248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
188248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
189248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sEnqueueBuffer(struct preview_stream_ops* w, buffer_handle_t* buffer) {
190248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
191248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
192248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
193248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
194248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
195248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    uint64_t bufferId = object->mBufferIdMap.at(buffer);
196248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getStatusT(object->mPreviewCallback->enqueueBuffer(bufferId));
197248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
198248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
199248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sCancelBuffer(struct preview_stream_ops* w, buffer_handle_t* buffer) {
200248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
201248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
202248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
203248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
204248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
205248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    uint64_t bufferId = object->mBufferIdMap.at(buffer);
206248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getStatusT(object->mPreviewCallback->cancelBuffer(bufferId));
207248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
208248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
209248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sSetBufferCount(struct preview_stream_ops* w, int count) {
210248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
211248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
212248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
213248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
214248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
215248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
216248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    object->cleanUpCirculatingBuffers();
217248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getStatusT(object->mPreviewCallback->setBufferCount(count));
218248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
219248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
220248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sSetBuffersGeometry(struct preview_stream_ops* w,
221248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                                         int width, int height, int format) {
222248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
223248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
224248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
225248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
226248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
227248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
228248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    object->cleanUpCirculatingBuffers();
229248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getStatusT(
230248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            object->mPreviewCallback->setBuffersGeometry(width, height, (PixelFormat) format));
231248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
232248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
233248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sSetCrop(struct preview_stream_ops *w,
234248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                             int left, int top, int right, int bottom) {
235248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
236248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
237248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
238248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
239248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
240248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
241248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getStatusT(object->mPreviewCallback->setCrop(left, top, right, bottom));
242248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
243248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
244248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sSetTimestamp(struct preview_stream_ops *w, int64_t timestamp) {
245248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
246248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
247248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
248248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
249248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
250248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
251248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getStatusT(object->mPreviewCallback->setTimestamp(timestamp));
252248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
253248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
254248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sSetUsage(struct preview_stream_ops* w, int usage) {
255248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
256248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
257248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
258248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
259248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
260248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
261248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    object->cleanUpCirculatingBuffers();
26279d13ff0f5cd3c4242445baf5b2f01a52f0ed06fChia-I Wu    return getStatusT(object->mPreviewCallback->setUsage((BufferUsage)usage));
263248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
264248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
265248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sSetSwapInterval(struct preview_stream_ops *w, int interval) {
266248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
267248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
268248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
269248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
270248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
271248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
272248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getStatusT(object->mPreviewCallback->setSwapInterval(interval));
273248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
274248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
275248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehint CameraDevice::sGetMinUndequeuedBufferCount(
276248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                  const struct preview_stream_ops *w,
277248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                  int *count) {
278248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    const CameraPreviewWindow* object =  static_cast<const CameraPreviewWindow*>(w);
279248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mPreviewCallback == nullptr) {
280248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
281248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return INVALID_OPERATION;
282248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
283248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (count == nullptr) {
284248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: count is null!", __FUNCTION__);
285248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return BAD_VALUE;
286248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
287248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
288248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Status s;
289248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    object->mPreviewCallback->getMinUndequeuedBufferCount(
290248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        [&](auto status, uint32_t cnt) {
291248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            s = status;
292248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            if (s == Status::OK) {
293248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                *count = cnt;
294248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            }
295248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        });
296248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getStatusT(s);
297248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
298248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
29912b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia YehCameraDevice::CameraHeapMemory::CameraHeapMemory(
30012b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    int fd, size_t buf_size, uint_t num_buffers) :
301248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mBufSize(buf_size),
302248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mNumBufs(num_buffers) {
30312b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    mHidlHandle = native_handle_create(1,0);
30412b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    mHidlHandle->data[0] = fcntl(fd, F_DUPFD_CLOEXEC, 0);
30512b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    const size_t pagesize = getpagesize();
30612b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1));
30712b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    mHidlHeap = hidl_memory("ashmem", mHidlHandle, size);
308248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    commonInitialization();
309248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
310248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
31112b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia YehCameraDevice::CameraHeapMemory::CameraHeapMemory(
31212b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    sp<IAllocator> ashmemAllocator,
31312b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    size_t buf_size, uint_t num_buffers) :
314248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mBufSize(buf_size),
315248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mNumBufs(num_buffers) {
31612b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    const size_t pagesize = getpagesize();
31712b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1));
31812b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    ashmemAllocator->allocate(size,
31912b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        [&](bool success, const hidl_memory& mem) {
32012b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh            if (!success) {
32112b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh                ALOGE("%s: allocating ashmem of %zu bytes failed!",
32212b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh                        __FUNCTION__, buf_size * num_buffers);
32312b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh                return;
32412b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh            }
32512b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh            mHidlHandle = native_handle_clone(mem.handle());
32612b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh            mHidlHeap = hidl_memory("ashmem", mHidlHandle, size);
32712b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        });
32812b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh
329248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    commonInitialization();
330248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
331248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
332248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehvoid CameraDevice::CameraHeapMemory::commonInitialization() {
33312b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    mHidlHeapMemory = mapMemory(mHidlHeap);
33412b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    if (mHidlHeapMemory == nullptr) {
33512b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        ALOGE("%s: memory map failed!", __FUNCTION__);
33612b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        native_handle_close(mHidlHandle); // close FD for the shared memory
33712b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        native_handle_delete(mHidlHandle);
33812b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        mHidlHeap = hidl_memory();
33912b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        mHidlHandle = nullptr;
34012b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        return;
34112b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    }
34212b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    mHidlHeapMemData = mHidlHeapMemory->getPointer();
34312b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    handle.data = mHidlHeapMemData;
344248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    handle.size = mBufSize * mNumBufs;
345248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    handle.handle = this;
346248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    handle.release = sPutMemory;
347248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
348248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
349248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehCameraDevice::CameraHeapMemory::~CameraHeapMemory() {
35012b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    if (mHidlHeapMemory != nullptr) {
35112b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        mHidlHeapMemData = nullptr;
35212b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        mHidlHeapMemory.clear(); // The destructor will trigger munmap
35312b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    }
35412b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh
35512b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    if (mHidlHandle) {
35612b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        native_handle_close(mHidlHandle); // close FD for the shared memory
35712b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        native_handle_delete(mHidlHandle);
35812b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    }
359248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
360248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
361248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh// shared memory methods
362248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehcamera_memory_t* CameraDevice::sGetMemory(int fd, size_t buf_size, uint_t num_bufs, void *user) {
363248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s", __FUNCTION__);
364248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraDevice* object = static_cast<CameraDevice*>(user);
365248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mDeviceCallback == nullptr) {
366248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL request memory while camera is not opened!", __FUNCTION__);
367248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return nullptr;
368248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
369248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
370248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraHeapMemory* mem;
371248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (fd < 0) {
37212b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        mem = new CameraHeapMemory(object->mAshmemAllocator, buf_size, num_bufs);
373248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    } else {
374248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mem = new CameraHeapMemory(fd, buf_size, num_bufs);
375248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
376248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mem->incStrong(mem);
37712b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh    hidl_handle hidlHandle = mem->mHidlHandle;
378248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    MemoryId id = object->mDeviceCallback->registerMemory(hidlHandle, buf_size, num_bufs);
379248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mem->handle.mId = id;
3806550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh
3816550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh    {
3826550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh        Mutex::Autolock _l(object->mMemoryMapLock);
3836550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh        if (object->mMemoryMap.count(id) != 0) {
3846550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh            ALOGE("%s: duplicate MemoryId %d returned by client!", __FUNCTION__, id);
3856550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh        }
3866550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh        object->mMemoryMap[id] = mem;
387248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
388248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mem->handle.mDevice = object;
389248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return &mem->handle;
390248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
391248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
392248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehvoid CameraDevice::sPutMemory(camera_memory_t *data) {
393248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!data)
394248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return;
395248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
396248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle);
397248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraDevice* device = mem->handle.mDevice;
398248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (device == nullptr) {
399248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL return memory for a null device!", __FUNCTION__);
400248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
401248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (device->mDeviceCallback == nullptr) {
402248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: camera HAL return memory while camera is not opened!", __FUNCTION__);
403248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
404248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    device->mDeviceCallback->unregisterMemory(mem->handle.mId);
4056550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh    {
4066550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh        Mutex::Autolock _l(device->mMemoryMapLock);
4076550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh        device->mMemoryMap.erase(mem->handle.mId);
4086550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh    }
409248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mem->decStrong(mem);
410248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
411248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
412248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh// Callback forwarding methods
413248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehvoid CameraDevice::sNotifyCb(int32_t msg_type, int32_t ext1, int32_t ext2, void *user) {
414248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s", __FUNCTION__);
415248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraDevice* object = static_cast<CameraDevice*>(user);
416248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mDeviceCallback != nullptr) {
417248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        object->mDeviceCallback->notifyCallback((NotifyCallbackMsg) msg_type, ext1, ext2);
418248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
419248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
420248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
421248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehvoid CameraDevice::sDataCb(int32_t msg_type, const camera_memory_t *data, unsigned int index,
422248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        camera_frame_metadata_t *metadata, void *user) {
423248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s", __FUNCTION__);
424248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraDevice* object = static_cast<CameraDevice*>(user);
425248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory*>(data->handle));
426248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (index >= mem->mNumBufs) {
427248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
428248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh             index, mem->mNumBufs);
429248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return;
430248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
431248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mDeviceCallback != nullptr) {
432248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        CameraFrameMetadata hidlMetadata;
433248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (metadata) {
434248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            hidlMetadata.faces.resize(metadata->number_of_faces);
435248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            for (size_t i = 0; i < hidlMetadata.faces.size(); i++) {
436248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                hidlMetadata.faces[i].score = metadata->faces[i].score;
437248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                hidlMetadata.faces[i].id = metadata->faces[i].id;
438248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                for (int k = 0; k < 4; k++) {
439248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    hidlMetadata.faces[i].rect[k] = metadata->faces[i].rect[k];
440248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                }
441248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                for (int k = 0; k < 2; k++) {
442248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    hidlMetadata.faces[i].leftEye[k] = metadata->faces[i].left_eye[k];
443248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                }
444248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                for (int k = 0; k < 2; k++) {
445248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    hidlMetadata.faces[i].rightEye[k] = metadata->faces[i].right_eye[k];
446248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                }
447248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                for (int k = 0; k < 2; k++) {
448248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    hidlMetadata.faces[i].mouth[k] = metadata->faces[i].mouth[k];
449248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                }
450248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            }
451248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
452248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle);
453248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        object->mDeviceCallback->dataCallback(
454248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                (DataCallbackMsg) msg_type, mem->handle.mId, index, hidlMetadata);
455248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
456248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
457248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
4581ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yehvoid CameraDevice::handleCallbackTimestamp(
4591ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        nsecs_t timestamp, int32_t msg_type,
4601ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        MemoryId memId , unsigned index, native_handle_t* handle) {
4611ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    uint32_t batchSize = 0;
4621ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    {
4631ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        Mutex::Autolock _l(mBatchLock);
4641ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        batchSize = mBatchSize;
4651ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    }
4661ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh
4671ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    if (batchSize == 0) { // non-batch mode
4681ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        mDeviceCallback->handleCallbackTimestamp(
4691ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh                (DataCallbackMsg) msg_type, handle, memId, index, timestamp);
4701ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    } else { // batch mode
4711ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        Mutex::Autolock _l(mBatchLock);
4721ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        size_t inflightSize = mInflightBatch.size();
4731ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        if (inflightSize == 0) {
4741ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh            mBatchMsgType = msg_type;
4751ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        } else if (mBatchMsgType != msg_type) {
4761ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh            ALOGE("%s: msg_type change (from %d to %d) is not supported!",
4771ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh                    __FUNCTION__, mBatchMsgType, msg_type);
4781ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh            return;
4791ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        }
4801ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        mInflightBatch.push_back({handle, memId, index, timestamp});
4811ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh
4821ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        // Send batched frames to camera framework
4831ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        if (mInflightBatch.size() >= batchSize) {
4841ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh            mDeviceCallback->handleCallbackTimestampBatch(
4851ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh                    (DataCallbackMsg) mBatchMsgType, mInflightBatch);
4861ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh            mInflightBatch.clear();
4871ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        }
4881ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    }
4891ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh}
4901ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh
491248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehvoid CameraDevice::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
492248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        const camera_memory_t *data, unsigned index, void *user) {
493248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s", __FUNCTION__);
494248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraDevice* object = static_cast<CameraDevice*>(user);
495248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    // Start refcounting the heap object from here on.  When the clients
496248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    // drop all references, it will be destroyed (as well as the enclosed
497248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    // MemoryHeapBase.
498248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory*>(data->handle));
499248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (index >= mem->mNumBufs) {
500248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
501248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh             index, mem->mNumBufs);
502248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return;
503248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
504248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
505248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    native_handle_t* handle = nullptr;
506248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mMetadataMode) {
507248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (mem->mBufSize == sizeof(VideoNativeHandleMetadata)) {
508248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
50912b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh                    ((uint8_t*) mem->mHidlHeapMemData + index * mem->mBufSize);
5101ee279df205218fb7372baf031fb93d2a0d6a821Yin-Chia Yeh            if (md->eType == kMetadataBufferTypeNativeHandleSource) {
511248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                handle = md->pHandle;
512248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            }
513248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
514248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
515248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
516248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (object->mDeviceCallback != nullptr) {
517248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (handle == nullptr) {
518248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            object->mDeviceCallback->dataCallbackTimestamp(
519248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    (DataCallbackMsg) msg_type, mem->handle.mId, index, timestamp);
520248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        } else {
5211ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh            object->handleCallbackTimestamp(timestamp, msg_type, mem->handle.mId, index, handle);
522248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
523248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
524248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
525248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
526248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehvoid CameraDevice::initHalPreviewWindow()
527248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh{
528248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.cancel_buffer = sCancelBuffer;
529248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.lock_buffer = sLockBuffer;
530248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.dequeue_buffer = sDequeueBuffer;
531248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.enqueue_buffer = sEnqueueBuffer;
532248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.set_buffer_count = sSetBufferCount;
533248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.set_buffers_geometry = sSetBuffersGeometry;
534248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.set_crop = sSetCrop;
535248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.set_timestamp = sSetTimestamp;
536248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.set_usage = sSetUsage;
537248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.set_swap_interval = sSetSwapInterval;
538248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
539248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.get_min_undequeued_buffer_count =
540248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            sGetMinUndequeuedBufferCount;
541248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
542248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
543248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh// Methods from ::android::hardware::camera::device::V1_0::ICameraDevice follow.
544248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::getResourceCost(getResourceCost_cb _hidl_cb) {
545248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Status status = initStatus();
546248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraResourceCost resCost;
547248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (status == Status::OK) {
548248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        int cost = 100;
549248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        std::vector<std::string> conflicting_devices;
550248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        struct camera_info info;
551248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
552248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        // If using post-2.4 module version, query the cost + conflicting devices from the HAL
553248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
554248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            int ret = mModule->getCameraInfo(mCameraIdInt, &info);
555248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            if (ret == OK) {
556248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                cost = info.resource_cost;
557248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                for (size_t i = 0; i < info.conflicting_devices_length; i++) {
558248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    std::string cameraId(info.conflicting_devices[i]);
559248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    for (const auto& pair : mCameraDeviceNames) {
560248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                        if (cameraId == pair.first) {
561248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                            conflicting_devices.push_back(pair.second);
562248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                        }
563248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    }
564248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                }
565248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            } else {
566248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                status = Status::INTERNAL_ERROR;
567248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            }
568248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
569248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
570248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (status == Status::OK) {
571248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            resCost.resourceCost = cost;
572248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            resCost.conflictingDevices.resize(conflicting_devices.size());
573248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            for (size_t i = 0; i < conflicting_devices.size(); i++) {
574248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                resCost.conflictingDevices[i] = conflicting_devices[i];
575248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                ALOGV("CamDevice %s is conflicting with camDevice %s",
576248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                        mCameraId.c_str(), resCost.conflictingDevices[i].c_str());
577248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            }
578248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
579248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
580248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    _hidl_cb(status, resCost);
581248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Void();
582248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
583248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
584248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::getCameraInfo(getCameraInfo_cb _hidl_cb) {
585248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Status status = initStatus();
586248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    CameraInfo cameraInfo;
587248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (status == Status::OK) {
588248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        struct camera_info info;
589248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        int ret = mModule->getCameraInfo(mCameraIdInt, &info);
590248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (ret == OK) {
591248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            cameraInfo.facing = (CameraFacing) info.facing;
592248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            // Device 1.0 does not support external camera facing.
593248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            // The closest approximation would be front camera.
594248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            if (cameraInfo.facing == CameraFacing::EXTERNAL) {
595248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                cameraInfo.facing = CameraFacing::FRONT;
596248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            }
597248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            cameraInfo.orientation = info.orientation;
598248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        } else {
599248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            ALOGE("%s: get camera info failed!", __FUNCTION__);
600248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            status = Status::INTERNAL_ERROR;
601248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
602248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
603248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    _hidl_cb(status, cameraInfo);
604248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Void();
605248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
606248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
607248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::setTorchMode(TorchMode mode) {
608248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mModule->isSetTorchModeSupported()) {
609248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::METHOD_NOT_SUPPORTED;
610248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
611248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
612248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Status status = initStatus();
613248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (status == Status::OK) {
614248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        bool enable = (mode == TorchMode::ON) ? true : false;
615248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        status = getHidlStatus(mModule->setTorchMode(mCameraId.c_str(), enable));
616248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
617248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return status;
618248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
619248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
620248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::dumpState(const hidl_handle& handle) {
621248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
622248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (handle.getNativeHandle() == nullptr) {
623248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: handle must not be null", __FUNCTION__);
624248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::ILLEGAL_ARGUMENT;
625248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
626248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (handle->numFds != 1 || handle->numInts != 0) {
627248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s: handle must contain 1 FD and 0 integers! Got %d FDs and %d ints",
628248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                __FUNCTION__, handle->numFds, handle->numInts);
629248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::ILLEGAL_ARGUMENT;
630248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
631248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    int fd = handle->data[0];
632248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
633248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice != nullptr) {
634248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (mDevice->ops->dump) { // It's fine if the HAL doesn't implement dump()
635248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return getHidlStatus(mDevice->ops->dump(mDevice, fd));
636248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
637248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
638248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::OK;
639248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
640248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
641248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::open(const sp<ICameraDeviceCallback>& callback) {
642248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGI("Opening camera %s", mCameraId.c_str());
643248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
644248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
645248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    camera_info info;
646248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    status_t res = mModule->getCameraInfo(mCameraIdInt, &info);
647248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (res != OK) {
648248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("Could not get camera info: %s: %d", mCameraId.c_str(), res);
649248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(res);
650248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
651248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
652248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    int rc = OK;
653248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
654248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
655248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        // Open higher version camera device as HAL1.0 device.
656248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        rc = mModule->openLegacy(mCameraId.c_str(),
657248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                                 CAMERA_DEVICE_API_VERSION_1_0,
658248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                                 (hw_device_t **)&mDevice);
659248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    } else {
660248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        rc = mModule->open(mCameraId.c_str(), (hw_device_t **)&mDevice);
661248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
662248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (rc != OK) {
663248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mDevice = nullptr;
664248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("Could not open camera %s: %d", mCameraId.c_str(), rc);
665248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(rc);
666248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
667248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
668248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    initHalPreviewWindow();
669248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mDeviceCallback = callback;
670248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
671248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->set_callbacks) {
672248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mDevice->ops->set_callbacks(mDevice,
673248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                sNotifyCb, sDataCb, sDataCbTimestamp, sGetMemory, this);
674248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
675248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
676248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return getHidlStatus(rc);
677248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
678248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
679248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::setPreviewWindow(const sp<ICameraDevicePreviewCallback>& window) {
680248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
681248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
682248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
683248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
684248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
685248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
686248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
687248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    mHalPreviewWindow.mPreviewCallback = window;
688248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->set_preview_window) {
689248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(mDevice->ops->set_preview_window(mDevice,
690248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                (window == nullptr) ? nullptr : &mHalPreviewWindow));
691248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
692248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::INTERNAL_ERROR; // HAL should provide set_preview_window
693248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
694248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
695248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::enableMsgType(uint32_t msgType) {
696248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
697248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
698248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
699248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
700248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Void();
701248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
702248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->enable_msg_type) {
703248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mDevice->ops->enable_msg_type(mDevice, msgType);
704248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
705248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Void();
706248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
707248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
708248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::disableMsgType(uint32_t msgType) {
709248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
710248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
711248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
712248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
713248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Void();
714248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
715248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->disable_msg_type) {
716248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mDevice->ops->disable_msg_type(mDevice, msgType);
717248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
718248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Void();
719248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
720248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
721248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<bool> CameraDevice::msgTypeEnabled(uint32_t msgType) {
722248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
723248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
724248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
725248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
726248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return false;
727248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
728248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->msg_type_enabled) {
729248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return mDevice->ops->msg_type_enabled(mDevice, msgType);
730248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
731248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return false;
732248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
733248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
734248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::startPreview() {
735248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
736248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
737248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
738248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
739248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
740248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
741248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->start_preview) {
742248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(mDevice->ops->start_preview(mDevice));
743248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
744248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::INTERNAL_ERROR; // HAL should provide start_preview
745248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
746248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
747248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::stopPreview() {
748248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
749248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
750248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
751248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
752248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Void();
753248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
754248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->stop_preview) {
755248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mDevice->ops->stop_preview(mDevice);
756248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
757248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Void();
758248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
759248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
760248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<bool> CameraDevice::previewEnabled() {
761248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
762248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
763248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
764248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
765248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return false;
766248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
767248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->preview_enabled) {
768248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return mDevice->ops->preview_enabled(mDevice);
769248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
770248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return false;
771248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
772248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
773248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::storeMetaDataInBuffers(bool enable) {
774248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
775248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
776248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
777248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
778248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
779248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
780248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->store_meta_data_in_buffers) {
781248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        status_t s = mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
782248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (s == OK && enable) {
783248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            mMetadataMode = true;
784248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
785248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(s);
786248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
787248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return enable ? Status::ILLEGAL_ARGUMENT : Status::OK;
788248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
789248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
790248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::startRecording() {
791248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
792248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
793248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
794248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
795248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
796248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
797248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->start_recording) {
798248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(mDevice->ops->start_recording(mDevice));
799248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
800248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::ILLEGAL_ARGUMENT;
801248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
802248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
803248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::stopRecording() {
804248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
805248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
806248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
807248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
808248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Void();
809248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
810248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->stop_recording) {
811248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mDevice->ops->stop_recording(mDevice);
812248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
813248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Void();
814248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
815248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
816248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<bool> CameraDevice::recordingEnabled() {
817248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
818248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
819248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
820248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
821248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return false;
822248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
823248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->recording_enabled) {
824248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return mDevice->ops->recording_enabled(mDevice);
825248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
826248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return false;
827248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
828248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
829248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yehvoid CameraDevice::releaseRecordingFrameLocked(
830248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        uint32_t memId, uint32_t bufferIndex, const native_handle_t* handle) {
831248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
832248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
833248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return;
834248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
835248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->release_recording_frame) {
8366550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh        CameraHeapMemory* camMemory;
8376550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh        {
8386550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh            Mutex::Autolock _l(mMemoryMapLock);
8396550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh            auto it = mMemoryMap.find(memId);
8406550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh            if (it == mMemoryMap.end() || it->second == nullptr) {
8416550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh                ALOGE("%s unknown memoryId %d", __FUNCTION__, memId);
8426550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh                return;
8436550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh            }
8446550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh            camMemory = it->second;
8456550022dbafb199568af856bda200d56b5ebacbfYin-Chia Yeh        }
846248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (bufferIndex >= camMemory->mNumBufs) {
847248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            ALOGE("%s: bufferIndex %d exceeds number of buffers %d",
848248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    __FUNCTION__, bufferIndex, camMemory->mNumBufs);
849248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            return;
850248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
85112b364bf8aa87ddc43df7b590d1f1d9b6dc5b061Yin-Chia Yeh        void *data = ((uint8_t *) camMemory->mHidlHeapMemData) + bufferIndex * camMemory->mBufSize;
852248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (handle) {
853248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) data;
8541ee279df205218fb7372baf031fb93d2a0d6a821Yin-Chia Yeh            if (md->eType == kMetadataBufferTypeNativeHandleSource) {
855248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                // Input handle will be closed by HIDL transport later, so clone it
856248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                // HAL implementation is responsible to close/delete the clone
857248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                native_handle_t* clone = native_handle_clone(handle);
858248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                if (!clone) {
859248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    ALOGE("%s: failed to clone buffer %p", __FUNCTION__, handle);
860248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                    return;
861248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                }
862248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                md->pHandle = clone;
863248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            } else {
864248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                ALOGE("%s:Malform VideoNativeHandleMetadata at memId %d, bufferId %d",
865248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                        __FUNCTION__, memId, bufferIndex);
866248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh                return;
867248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            }
868248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
869248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mDevice->ops->release_recording_frame(mDevice, data);
870248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
871248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
872248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
873248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::releaseRecordingFrame(uint32_t memId, uint32_t bufferIndex) {
874248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
875248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
876248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    releaseRecordingFrameLocked(memId, bufferIndex, nullptr);
877248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Void();
878248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
879248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
880248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::releaseRecordingFrameHandle(
881248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        uint32_t memId, uint32_t bufferIndex, const hidl_handle& frame) {
882248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
883248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
884248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    releaseRecordingFrameLocked(
885248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            memId, bufferIndex, frame.getNativeHandle());
886248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Void();
887248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
888248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
8891ba83a9a282afa086ac2431942a4814633438ffcYin-Chia YehReturn<void> CameraDevice::releaseRecordingFrameHandleBatch(
8901ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        const hidl_vec<VideoFrameMessage>& msgs) {
8911ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
8921ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    Mutex::Autolock _l(mLock);
8931ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    for (auto& msg : msgs) {
8941ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh        releaseRecordingFrameLocked(
8951ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh                msg.data, msg.bufferIndex, msg.frameData.getNativeHandle());
8961ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    }
8971ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh    return Void();
8981ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh}
8991ba83a9a282afa086ac2431942a4814633438ffcYin-Chia Yeh
900248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::autoFocus() {
901248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
902248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
903248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
904248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
905248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
906248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
907248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->auto_focus) {
908248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(mDevice->ops->auto_focus(mDevice));
909248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
910248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::ILLEGAL_ARGUMENT;
911248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
912248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
913248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::cancelAutoFocus() {
914248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
915248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
916248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
917248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
918248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
919248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
920248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->cancel_auto_focus) {
921248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(mDevice->ops->cancel_auto_focus(mDevice));
922248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
923248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::ILLEGAL_ARGUMENT;
924248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
925248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
926248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::takePicture() {
927248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
928248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
929248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
930248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
931248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
932248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
933248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->take_picture) {
934248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(mDevice->ops->take_picture(mDevice));
935248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
936248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::ILLEGAL_ARGUMENT;
937248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
938248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
939248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::cancelPicture() {
940248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
941248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
942248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
943248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
944248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
945248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
946248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->cancel_picture) {
947248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(mDevice->ops->cancel_picture(mDevice));
948248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
949248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::ILLEGAL_ARGUMENT;
950248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
951248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
952248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::setParameters(const hidl_string& params) {
953248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
954248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
955248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
956248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
957248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
958248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
959248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->set_parameters) {
960248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(mDevice->ops->set_parameters(mDevice, params.c_str()));
961248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
962248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::ILLEGAL_ARGUMENT;
963248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
964248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
965248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::getParameters(getParameters_cb _hidl_cb) {
966248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
967248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
968248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    hidl_string outStr;
969248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
970248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
971248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        _hidl_cb(outStr);
972248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Void();
973248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
974248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->get_parameters) {
975248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        char *temp = mDevice->ops->get_parameters(mDevice);
976248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        outStr = temp;
977248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (mDevice->ops->put_parameters) {
978248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            mDevice->ops->put_parameters(mDevice, temp);
979248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        } else {
980248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            free(temp);
981248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
982248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
983248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    _hidl_cb(outStr);
984248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Void();
985248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
986248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
987248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<Status> CameraDevice::sendCommand(CommandType cmd, int32_t arg1, int32_t arg2) {
988248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
989248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
990248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (!mDevice) {
991248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        ALOGE("%s called while camera is not opened", __FUNCTION__);
992248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return Status::OPERATION_NOT_SUPPORTED;
993248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
994248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if (mDevice->ops->send_command) {
995248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        return getHidlStatus(mDevice->ops->send_command(mDevice, (int32_t) cmd, arg1, arg2));
996248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
997248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    return Status::ILLEGAL_ARGUMENT;
998248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
999248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
1000248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia YehReturn<void> CameraDevice::close() {
1001248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    Mutex::Autolock _l(mLock);
100277dd4aaad3d71a31a8b546758d8ee09e9b50d6e0Yahan Zhou    closeLocked();
100377dd4aaad3d71a31a8b546758d8ee09e9b50d6e0Yahan Zhou    return Void();
100477dd4aaad3d71a31a8b546758d8ee09e9b50d6e0Yahan Zhou}
100577dd4aaad3d71a31a8b546758d8ee09e9b50d6e0Yahan Zhou
100677dd4aaad3d71a31a8b546758d8ee09e9b50d6e0Yahan Zhouvoid CameraDevice::closeLocked() {
100777dd4aaad3d71a31a8b546758d8ee09e9b50d6e0Yahan Zhou    ALOGI("Closing camera %s", mCameraId.c_str());
1008248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    if(mDevice) {
1009248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        int rc = mDevice->common.close(&mDevice->common);
1010248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        if (rc != OK) {
1011248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh            ALOGE("Could not close camera %s: %d", mCameraId.c_str(), rc);
1012248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        }
1013248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh        mDevice = nullptr;
1014248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh    }
1015248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}
1016248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh
1017248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}  // namespace implementation
1018248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}  // namespace V1_0
1019248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}  // namespace device
1020248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}  // namespace camera
1021248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}  // namespace hardware
1022248ed700fed7e682eddf3d0607592eb5f3a3fb1aYin-Chia Yeh}  // namespace android
1023