Last active
September 15, 2019 10:39
-
-
Save erfanoabdi/bd6baef41b575a9c2b86c46727a0a903 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2017 The Android Open Source Project | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
#define LOG_TAG "[email protected]" | |
#include <hardware/camera.h> | |
#include <hardware/gralloc1.h> | |
#include <hidlmemory/mapping.h> | |
#include <log/log.h> | |
#include <utils/Trace.h> | |
#include <media/hardware/HardwareAPI.h> // For VideoNativeHandleMetadata | |
#include "CameraDevice_1_0.h" | |
namespace android { | |
namespace hardware { | |
namespace camera { | |
namespace device { | |
namespace V1_0 { | |
namespace implementation { | |
using ::android::hardware::graphics::common::V1_0::BufferUsage; | |
using ::android::hardware::graphics::common::V1_0::PixelFormat; | |
HandleImporter CameraDevice::sHandleImporter; | |
Status CameraDevice::getHidlStatus(const int& status) { | |
switch (status) { | |
case 0: return Status::OK; | |
case -ENOSYS: return Status::OPERATION_NOT_SUPPORTED; | |
case -EBUSY : return Status::CAMERA_IN_USE; | |
case -EUSERS: return Status::MAX_CAMERAS_IN_USE; | |
case -ENODEV: return Status::INTERNAL_ERROR; | |
case -EINVAL: return Status::ILLEGAL_ARGUMENT; | |
default: | |
ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status); | |
return Status::INTERNAL_ERROR; | |
} | |
} | |
status_t CameraDevice::getStatusT(const Status& s) { | |
switch(s) { | |
case Status::OK: | |
return OK; | |
case Status::ILLEGAL_ARGUMENT: | |
return BAD_VALUE; | |
case Status::CAMERA_IN_USE: | |
return -EBUSY; | |
case Status::MAX_CAMERAS_IN_USE: | |
return -EUSERS; | |
case Status::METHOD_NOT_SUPPORTED: | |
return UNKNOWN_TRANSACTION; | |
case Status::OPERATION_NOT_SUPPORTED: | |
return INVALID_OPERATION; | |
case Status::CAMERA_DISCONNECTED: | |
return DEAD_OBJECT; | |
case Status::INTERNAL_ERROR: | |
return INVALID_OPERATION; | |
} | |
ALOGW("Unexpected HAL status code %d", s); | |
return INVALID_OPERATION; | |
} | |
Status CameraDevice::initStatus() const { | |
Mutex::Autolock _l(mLock); | |
Status status = Status::OK; | |
if (mInitFail) { | |
status = Status::INTERNAL_ERROR; | |
} else if (mDisconnected) { | |
status = Status::CAMERA_DISCONNECTED; | |
} | |
return status; | |
} | |
CameraDevice::CameraDevice( | |
sp<CameraModule> module, const std::string& cameraId, | |
const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames) : | |
mModule(module), | |
mCameraId(cameraId), | |
mDisconnected(false), | |
mCameraDeviceNames(cameraDeviceNames) { | |
mCameraIdInt = atoi(mCameraId.c_str()); | |
// Should not reach here as provider also validate ID | |
if (mCameraIdInt < 0 || mCameraIdInt >= module->getNumberOfCameras()) { | |
ALOGE("%s: Invalid camera id: %s", __FUNCTION__, mCameraId.c_str()); | |
mInitFail = true; | |
} | |
mDeviceVersion = mModule->getDeviceVersion(mCameraIdInt); | |
if (mDeviceVersion != CAMERA_DEVICE_API_VERSION_1_0 && !mModule->isOpenLegacyDefined()) { | |
ALOGI("%s: Camera id %s does not support HAL1.0", | |
__FUNCTION__, mCameraId.c_str()); | |
mInitFail = true; | |
} | |
mAshmemAllocator = IAllocator::getService("ashmem"); | |
if (mAshmemAllocator == nullptr) { | |
ALOGI("%s: cannot get ashmemAllocator", __FUNCTION__); | |
mInitFail = true; | |
} | |
} | |
CameraDevice::~CameraDevice() { | |
Mutex::Autolock _l(mLock); | |
if (mDevice != nullptr) { | |
ALOGW("%s: camera %s is deleted while open", __FUNCTION__, mCameraId.c_str()); | |
closeLocked(); | |
} | |
mHalPreviewWindow.cleanUpCirculatingBuffers(); | |
} | |
void CameraDevice::setConnectionStatus(bool connected) { | |
Mutex::Autolock _l(mLock); | |
mDisconnected = !connected; | |
if (mDevice == nullptr) { | |
return; | |
} | |
if (!connected) { | |
ALOGW("%s: camera %s is disconneted. Closing", __FUNCTION__, mCameraId.c_str()); | |
closeLocked(); | |
} | |
return; | |
} | |
void CameraDevice::CameraPreviewWindow::cleanUpCirculatingBuffers() { | |
Mutex::Autolock _l(mLock); | |
for (auto pair : mCirculatingBuffers) { | |
sHandleImporter.freeBuffer(pair.second); | |
} | |
mCirculatingBuffers.clear(); | |
mBufferIdMap.clear(); | |
} | |
int CameraDevice::sDequeueBuffer(struct preview_stream_ops* w, | |
buffer_handle_t** buffer, int *stride) { | |
CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
if (buffer == nullptr || stride == nullptr) { | |
ALOGE("%s: buffer (%p) and stride (%p) must not be null!", __FUNCTION__, buffer, stride); | |
return BAD_VALUE; | |
} | |
Status s; | |
object->mPreviewCallback->dequeueBuffer( | |
[&](auto status, uint64_t bufferId, const auto& buf, uint32_t strd) { | |
s = status; | |
if (s == Status::OK) { | |
Mutex::Autolock _l(object->mLock); | |
if (object->mCirculatingBuffers.count(bufferId) == 0) { | |
buffer_handle_t importedBuf = buf.getNativeHandle(); | |
sHandleImporter.importBuffer(importedBuf); | |
if (importedBuf == nullptr) { | |
ALOGE("%s: preview buffer import failed!", __FUNCTION__); | |
s = Status::INTERNAL_ERROR; | |
return; | |
} else { | |
object->mCirculatingBuffers[bufferId] = importedBuf; | |
object->mBufferIdMap[&(object->mCirculatingBuffers[bufferId])] = bufferId; | |
} | |
} | |
*buffer = &(object->mCirculatingBuffers[bufferId]); | |
*stride = strd; | |
} | |
}); | |
return getStatusT(s); | |
} | |
int CameraDevice::sLockBuffer(struct preview_stream_ops*, buffer_handle_t*) { | |
return 0; | |
} | |
int CameraDevice::sEnqueueBuffer(struct preview_stream_ops* w, buffer_handle_t* buffer) { | |
CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
uint64_t bufferId = object->mBufferIdMap.at(buffer); | |
return getStatusT(object->mPreviewCallback->enqueueBuffer(bufferId)); | |
} | |
int CameraDevice::sCancelBuffer(struct preview_stream_ops* w, buffer_handle_t* buffer) { | |
CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
uint64_t bufferId = object->mBufferIdMap.at(buffer); | |
return getStatusT(object->mPreviewCallback->cancelBuffer(bufferId)); | |
} | |
int CameraDevice::sSetBufferCount(struct preview_stream_ops* w, int count) { | |
CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
object->cleanUpCirculatingBuffers(); | |
return getStatusT(object->mPreviewCallback->setBufferCount(count)); | |
} | |
int CameraDevice::sSetBuffersGeometry(struct preview_stream_ops* w, | |
int width, int height, int format) { | |
CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
object->cleanUpCirculatingBuffers(); | |
return getStatusT( | |
object->mPreviewCallback->setBuffersGeometry(width, height, (PixelFormat) format)); | |
} | |
int CameraDevice::sSetCrop(struct preview_stream_ops *w, | |
int left, int top, int right, int bottom) { | |
CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
return getStatusT(object->mPreviewCallback->setCrop(left, top, right, bottom)); | |
} | |
int CameraDevice::sSetTimestamp(struct preview_stream_ops *w, int64_t timestamp) { | |
CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
return getStatusT(object->mPreviewCallback->setTimestamp(timestamp)); | |
} | |
int CameraDevice::sSetUsage(struct preview_stream_ops* w, int usage) { | |
CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
object->cleanUpCirculatingBuffers(); | |
return getStatusT(object->mPreviewCallback->setUsage((BufferUsage)usage)); | |
} | |
int CameraDevice::sSetSwapInterval(struct preview_stream_ops *w, int interval) { | |
CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
return getStatusT(object->mPreviewCallback->setSwapInterval(interval)); | |
} | |
int CameraDevice::sGetMinUndequeuedBufferCount( | |
const struct preview_stream_ops *w, | |
int *count) { | |
const CameraPreviewWindow* object = static_cast<const CameraPreviewWindow*>(w); | |
if (object->mPreviewCallback == nullptr) { | |
ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__); | |
return INVALID_OPERATION; | |
} | |
if (count == nullptr) { | |
ALOGE("%s: count is null!", __FUNCTION__); | |
return BAD_VALUE; | |
} | |
Status s; | |
object->mPreviewCallback->getMinUndequeuedBufferCount( | |
[&](auto status, uint32_t cnt) { | |
s = status; | |
if (s == Status::OK) { | |
*count = cnt; | |
} | |
}); | |
return getStatusT(s); | |
} | |
CameraDevice::CameraHeapMemory::CameraHeapMemory( | |
int fd, size_t buf_size, uint_t num_buffers) : | |
mBufSize(buf_size), | |
mNumBufs(num_buffers) { | |
mHidlHandle = native_handle_create(1,0); | |
mHidlHandle->data[0] = fcntl(fd, F_DUPFD_CLOEXEC, 0); | |
const size_t pagesize = getpagesize(); | |
size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1)); | |
mHidlHeap = hidl_memory("ashmem", mHidlHandle, size); | |
commonInitialization(); | |
} | |
CameraDevice::CameraHeapMemory::CameraHeapMemory( | |
sp<IAllocator> ashmemAllocator, | |
size_t buf_size, uint_t num_buffers) : | |
mBufSize(buf_size), | |
mNumBufs(num_buffers) { | |
const size_t pagesize = getpagesize(); | |
size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1)); | |
ashmemAllocator->allocate(size, | |
[&](bool success, const hidl_memory& mem) { | |
if (!success) { | |
ALOGE("%s: allocating ashmem of %zu bytes failed!", | |
__FUNCTION__, buf_size * num_buffers); | |
return; | |
} | |
mHidlHandle = native_handle_clone(mem.handle()); | |
mHidlHeap = hidl_memory("ashmem", mHidlHandle, size); | |
}); | |
commonInitialization(); | |
} | |
void CameraDevice::CameraHeapMemory::commonInitialization() { | |
mHidlHeapMemory = mapMemory(mHidlHeap); | |
if (mHidlHeapMemory == nullptr) { | |
ALOGE("%s: memory map failed!", __FUNCTION__); | |
native_handle_close(mHidlHandle); // close FD for the shared memory | |
native_handle_delete(mHidlHandle); | |
mHidlHeap = hidl_memory(); | |
mHidlHandle = nullptr; | |
return; | |
} | |
mHidlHeapMemData = mHidlHeapMemory->getPointer(); | |
handle.data = mHidlHeapMemData; | |
handle.size = mBufSize * mNumBufs; | |
handle.handle = this; | |
handle.release = sPutMemory; | |
} | |
CameraDevice::CameraHeapMemory::~CameraHeapMemory() { | |
if (mHidlHeapMemory != nullptr) { | |
mHidlHeapMemData = nullptr; | |
mHidlHeapMemory.clear(); // The destructor will trigger munmap | |
} | |
if (mHidlHandle) { | |
native_handle_close(mHidlHandle); // close FD for the shared memory | |
native_handle_delete(mHidlHandle); | |
} | |
} | |
// shared memory methods | |
camera_memory_t* CameraDevice::sGetMemory(int fd, size_t buf_size, uint_t num_bufs, void *user) { | |
ALOGV("%s", __FUNCTION__); | |
CameraDevice* object = static_cast<CameraDevice*>(user); | |
if (object->mDeviceCallback == nullptr) { | |
ALOGE("%s: camera HAL request memory while camera is not opened!", __FUNCTION__); | |
return nullptr; | |
} | |
CameraHeapMemory* mem; | |
if (fd < 0) { | |
mem = new CameraHeapMemory(object->mAshmemAllocator, buf_size, num_bufs); | |
} else { | |
mem = new CameraHeapMemory(fd, buf_size, num_bufs); | |
} | |
mem->incStrong(mem); | |
hidl_handle hidlHandle = mem->mHidlHandle; | |
MemoryId id = object->mDeviceCallback->registerMemory(hidlHandle, buf_size, num_bufs); | |
mem->handle.mId = id; | |
{ | |
Mutex::Autolock _l(object->mMemoryMapLock); | |
if (object->mMemoryMap.count(id) != 0) { | |
ALOGE("%s: duplicate MemoryId %d returned by client!", __FUNCTION__, id); | |
} | |
object->mMemoryMap[id] = mem; | |
} | |
mem->handle.mDevice = object; | |
return &mem->handle; | |
} | |
void CameraDevice::sPutMemory(camera_memory_t *data) { | |
if (!data) | |
return; | |
CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle); | |
CameraDevice* device = mem->handle.mDevice; | |
if (device == nullptr) { | |
ALOGE("%s: camera HAL return memory for a null device!", __FUNCTION__); | |
} | |
if (device->mDeviceCallback == nullptr) { | |
ALOGE("%s: camera HAL return memory while camera is not opened!", __FUNCTION__); | |
} | |
device->mDeviceCallback->unregisterMemory(mem->handle.mId); | |
{ | |
Mutex::Autolock _l(device->mMemoryMapLock); | |
device->mMemoryMap.erase(mem->handle.mId); | |
} | |
mem->decStrong(mem); | |
} | |
// Callback forwarding methods | |
void CameraDevice::sNotifyCb(int32_t msg_type, int32_t ext1, int32_t ext2, void *user) { | |
ALOGV("%s", __FUNCTION__); | |
CameraDevice* object = static_cast<CameraDevice*>(user); | |
if (object->mDeviceCallback != nullptr) { | |
object->mDeviceCallback->notifyCallback((NotifyCallbackMsg) msg_type, ext1, ext2); | |
} | |
} | |
void CameraDevice::sDataCb(int32_t msg_type, const camera_memory_t *data, unsigned int index, | |
camera_frame_metadata_t *metadata, void *user) { | |
ALOGV("%s", __FUNCTION__); | |
CameraDevice* object = static_cast<CameraDevice*>(user); | |
sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory*>(data->handle)); | |
if (index >= mem->mNumBufs) { | |
ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__, | |
index, mem->mNumBufs); | |
return; | |
} | |
if (object->mDeviceCallback != nullptr) { | |
CameraFrameMetadata hidlMetadata; | |
if (metadata) { | |
hidlMetadata.faces.resize(metadata->number_of_faces); | |
for (size_t i = 0; i < hidlMetadata.faces.size(); i++) { | |
hidlMetadata.faces[i].score = metadata->faces[i].score; | |
hidlMetadata.faces[i].id = metadata->faces[i].id; | |
for (int k = 0; k < 4; k++) { | |
hidlMetadata.faces[i].rect[k] = metadata->faces[i].rect[k]; | |
} | |
for (int k = 0; k < 2; k++) { | |
hidlMetadata.faces[i].leftEye[k] = metadata->faces[i].left_eye[k]; | |
} | |
for (int k = 0; k < 2; k++) { | |
hidlMetadata.faces[i].rightEye[k] = metadata->faces[i].right_eye[k]; | |
} | |
for (int k = 0; k < 2; k++) { | |
hidlMetadata.faces[i].mouth[k] = metadata->faces[i].mouth[k]; | |
} | |
} | |
} | |
CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle); | |
object->mDeviceCallback->dataCallback( | |
(DataCallbackMsg) msg_type, mem->handle.mId, index, hidlMetadata); | |
} | |
} | |
void CameraDevice::handleCallbackTimestamp( | |
nsecs_t timestamp, int32_t msg_type, | |
MemoryId memId , unsigned index, native_handle_t* handle) { | |
uint32_t batchSize = 0; | |
{ | |
Mutex::Autolock _l(mBatchLock); | |
batchSize = mBatchSize; | |
} | |
if (batchSize == 0) { // non-batch mode | |
mDeviceCallback->handleCallbackTimestamp( | |
(DataCallbackMsg) msg_type, handle, memId, index, timestamp); | |
} else { // batch mode | |
Mutex::Autolock _l(mBatchLock); | |
size_t inflightSize = mInflightBatch.size(); | |
if (inflightSize == 0) { | |
mBatchMsgType = msg_type; | |
} else if (mBatchMsgType != msg_type) { | |
ALOGE("%s: msg_type change (from %d to %d) is not supported!", | |
__FUNCTION__, mBatchMsgType, msg_type); | |
return; | |
} | |
mInflightBatch.push_back({handle, memId, index, timestamp}); | |
// Send batched frames to camera framework | |
if (mInflightBatch.size() >= batchSize) { | |
mDeviceCallback->handleCallbackTimestampBatch( | |
(DataCallbackMsg) mBatchMsgType, mInflightBatch); | |
mInflightBatch.clear(); | |
} | |
} | |
} | |
void CameraDevice::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type, | |
const camera_memory_t *data, unsigned index, void *user) { | |
ALOGV("%s", __FUNCTION__); | |
CameraDevice* object = static_cast<CameraDevice*>(user); | |
// Start refcounting the heap object from here on. When the clients | |
// drop all references, it will be destroyed (as well as the enclosed | |
// MemoryHeapBase. | |
sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory*>(data->handle)); | |
if (index >= mem->mNumBufs) { | |
ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__, | |
index, mem->mNumBufs); | |
return; | |
} | |
native_handle_t* handle = nullptr; | |
if (object->mMetadataMode) { | |
if (mem->mBufSize == sizeof(VideoNativeHandleMetadata)) { | |
VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) | |
((uint8_t*) mem->mHidlHeapMemData + index * mem->mBufSize); | |
if (md->eType == kMetadataBufferTypeNativeHandleSource) { | |
handle = md->pHandle; | |
} | |
} | |
} | |
if (object->mDeviceCallback != nullptr) { | |
if (handle == nullptr) { | |
object->mDeviceCallback->dataCallbackTimestamp( | |
(DataCallbackMsg) msg_type, mem->handle.mId, index, timestamp); | |
} else { | |
object->handleCallbackTimestamp(timestamp, msg_type, mem->handle.mId, index, handle); | |
} | |
} | |
} | |
void CameraDevice::initHalPreviewWindow() | |
{ | |
mHalPreviewWindow.cancel_buffer = sCancelBuffer; | |
mHalPreviewWindow.lock_buffer = sLockBuffer; | |
mHalPreviewWindow.dequeue_buffer = sDequeueBuffer; | |
mHalPreviewWindow.enqueue_buffer = sEnqueueBuffer; | |
mHalPreviewWindow.set_buffer_count = sSetBufferCount; | |
mHalPreviewWindow.set_buffers_geometry = sSetBuffersGeometry; | |
mHalPreviewWindow.set_crop = sSetCrop; | |
mHalPreviewWindow.set_timestamp = sSetTimestamp; | |
mHalPreviewWindow.set_usage = sSetUsage; | |
mHalPreviewWindow.set_swap_interval = sSetSwapInterval; | |
mHalPreviewWindow.get_min_undequeued_buffer_count = | |
sGetMinUndequeuedBufferCount; | |
} | |
// Methods from ::android::hardware::camera::device::V1_0::ICameraDevice follow. | |
Return<void> CameraDevice::getResourceCost(getResourceCost_cb _hidl_cb) { | |
Status status = initStatus(); | |
CameraResourceCost resCost; | |
if (status == Status::OK) { | |
int cost = 100; | |
std::vector<std::string> conflicting_devices; | |
struct camera_info info; | |
// If using post-2.4 module version, query the cost + conflicting devices from the HAL | |
if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) { | |
int ret = mModule->getCameraInfo(mCameraIdInt, &info); | |
if (ret == OK) { | |
cost = info.resource_cost; | |
for (size_t i = 0; i < info.conflicting_devices_length; i++) { | |
std::string cameraId(info.conflicting_devices[i]); | |
for (const auto& pair : mCameraDeviceNames) { | |
if (cameraId == pair.first) { | |
conflicting_devices.push_back(pair.second); | |
} | |
} | |
} | |
} else { | |
status = Status::INTERNAL_ERROR; | |
} | |
} | |
if (status == Status::OK) { | |
resCost.resourceCost = cost; | |
resCost.conflictingDevices.resize(conflicting_devices.size()); | |
for (size_t i = 0; i < conflicting_devices.size(); i++) { | |
resCost.conflictingDevices[i] = conflicting_devices[i]; | |
ALOGV("CamDevice %s is conflicting with camDevice %s", | |
mCameraId.c_str(), resCost.conflictingDevices[i].c_str()); | |
} | |
} | |
} | |
_hidl_cb(status, resCost); | |
return Void(); | |
} | |
Return<void> CameraDevice::getCameraInfo(getCameraInfo_cb _hidl_cb) { | |
Status status = initStatus(); | |
CameraInfo cameraInfo; | |
if (status == Status::OK) { | |
struct camera_info info; | |
int ret = mModule->getCameraInfo(mCameraIdInt, &info); | |
if (ret == OK) { | |
cameraInfo.facing = (CameraFacing) info.facing; | |
// Device 1.0 does not support external camera facing. | |
// The closest approximation would be front camera. | |
if (cameraInfo.facing == CameraFacing::EXTERNAL) { | |
cameraInfo.facing = CameraFacing::FRONT; | |
} | |
cameraInfo.orientation = info.orientation; | |
} else { | |
ALOGE("%s: get camera info failed!", __FUNCTION__); | |
status = Status::INTERNAL_ERROR; | |
} | |
} | |
_hidl_cb(status, cameraInfo); | |
return Void(); | |
} | |
Return<Status> CameraDevice::setTorchMode(TorchMode mode) { | |
if (!mModule->isSetTorchModeSupported()) { | |
return Status::METHOD_NOT_SUPPORTED; | |
} | |
Status status = initStatus(); | |
if (status == Status::OK) { | |
bool enable = (mode == TorchMode::ON) ? true : false; | |
status = getHidlStatus(mModule->setTorchMode(mCameraId.c_str(), enable)); | |
} | |
return status; | |
} | |
Return<Status> CameraDevice::dumpState(const hidl_handle& handle) { | |
Mutex::Autolock _l(mLock); | |
if (handle.getNativeHandle() == nullptr) { | |
ALOGE("%s: handle must not be null", __FUNCTION__); | |
return Status::ILLEGAL_ARGUMENT; | |
} | |
if (handle->numFds != 1 || handle->numInts != 0) { | |
ALOGE("%s: handle must contain 1 FD and 0 integers! Got %d FDs and %d ints", | |
__FUNCTION__, handle->numFds, handle->numInts); | |
return Status::ILLEGAL_ARGUMENT; | |
} | |
int fd = handle->data[0]; | |
if (mDevice != nullptr) { | |
if (mDevice->ops->dump) { // It's fine if the HAL doesn't implement dump() | |
return getHidlStatus(mDevice->ops->dump(mDevice, fd)); | |
} | |
} | |
return Status::OK; | |
} | |
Return<Status> CameraDevice::open(const sp<ICameraDeviceCallback>& callback) { | |
ALOGI("Opening camera %s", mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
camera_info info; | |
status_t res = mModule->getCameraInfo(mCameraIdInt, &info); | |
if (res != OK) { | |
ALOGE("Could not get camera info: %s: %d", mCameraId.c_str(), res); | |
return getHidlStatus(res); | |
} | |
int rc = OK; | |
if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 && | |
info.device_version > CAMERA_DEVICE_API_VERSION_1_0) { | |
// Open higher version camera device as HAL1.0 device. | |
rc = mModule->openLegacy(mCameraId.c_str(), | |
CAMERA_DEVICE_API_VERSION_1_0, | |
(hw_device_t **)&mDevice); | |
} else { | |
rc = mModule->open(mCameraId.c_str(), (hw_device_t **)&mDevice); | |
} | |
if (rc != OK) { | |
mDevice = nullptr; | |
ALOGE("Could not open camera %s: %d", mCameraId.c_str(), rc); | |
return getHidlStatus(rc); | |
} | |
initHalPreviewWindow(); | |
mDeviceCallback = callback; | |
if (mDevice->ops->set_callbacks) { | |
mDevice->ops->set_callbacks(mDevice, | |
sNotifyCb, sDataCb, sDataCbTimestamp, sGetMemory, this); | |
} | |
return getHidlStatus(rc); | |
} | |
Return<Status> CameraDevice::setPreviewWindow(const sp<ICameraDevicePreviewCallback>& window) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
mHalPreviewWindow.mPreviewCallback = window; | |
if (mDevice->ops->set_preview_window) { | |
return getHidlStatus(mDevice->ops->set_preview_window(mDevice, | |
(window == nullptr) ? nullptr : &mHalPreviewWindow)); | |
} | |
return Status::INTERNAL_ERROR; // HAL should provide set_preview_window | |
} | |
Return<void> CameraDevice::enableMsgType(uint32_t msgType) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Void(); | |
} | |
if (mDevice->ops->enable_msg_type) { | |
mDevice->ops->enable_msg_type(mDevice, msgType); | |
} | |
return Void(); | |
} | |
Return<void> CameraDevice::disableMsgType(uint32_t msgType) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Void(); | |
} | |
if (mDevice->ops->disable_msg_type) { | |
mDevice->ops->disable_msg_type(mDevice, msgType); | |
} | |
return Void(); | |
} | |
Return<bool> CameraDevice::msgTypeEnabled(uint32_t msgType) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return false; | |
} | |
if (mDevice->ops->msg_type_enabled) { | |
return mDevice->ops->msg_type_enabled(mDevice, msgType); | |
} | |
return false; | |
} | |
Return<Status> CameraDevice::startPreview() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
if (mDevice->ops->start_preview) { | |
return getHidlStatus(mDevice->ops->start_preview(mDevice)); | |
} | |
return Status::INTERNAL_ERROR; // HAL should provide start_preview | |
} | |
Return<void> CameraDevice::stopPreview() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Void(); | |
} | |
if (mDevice->ops->stop_preview) { | |
mDevice->ops->stop_preview(mDevice); | |
} | |
return Void(); | |
} | |
Return<bool> CameraDevice::previewEnabled() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return false; | |
} | |
if (mDevice->ops->preview_enabled) { | |
return mDevice->ops->preview_enabled(mDevice); | |
} | |
return false; | |
} | |
Return<Status> CameraDevice::storeMetaDataInBuffers(bool enable) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
if (mDevice->ops->store_meta_data_in_buffers) { | |
status_t s = mDevice->ops->store_meta_data_in_buffers(mDevice, enable); | |
if (s == OK && enable) { | |
mMetadataMode = true; | |
} | |
return getHidlStatus(s); | |
} | |
return enable ? Status::ILLEGAL_ARGUMENT : Status::OK; | |
} | |
Return<Status> CameraDevice::startRecording() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
if (mDevice->ops->start_recording) { | |
return getHidlStatus(mDevice->ops->start_recording(mDevice)); | |
} | |
return Status::ILLEGAL_ARGUMENT; | |
} | |
Return<void> CameraDevice::stopRecording() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Void(); | |
} | |
if (mDevice->ops->stop_recording) { | |
mDevice->ops->stop_recording(mDevice); | |
} | |
return Void(); | |
} | |
Return<bool> CameraDevice::recordingEnabled() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return false; | |
} | |
if (mDevice->ops->recording_enabled) { | |
return mDevice->ops->recording_enabled(mDevice); | |
} | |
return false; | |
} | |
void CameraDevice::releaseRecordingFrameLocked( | |
uint32_t memId, uint32_t bufferIndex, const native_handle_t* handle) { | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return; | |
} | |
if (mDevice->ops->release_recording_frame) { | |
CameraHeapMemory* camMemory; | |
{ | |
Mutex::Autolock _l(mMemoryMapLock); | |
auto it = mMemoryMap.find(memId); | |
if (it == mMemoryMap.end() || it->second == nullptr) { | |
ALOGE("%s unknown memoryId %d", __FUNCTION__, memId); | |
return; | |
} | |
camMemory = it->second; | |
} | |
if (bufferIndex >= camMemory->mNumBufs) { | |
ALOGE("%s: bufferIndex %d exceeds number of buffers %d", | |
__FUNCTION__, bufferIndex, camMemory->mNumBufs); | |
return; | |
} | |
void *data = ((uint8_t *) camMemory->mHidlHeapMemData) + bufferIndex * camMemory->mBufSize; | |
if (handle) { | |
VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) data; | |
if (md->eType == kMetadataBufferTypeNativeHandleSource) { | |
// Input handle will be closed by HIDL transport later, so clone it | |
// HAL implementation is responsible to close/delete the clone | |
native_handle_t* clone = native_handle_clone(handle); | |
if (!clone) { | |
ALOGE("%s: failed to clone buffer %p", __FUNCTION__, handle); | |
return; | |
} | |
md->pHandle = clone; | |
} else { | |
ALOGE("%s:Malform VideoNativeHandleMetadata at memId %d, bufferId %d", | |
__FUNCTION__, memId, bufferIndex); | |
return; | |
} | |
} | |
mDevice->ops->release_recording_frame(mDevice, data); | |
} | |
} | |
Return<void> CameraDevice::releaseRecordingFrame(uint32_t memId, uint32_t bufferIndex) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
releaseRecordingFrameLocked(memId, bufferIndex, nullptr); | |
return Void(); | |
} | |
Return<void> CameraDevice::releaseRecordingFrameHandle( | |
uint32_t memId, uint32_t bufferIndex, const hidl_handle& frame) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
releaseRecordingFrameLocked( | |
memId, bufferIndex, frame.getNativeHandle()); | |
return Void(); | |
} | |
Return<void> CameraDevice::releaseRecordingFrameHandleBatch( | |
const hidl_vec<VideoFrameMessage>& msgs) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
for (auto& msg : msgs) { | |
releaseRecordingFrameLocked( | |
msg.data, msg.bufferIndex, msg.frameData.getNativeHandle()); | |
} | |
return Void(); | |
} | |
Return<Status> CameraDevice::autoFocus() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
if (mDevice->ops->auto_focus) { | |
return getHidlStatus(mDevice->ops->auto_focus(mDevice)); | |
} | |
return Status::ILLEGAL_ARGUMENT; | |
} | |
Return<Status> CameraDevice::cancelAutoFocus() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
if (mDevice->ops->cancel_auto_focus) { | |
return getHidlStatus(mDevice->ops->cancel_auto_focus(mDevice)); | |
} | |
return Status::ILLEGAL_ARGUMENT; | |
} | |
Return<Status> CameraDevice::takePicture() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
if (mDevice->ops->take_picture) { | |
return getHidlStatus(mDevice->ops->take_picture(mDevice)); | |
} | |
return Status::ILLEGAL_ARGUMENT; | |
} | |
Return<Status> CameraDevice::cancelPicture() { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
if (mDevice->ops->cancel_picture) { | |
return getHidlStatus(mDevice->ops->cancel_picture(mDevice)); | |
} | |
return Status::ILLEGAL_ARGUMENT; | |
} | |
Return<Status> CameraDevice::setParameters(const hidl_string& params) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
if (mDevice->ops->set_parameters) { | |
return getHidlStatus(mDevice->ops->set_parameters(mDevice, params.c_str())); | |
} | |
return Status::ILLEGAL_ARGUMENT; | |
} | |
Return<void> CameraDevice::getParameters(getParameters_cb _hidl_cb) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
hidl_string outStr; | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
_hidl_cb(outStr); | |
return Void(); | |
} | |
if (mCameraId == "0") | |
outStr = "ae-bracket-hdr=Off;ae-bracket-hdr-values=Off,AE-Bracket;af-bracket=af-bracket-off;af-bracket-values=af-bracket-off,af-bracket-on;antibanding=auto;antibanding-values=off,60hz,50hz,auto;auto-dc-offset-mode=on;auto-dc-offset-mode-values=off,on;auto-exposure=center-weighted;auto-exposure-lock=false;auto-exposure-lock-supported=true;auto-exposure-values=frame-average,center-weighted,spot-metering,center-weighted,spot-metering-adv,center-weighted-adv;auto-hdr-supported=true;auto-whitebalance-lock=false;auto-whitebalance-lock-supported=true;avtimer=disable;background-proc=on;brightness-step=1;burst-max-fps=80;burst-status=off;burst-status-values=off,on;cache-video-buffers=disable;camera-mode=0;cds-mode-values=off,on,auto;chroma-flash=chroma-flash-off;chroma-flash-values=chroma-flash-off,chroma-flash-on;contrast=5;contrast-step=1;dbg-log-aec=off;dbg-log-aec-values=on,off;dbg-log-af=off;dbg-log-af-values=on,off;dbg-log-awb=off;dbg-log-awb-values=on,off;denoise=denoise-on;denoise-values=denoise-off,denoise-on;dis=disable;dis-values=enable,disable;effect=none;effect-values=none,mono,negative,solarize,sepia,posterize,whiteboard,blackboard,aqua,emboss,sketch,neon;exposure-compensation=0;exposure-compensation-step=0.166667;face-detection=off;face-detection-values=off,on;flash-mode=off;flash-mode-values=off,auto,on,torch;flip-mode-values=off,flip-v,flip-h,flip-vh;focal-length=3.68;focus-areas=(0,0,0,0,0);focus-distances=Infinity,Infinity,Infinity;focus-mode=auto;focus-mode-values=auto,infinity,fixed,macro,continuous-video,continuous-picture,manual;hdr-mode=hdr-mode-multiframe;hdr-mode-values=hdr-mode-sensor,hdr-mode-multiframe;hdr-need-1x=false;hdr-need-1x-values=false,true;hfr-size-values=1920x1080,1280x720;histogram=disable;histogram-values=enable,disable;horizontal-view-angle=64.85;instant-aec-values=;instant-capture-values=;internal-restart=true;iso=auto;iso-values=auto,ISO_HJR,ISO50,ISO100,ISO200,ISO400,ISO800,ISO1600,ISO3200;jpeg-quality=95;jpeg-thumbnail-height=384;jpeg-thumbnail-quality=85;jpeg-thumbnail-size-values=512x384,512x288,0x0;jpeg-thumbnail-width=512;jsaudio=off;jsaudio-values=off,on;jsreplace=on;jsreplace-values=off,on;jsvideo=off;jsvideo-values=off,on;lensshade=enable;lensshade-values=enable,disable;long-shot=off;longshot-supported=true;luma-adaptation=3;manual-dc-offset=0;manual-dc-offset-max=0;manual-dc-offset-min=-40;manual-dc-offset-step=1;manual-exposure-modes=off,exp-time-priority,iso-priority,user-setting;manual-focus-modes=off,scale-mode,diopter-mode;manual-wb-modes=off,color-temperature,rbgb-gains;max-brightness=6;max-contrast=10;max-exposure-compensation=12;max-exposure-time=500.000000;max-focus-pos-dac=1023;max-focus-pos-diopter=10;max-focus-pos-index=1023;max-focus-pos-ratio=100;max-iso=4697;max-num-detected-faces-hw=32;max-num-detected-faces-sw=32;max-num-focus-areas=1;max-num-metering-areas=1;max-saturation=10;max-sce-factor=100;max-sharpness=36;max-wb-cct=8000;max-wb-gain=4;max-zoom=90;mce=enable;mce-values=enable,disable;metering-areas=(0,0,0,0,0);min-brightness=0;min-contrast=0;min-exposure-compensation=-12;min-exposure-time=0.010486;min-focus-pos-dac=0;min-focus-pos-diopter=0;min-focus-pos-index=0;min-focus-pos-ratio=0;min-iso=48;min-saturation=0;min-sce-factor=-100;min-sharpness=0;min-wb-cct=2000;min-wb-gain=1;mot-barcodes-supported=false;mot-beauty=off;mot-beauty-level=5;mot-beauty-limitfps-need=false;mot-beauty-maxfps=22;mot-beauty-values=off;mot-max-still-fps=30;mot-mcas-mode=on;mot-mcas-mode-values=off,on;mot-sensor-video-hdr-supported-sizes=1920x1080x30,3840x2160x30;num-retro-burst-per-shutter=0;num-snaps-per-shutter=1;opti-zoom=opti-zoom-off;opti-zoom-values=opti-zoom-off,opti-zoom-on;picture-format=jpeg;picture-format-values=jpeg;picture-size=4160x3120;picture-size-values=4160x3120,4160x2340,3840x2160,3264x2448,3264x1836,2592x1944,2592x1458,1920x1080,1440x1080,1280x960,1280x720,720x480,640x480,352x288,320x240,176x144;preferred-preview-size-for-video=1920x1080;preview-flip=off;preview-format=yuv420sp;preview-format-values=yuv420sp,yuv420p;preview-fps-range=4000,30000;preview-fps-range-values=(15000,15000),(15000,20000),(20000,20000),(4000,30000),(30000,30000),(9000,30000),(15000,30000),(24000,30000);preview-frame-rate=30;preview-frame-rate-values=4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30;preview-hist=preview-hist-off;preview-hist-values=preview-hist-off,preview-hist-on;preview-size=1920x1080;preview-size-values=1920x1080,1440x1080,1280x720,960x720,768x432,720x480,640x480,320x240,176x144;qc-camera-features=1011613183;qc-max-num-requested-faces=32;raw-size=4208x3120;rdi-mode=disable;rdi-mode-values=enable,disable;re-focus=re-focus-off;re-focus-values=re-focus-off,re-focus-on;redeye-reduction=disable;redeye-reduction-values=enable,disable;saturation=5;saturation-step=1;sce-factor-step=10;scene-detect=off;scene-detect-values=off,on;scene-mode=auto;scene-mode-values=auto,hdr,auto_hdr;scene-selection=disable;secure-mode=disable;secure-mode-values=enable,disable;selectable-zone-af=auto;selectable-zone-af-values=auto,spot-metering,center-weighted,frame-average;sensor-hdr=off;sensor-hdr-values=off,on;sharpness=12;sharpness-step=6;skinToneEnhancement=0;skinToneEnhancement-values=enable,disable;smooth-zoom-supported=true;snapshot-burst-num=0;snapshot-picture-flip=off;still-more=still-more-off;still-more-values=still-more-off,still-more-on;supported-live-snapshot-sizes=4160x2340,3840x2160,3264x2448,3264x1836,2592x1944,2592x1458,1920x1080,1440x1080,1280x960,1280x720,1024x768,864x480,720x480,640x480,352x288,320x240;tintless=on;tintless-values=off,on;tnr-mode-values=off,on;touch-af-aec=touch-off;touch-af-aec-values=touch-off,touch-on;true-portrait-values=true-portrait-off,true-portrait-on;vertical-view-angle=50.95;video-batch-size=0;video-cds-mode-values=off,on,auto;video-flip=off;video-frame-format=android-opaque;video-hdr=off;video-hdr-values=off,on;video-hfr=off;video-hfr-values=60,120,off;video-hsr=off;video-rotation=0;video-rotation-values=0,90,180,270;video-size-values=3840x2160,1920x1080,1280x720,864x480,720x480,640x480,352x288,320x240,176x144;video-snapshot-supported=true;video-stabilization=false;video-stabilization-supported=true;video-tnr-mode-values=off,on;visionfw=off;visionfw-values=off,on;whitebalance=auto;whitebalance-values=auto,incandescent,fluorescent,warm-fluorescent,daylight,cloudy-daylight,twilight,shade,manual;zoom=0;zoom-ratios=100,102,104,107,109,112,114,117,120,123,125,128,131,135,138,141,144,148,151,155,158,162,166,170,174,178,182,186,190,195,200,204,209,214,219,224,229,235,240,246,251,257,263,270,276,282,289,296,303,310,317,324,332,340,348,356,364,373,381,390,400,409,418,428,438,448,459,470,481,492,503,515,527,540,552,565,578,592,606,620,634,649,664,680,696,712,729,746,763,781,800;zoom-supported=true;zsl=on;zsl-hdr-supported=true;zsl-values=off,on"; | |
if (mCameraId == "1") | |
outStr = "ae-bracket-hdr=Off;ae-bracket-hdr-values=Off,AE-Bracket;antibanding=auto;antibanding-values=off,60hz,50hz,auto;auto-dc-offset-mode=on;auto-dc-offset-mode-values=off,on;auto-exposure=center-weighted;auto-exposure-lock=false;auto-exposure-lock-supported=true;auto-exposure-values=frame-average,center-weighted,spot-metering,center-weighted,spot-metering-adv,center-weighted-adv;auto-hdr-supported=true;auto-whitebalance-lock=false;auto-whitebalance-lock-supported=true;avtimer=disable;background-proc=on;brightness-step=1;burst-max-fps=50;burst-status=off;burst-status-values=off,on;cache-video-buffers=disable;camera-mode=0;cds-mode-values=off,on,auto;chroma-flash=chroma-flash-off;chroma-flash-values=chroma-flash-off,chroma-flash-on;contrast=5;contrast-step=1;dbg-log-aec=off;dbg-log-aec-values=on,off;dbg-log-af=off;dbg-log-af-values=on,off;dbg-log-awb=off;dbg-log-awb-values=on,off;denoise=denoise-on;denoise-values=denoise-off,denoise-on;dis=disable;dis-values=enable,disable;effect=none;effect-values=none,mono,negative,solarize,sepia,posterize,whiteboard,blackboard,aqua,emboss,sketch,neon;exposure-compensation=0;exposure-compensation-step=0.166667;face-detection=off;face-detection-values=off,on;flash-mode=off;flash-mode-values=off,auto,on,torch;flip-mode-values=off,flip-v,flip-h,flip-vh;focal-length=2.448;focus-distances=Infinity,Infinity,Infinity;focus-mode=fixed;focus-mode-values=fixed;hdr-mode=hdr-mode-multiframe;hdr-mode-values=hdr-mode-multiframe;hdr-need-1x=false;hdr-need-1x-values=false,true;hfr-size-values=1280x720;histogram=disable;histogram-values=enable,disable;horizontal-view-angle=72.82;instant-aec-values=;instant-capture-values=;internal-restart=true;iso=auto;iso-values=auto,ISO_HJR,ISO50,ISO100,ISO200,ISO400,ISO800,ISO1600,ISO3200;jpeg-quality=95;jpeg-thumbnail-height=384;jpeg-thumbnail-quality=85;jpeg-thumbnail-size-values=512x384,512x288,0x0;jpeg-thumbnail-width=512;jsaudio=off;jsaudio-values=off,on;jsreplace=on;jsreplace-values=off,on;jsvideo=off;jsvideo-values=off,on;lensshade=enable;lensshade-values=enable,disable;long-shot=off;longshot-supported=true;luma-adaptation=3;manual-dc-offset=0;manual-dc-offset-max=0;manual-dc-offset-min=-40;manual-dc-offset-step=1;manual-exposure-modes=off,exp-time-priority,iso-priority,user-setting;manual-focus-modes=off;manual-wb-modes=off,color-temperature,rbgb-gains;max-brightness=6;max-contrast=10;max-exposure-compensation=12;max-exposure-time=521.395200;max-focus-pos-dac=1023;max-focus-pos-diopter=0;max-focus-pos-index=1023;max-focus-pos-ratio=100;max-iso=1979;max-num-detected-faces-hw=32;max-num-detected-faces-sw=32;max-num-focus-areas=0;max-num-metering-areas=1;max-saturation=10;max-sce-factor=100;max-sharpness=36;max-wb-cct=8000;max-wb-gain=4;max-zoom=90;mce=enable;mce-values=enable,disable;metering-areas=(0,0,0,0,0);min-brightness=0;min-contrast=0;min-exposure-compensation=-12;min-exposure-time=0.016802;min-focus-pos-dac=0;min-focus-pos-diopter=0;min-focus-pos-index=0;min-focus-pos-ratio=0;min-iso=59;min-saturation=0;min-sce-factor=-100;min-sharpness=0;min-wb-cct=2000;min-wb-gain=1;mot-barcodes-supported=false;mot-beauty=off;mot-beauty-level=5;mot-beauty-limitfps-need=false;mot-beauty-maxfps=22;mot-beauty-values=off;mot-max-still-fps=30;mot-mcas-mode=off;mot-mcas-mode-values=off;num-retro-burst-per-shutter=0;num-snaps-per-shutter=1;opti-zoom=opti-zoom-off;opti-zoom-values=opti-zoom-off,opti-zoom-on;picture-format=jpeg;picture-format-values=jpeg;picture-size=2592x1944;picture-size-values=2592x1944,2592x1458,1920x1080,1440x1080,1280x960,1280x720,720x480,640x480,352x288,320x240,176x144;preferred-preview-size-for-video=1920x1080;preview-flip=off;preview-format=yuv420sp;preview-format-values=yuv420sp,yuv420p;preview-fps-range=9000,30000;preview-fps-range-values=(15000,15000),(15000,20000),(20000,20000),(9000,30000),(30000,30000),(15000,30000),(24000,30000);preview-frame-rate=30;preview-frame-rate-values=9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30;preview-hist=preview-hist-off;preview-hist-values=preview-hist-off,preview-hist-on;preview-size=1920x1080;preview-size-values=1920x1080,1440x1080,1280x720,960x720,768x432,720x480,640x480,320x240,176x144;qc-camera-features=1011580159;qc-max-num-requested-faces=32;raw-size=2592x1944;rdi-mode=disable;rdi-mode-values=enable,disable;redeye-reduction=disable;redeye-reduction-values=enable,disable;saturation=5;saturation-step=1;sce-factor-step=10;scene-detect=off;scene-detect-values=off,on;scene-mode=auto;scene-mode-values=auto,hdr,auto_hdr;scene-selection=disable;secure-mode=disable;secure-mode-values=enable,disable;selectable-zone-af=auto;selectable-zone-af-values=auto,spot-metering,center-weighted,frame-average;sharpness=12;sharpness-step=6;skinToneEnhancement=0;skinToneEnhancement-values=enable,disable;smooth-zoom-supported=true;snapshot-burst-num=0;snapshot-picture-flip=off;still-more=still-more-off;still-more-values=still-more-off,still-more-on;supported-live-snapshot-sizes=2592x1944,2592x1458,1920x1080,1440x1080,1280x960,1280x720,1024x768,864x480,720x480,640x480,352x288,320x240;tintless=on;tintless-values=off,on;tnr-mode-values=off,on;touch-af-aec=touch-off;touch-af-aec-values=touch-off,touch-on;true-portrait-values=true-portrait-off,true-portrait-on;vertical-view-angle=57.9;video-batch-size=0;video-cds-mode-values=off,on,auto;video-flip=off;video-frame-format=android-opaque;video-hfr=off;video-hfr-values=120,off;video-hsr=off;video-rotation=0;video-rotation-values=0,90,180,270;video-size-values=1920x1080,1280x720,864x480,720x480,640x480,352x288,320x240,176x144;video-snapshot-supported=true;video-stabilization-supported=false;video-tnr-mode-values=off,on;visionfw=off;visionfw-values=off,on;whitebalance=auto;whitebalance-values=auto,incandescent,fluorescent,warm-fluorescent,daylight,cloudy-daylight,twilight,shade,manual;zoom=0;zoom-ratios=100,102,104,107,109,112,114,117,120,123,125,128,131,135,138,141,144,148,151,155,158,162,166,170,174,178,182,186,190,195,200,204,209,214,219,224,229,235,240,246,251,257,263,270,276,282,289,296,303,310,317,324,332,340,348,356,364,373,381,390,400,409,418,428,438,448,459,470,481,492,503,515,527,540,552,565,578,592,606,620,634,649,664,680,696,712,729,746,763,781,800;zoom-supported=true;zsl=on;zsl-hdr-supported=true;zsl-values=off,on"; | |
_hidl_cb(outStr); | |
return Void(); | |
} | |
Return<Status> CameraDevice::sendCommand(CommandType cmd, int32_t arg1, int32_t arg2) { | |
ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); | |
Mutex::Autolock _l(mLock); | |
if (!mDevice) { | |
ALOGE("%s called while camera is not opened", __FUNCTION__); | |
return Status::OPERATION_NOT_SUPPORTED; | |
} | |
if (mDevice->ops->send_command) { | |
return getHidlStatus(mDevice->ops->send_command(mDevice, (int32_t) cmd, arg1, arg2)); | |
} | |
return Status::ILLEGAL_ARGUMENT; | |
} | |
Return<void> CameraDevice::close() { | |
Mutex::Autolock _l(mLock); | |
closeLocked(); | |
return Void(); | |
} | |
void CameraDevice::closeLocked() { | |
ALOGI("Closing camera %s", mCameraId.c_str()); | |
if(mDevice) { | |
int rc = mDevice->common.close(&mDevice->common); | |
if (rc != OK) { | |
ALOGE("Could not close camera %s: %d", mCameraId.c_str(), rc); | |
} | |
mDevice = nullptr; | |
} | |
} | |
} // namespace implementation | |
} // namespace V1_0 | |
} // namespace device | |
} // namespace camera | |
} // namespace hardware | |
} // namespace android |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment