blob: 5c4723ddad25ece208e6094195babd2b77293d7a [file] [log] [blame]
Yin-Chia Yeh248ed702017-01-23 17:27:26 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "CamDev@1.0-impl"
18#include <utils/Log.h>
19#include <hardware/camera.h>
20#include <hardware/gralloc1.h>
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -070021#include <hidlmemory/mapping.h>
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080022#include <utils/Trace.h>
23
Eino-Ville Talvala2d80c0d2017-03-23 15:39:12 -070024#include <grallocusage/GrallocUsageConversion.h>
25
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080026#include "CameraDevice_1_0.h"
27
28namespace android {
29namespace hardware {
30namespace camera {
31namespace device {
32namespace V1_0 {
33namespace implementation {
34
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080035using ::android::hardware::graphics::common::V1_0::PixelFormat;
36
37HandleImporter& CameraDevice::sHandleImporter = HandleImporter::getInstance();
38
39Status CameraDevice::getHidlStatus(const int& status) {
40 switch (status) {
41 case 0: return Status::OK;
42 case -ENOSYS: return Status::OPERATION_NOT_SUPPORTED;
43 case -EBUSY : return Status::CAMERA_IN_USE;
44 case -EUSERS: return Status::MAX_CAMERAS_IN_USE;
45 case -ENODEV: return Status::INTERNAL_ERROR;
46 case -EINVAL: return Status::ILLEGAL_ARGUMENT;
47 default:
48 ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
49 return Status::INTERNAL_ERROR;
50 }
51}
52
53status_t CameraDevice::getStatusT(const Status& s) {
54 switch(s) {
55 case Status::OK:
56 return OK;
57 case Status::ILLEGAL_ARGUMENT:
58 return BAD_VALUE;
59 case Status::CAMERA_IN_USE:
60 return -EBUSY;
61 case Status::MAX_CAMERAS_IN_USE:
62 return -EUSERS;
63 case Status::METHOD_NOT_SUPPORTED:
64 return UNKNOWN_TRANSACTION;
65 case Status::OPERATION_NOT_SUPPORTED:
66 return INVALID_OPERATION;
67 case Status::CAMERA_DISCONNECTED:
68 return DEAD_OBJECT;
69 case Status::INTERNAL_ERROR:
70 return INVALID_OPERATION;
71 }
72 ALOGW("Unexpected HAL status code %d", s);
73 return INVALID_OPERATION;
74}
75
76Status CameraDevice::initStatus() const {
77 Mutex::Autolock _l(mLock);
78 Status status = Status::OK;
79 if (mInitFail) {
80 status = Status::INTERNAL_ERROR;
81 } else if (mDisconnected) {
82 status = Status::CAMERA_DISCONNECTED;
83 }
84 return status;
85}
86
87CameraDevice::CameraDevice(
88 sp<CameraModule> module, const std::string& cameraId,
89 const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames) :
90 mModule(module),
91 mCameraId(cameraId),
92 mDisconnected(false),
93 mCameraDeviceNames(cameraDeviceNames) {
94 mCameraIdInt = atoi(mCameraId.c_str());
95 // Should not reach here as provider also validate ID
96 if (mCameraIdInt < 0 || mCameraIdInt >= module->getNumberOfCameras()) {
97 ALOGE("%s: Invalid camera id: %s", __FUNCTION__, mCameraId.c_str());
98 mInitFail = true;
99 }
100
101 mDeviceVersion = mModule->getDeviceVersion(mCameraIdInt);
102 if (mDeviceVersion != CAMERA_DEVICE_API_VERSION_1_0 && !mModule->isOpenLegacyDefined()) {
103 ALOGI("%s: Camera id %s does not support HAL1.0",
104 __FUNCTION__, mCameraId.c_str());
105 mInitFail = true;
106 }
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700107
108 mAshmemAllocator = IAllocator::getService("ashmem");
109 if (mAshmemAllocator == nullptr) {
110 ALOGI("%s: cannot get ashmemAllocator", __FUNCTION__);
111 mInitFail = true;
112 }
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800113}
114
115CameraDevice::~CameraDevice() {
116 Mutex::Autolock _l(mLock);
117 if (mDevice != nullptr) {
118 ALOGW("%s: camera %s is deleted while open", __FUNCTION__, mCameraId.c_str());
119 close();
120 }
121 mHalPreviewWindow.cleanUpCirculatingBuffers();
122}
123
124
125void CameraDevice::setConnectionStatus(bool connected) {
126 Mutex::Autolock _l(mLock);
127 mDisconnected = !connected;
128 if (mDevice == nullptr) {
129 return;
130 }
131 if (!connected) {
132 ALOGW("%s: camera %s is disconneted. Closing", __FUNCTION__, mCameraId.c_str());
133 close();
134 }
135 return;
136}
137
138void CameraDevice::CameraPreviewWindow::cleanUpCirculatingBuffers() {
139 Mutex::Autolock _l(mLock);
140 for (auto pair : mCirculatingBuffers) {
141 sHandleImporter.freeBuffer(pair.second);
142 }
143 mCirculatingBuffers.clear();
144 mBufferIdMap.clear();
145}
146
147int CameraDevice::sDequeueBuffer(struct preview_stream_ops* w,
148 buffer_handle_t** buffer, int *stride) {
149 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
150 if (object->mPreviewCallback == nullptr) {
151 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
152 return INVALID_OPERATION;
153 }
154
155 if (buffer == nullptr || stride == nullptr) {
156 ALOGE("%s: buffer (%p) and stride (%p) must not be null!", __FUNCTION__, buffer, stride);
157 return BAD_VALUE;
158 }
159
160 Status s;
161 object->mPreviewCallback->dequeueBuffer(
162 [&](auto status, uint64_t bufferId, const auto& buf, uint32_t strd) {
163 s = status;
164 if (s == Status::OK) {
165 Mutex::Autolock _l(object->mLock);
166 if (object->mCirculatingBuffers.count(bufferId) == 0) {
167 buffer_handle_t importedBuf = buf.getNativeHandle();
168 sHandleImporter.importBuffer(importedBuf);
169 if (importedBuf == nullptr) {
170 ALOGE("%s: preview buffer import failed!", __FUNCTION__);
171 s = Status::INTERNAL_ERROR;
172 return;
173 } else {
174 object->mCirculatingBuffers[bufferId] = importedBuf;
175 object->mBufferIdMap[&(object->mCirculatingBuffers[bufferId])] = bufferId;
176 }
177 }
178 *buffer = &(object->mCirculatingBuffers[bufferId]);
179 *stride = strd;
180 }
181 });
182 return getStatusT(s);
183}
184
185int CameraDevice::sLockBuffer(struct preview_stream_ops*, buffer_handle_t*) {
186 // TODO: make sure lock_buffer is indeed a no-op (and will always be)
187 return 0;
188}
189
190int CameraDevice::sEnqueueBuffer(struct preview_stream_ops* w, buffer_handle_t* buffer) {
191 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
192 if (object->mPreviewCallback == nullptr) {
193 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
194 return INVALID_OPERATION;
195 }
196 uint64_t bufferId = object->mBufferIdMap.at(buffer);
197 return getStatusT(object->mPreviewCallback->enqueueBuffer(bufferId));
198}
199
200int CameraDevice::sCancelBuffer(struct preview_stream_ops* w, buffer_handle_t* buffer) {
201 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
202 if (object->mPreviewCallback == nullptr) {
203 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
204 return INVALID_OPERATION;
205 }
206 uint64_t bufferId = object->mBufferIdMap.at(buffer);
207 return getStatusT(object->mPreviewCallback->cancelBuffer(bufferId));
208}
209
210int CameraDevice::sSetBufferCount(struct preview_stream_ops* w, int count) {
211 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
212 if (object->mPreviewCallback == nullptr) {
213 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
214 return INVALID_OPERATION;
215 }
216
217 object->cleanUpCirculatingBuffers();
218 return getStatusT(object->mPreviewCallback->setBufferCount(count));
219}
220
221int CameraDevice::sSetBuffersGeometry(struct preview_stream_ops* w,
222 int width, int height, int format) {
223 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
224 if (object->mPreviewCallback == nullptr) {
225 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
226 return INVALID_OPERATION;
227 }
228
229 object->cleanUpCirculatingBuffers();
230 return getStatusT(
231 object->mPreviewCallback->setBuffersGeometry(width, height, (PixelFormat) format));
232}
233
234int CameraDevice::sSetCrop(struct preview_stream_ops *w,
235 int left, int top, int right, int bottom) {
236 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
237 if (object->mPreviewCallback == nullptr) {
238 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
239 return INVALID_OPERATION;
240 }
241
242 return getStatusT(object->mPreviewCallback->setCrop(left, top, right, bottom));
243}
244
245int CameraDevice::sSetTimestamp(struct preview_stream_ops *w, int64_t timestamp) {
246 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
247 if (object->mPreviewCallback == nullptr) {
248 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
249 return INVALID_OPERATION;
250 }
251
252 return getStatusT(object->mPreviewCallback->setTimestamp(timestamp));
253}
254
255int CameraDevice::sSetUsage(struct preview_stream_ops* w, int usage) {
256 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
257 if (object->mPreviewCallback == nullptr) {
258 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
259 return INVALID_OPERATION;
260 }
261
262 object->cleanUpCirculatingBuffers();
Eino-Ville Talvala2d80c0d2017-03-23 15:39:12 -0700263 ProducerUsageFlags producerUsage;
264 uint64_t consumerUsage;
265 ::android_convertGralloc0To1Usage(usage, &producerUsage, &consumerUsage);
266 return getStatusT(object->mPreviewCallback->setUsage(producerUsage));
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800267}
268
269int CameraDevice::sSetSwapInterval(struct preview_stream_ops *w, int interval) {
270 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
271 if (object->mPreviewCallback == nullptr) {
272 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
273 return INVALID_OPERATION;
274 }
275
276 return getStatusT(object->mPreviewCallback->setSwapInterval(interval));
277}
278
279int CameraDevice::sGetMinUndequeuedBufferCount(
280 const struct preview_stream_ops *w,
281 int *count) {
282 const CameraPreviewWindow* object = static_cast<const CameraPreviewWindow*>(w);
283 if (object->mPreviewCallback == nullptr) {
284 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
285 return INVALID_OPERATION;
286 }
287 if (count == nullptr) {
288 ALOGE("%s: count is null!", __FUNCTION__);
289 return BAD_VALUE;
290 }
291
292 Status s;
293 object->mPreviewCallback->getMinUndequeuedBufferCount(
294 [&](auto status, uint32_t cnt) {
295 s = status;
296 if (s == Status::OK) {
297 *count = cnt;
298 }
299 });
300 return getStatusT(s);
301}
302
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700303CameraDevice::CameraHeapMemory::CameraHeapMemory(
304 int fd, size_t buf_size, uint_t num_buffers) :
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800305 mBufSize(buf_size),
306 mNumBufs(num_buffers) {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700307 mHidlHandle = native_handle_create(1,0);
308 mHidlHandle->data[0] = fcntl(fd, F_DUPFD_CLOEXEC, 0);
309 const size_t pagesize = getpagesize();
310 size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1));
311 mHidlHeap = hidl_memory("ashmem", mHidlHandle, size);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800312 commonInitialization();
313}
314
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700315CameraDevice::CameraHeapMemory::CameraHeapMemory(
316 sp<IAllocator> ashmemAllocator,
317 size_t buf_size, uint_t num_buffers) :
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800318 mBufSize(buf_size),
319 mNumBufs(num_buffers) {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700320 const size_t pagesize = getpagesize();
321 size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1));
322 ashmemAllocator->allocate(size,
323 [&](bool success, const hidl_memory& mem) {
324 if (!success) {
325 ALOGE("%s: allocating ashmem of %zu bytes failed!",
326 __FUNCTION__, buf_size * num_buffers);
327 return;
328 }
329 mHidlHandle = native_handle_clone(mem.handle());
330 mHidlHeap = hidl_memory("ashmem", mHidlHandle, size);
331 });
332
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800333 commonInitialization();
334}
335
336void CameraDevice::CameraHeapMemory::commonInitialization() {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700337 mHidlHeapMemory = mapMemory(mHidlHeap);
338 if (mHidlHeapMemory == nullptr) {
339 ALOGE("%s: memory map failed!", __FUNCTION__);
340 native_handle_close(mHidlHandle); // close FD for the shared memory
341 native_handle_delete(mHidlHandle);
342 mHidlHeap = hidl_memory();
343 mHidlHandle = nullptr;
344 return;
345 }
346 mHidlHeapMemData = mHidlHeapMemory->getPointer();
347 handle.data = mHidlHeapMemData;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800348 handle.size = mBufSize * mNumBufs;
349 handle.handle = this;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800350 handle.release = sPutMemory;
351}
352
353CameraDevice::CameraHeapMemory::~CameraHeapMemory() {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700354 if (mHidlHeapMemory != nullptr) {
355 mHidlHeapMemData = nullptr;
356 mHidlHeapMemory.clear(); // The destructor will trigger munmap
357 }
358
359 if (mHidlHandle) {
360 native_handle_close(mHidlHandle); // close FD for the shared memory
361 native_handle_delete(mHidlHandle);
362 }
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800363}
364
365// shared memory methods
366camera_memory_t* CameraDevice::sGetMemory(int fd, size_t buf_size, uint_t num_bufs, void *user) {
367 ALOGV("%s", __FUNCTION__);
368 CameraDevice* object = static_cast<CameraDevice*>(user);
369 if (object->mDeviceCallback == nullptr) {
370 ALOGE("%s: camera HAL request memory while camera is not opened!", __FUNCTION__);
371 return nullptr;
372 }
373
374 CameraHeapMemory* mem;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800375 if (fd < 0) {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700376 mem = new CameraHeapMemory(object->mAshmemAllocator, buf_size, num_bufs);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800377 } else {
378 mem = new CameraHeapMemory(fd, buf_size, num_bufs);
379 }
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800380 mem->incStrong(mem);
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700381 hidl_handle hidlHandle = mem->mHidlHandle;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800382 MemoryId id = object->mDeviceCallback->registerMemory(hidlHandle, buf_size, num_bufs);
383 mem->handle.mId = id;
384 if (object->mMemoryMap.count(id) != 0) {
385 ALOGE("%s: duplicate MemoryId %d returned by client!", __FUNCTION__, id);
386 }
387 object->mMemoryMap[id] = mem;
388 mem->handle.mDevice = object;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800389 return &mem->handle;
390}
391
392void CameraDevice::sPutMemory(camera_memory_t *data) {
393 if (!data)
394 return;
395
396 CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle);
397 CameraDevice* device = mem->handle.mDevice;
398 if (device == nullptr) {
399 ALOGE("%s: camera HAL return memory for a null device!", __FUNCTION__);
400 }
401 if (device->mDeviceCallback == nullptr) {
402 ALOGE("%s: camera HAL return memory while camera is not opened!", __FUNCTION__);
403 }
404 device->mDeviceCallback->unregisterMemory(mem->handle.mId);
405 device->mMemoryMap.erase(mem->handle.mId);
406 mem->decStrong(mem);
407}
408
409// Callback forwarding methods
410void CameraDevice::sNotifyCb(int32_t msg_type, int32_t ext1, int32_t ext2, void *user) {
411 ALOGV("%s", __FUNCTION__);
412 CameraDevice* object = static_cast<CameraDevice*>(user);
413 if (object->mDeviceCallback != nullptr) {
414 object->mDeviceCallback->notifyCallback((NotifyCallbackMsg) msg_type, ext1, ext2);
415 }
416}
417
418void CameraDevice::sDataCb(int32_t msg_type, const camera_memory_t *data, unsigned int index,
419 camera_frame_metadata_t *metadata, void *user) {
420 ALOGV("%s", __FUNCTION__);
421 CameraDevice* object = static_cast<CameraDevice*>(user);
422 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory*>(data->handle));
423 if (index >= mem->mNumBufs) {
424 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
425 index, mem->mNumBufs);
426 return;
427 }
428 if (object->mDeviceCallback != nullptr) {
429 CameraFrameMetadata hidlMetadata;
430 if (metadata) {
431 hidlMetadata.faces.resize(metadata->number_of_faces);
432 for (size_t i = 0; i < hidlMetadata.faces.size(); i++) {
433 hidlMetadata.faces[i].score = metadata->faces[i].score;
434 hidlMetadata.faces[i].id = metadata->faces[i].id;
435 for (int k = 0; k < 4; k++) {
436 hidlMetadata.faces[i].rect[k] = metadata->faces[i].rect[k];
437 }
438 for (int k = 0; k < 2; k++) {
439 hidlMetadata.faces[i].leftEye[k] = metadata->faces[i].left_eye[k];
440 }
441 for (int k = 0; k < 2; k++) {
442 hidlMetadata.faces[i].rightEye[k] = metadata->faces[i].right_eye[k];
443 }
444 for (int k = 0; k < 2; k++) {
445 hidlMetadata.faces[i].mouth[k] = metadata->faces[i].mouth[k];
446 }
447 }
448 }
449 CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle);
450 object->mDeviceCallback->dataCallback(
451 (DataCallbackMsg) msg_type, mem->handle.mId, index, hidlMetadata);
452 }
453}
454
Yin-Chia Yeh1ba83a92017-03-21 17:47:02 -0700455void CameraDevice::handleCallbackTimestamp(
456 nsecs_t timestamp, int32_t msg_type,
457 MemoryId memId , unsigned index, native_handle_t* handle) {
458 uint32_t batchSize = 0;
459 {
460 Mutex::Autolock _l(mBatchLock);
461 batchSize = mBatchSize;
462 }
463
464 if (batchSize == 0) { // non-batch mode
465 mDeviceCallback->handleCallbackTimestamp(
466 (DataCallbackMsg) msg_type, handle, memId, index, timestamp);
467 } else { // batch mode
468 Mutex::Autolock _l(mBatchLock);
469 size_t inflightSize = mInflightBatch.size();
470 if (inflightSize == 0) {
471 mBatchMsgType = msg_type;
472 } else if (mBatchMsgType != msg_type) {
473 ALOGE("%s: msg_type change (from %d to %d) is not supported!",
474 __FUNCTION__, mBatchMsgType, msg_type);
475 return;
476 }
477 mInflightBatch.push_back({handle, memId, index, timestamp});
478
479 // Send batched frames to camera framework
480 if (mInflightBatch.size() >= batchSize) {
481 mDeviceCallback->handleCallbackTimestampBatch(
482 (DataCallbackMsg) mBatchMsgType, mInflightBatch);
483 mInflightBatch.clear();
484 }
485 }
486}
487
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800488void CameraDevice::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
489 const camera_memory_t *data, unsigned index, void *user) {
490 ALOGV("%s", __FUNCTION__);
491 CameraDevice* object = static_cast<CameraDevice*>(user);
492 // Start refcounting the heap object from here on. When the clients
493 // drop all references, it will be destroyed (as well as the enclosed
494 // MemoryHeapBase.
495 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory*>(data->handle));
496 if (index >= mem->mNumBufs) {
497 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
498 index, mem->mNumBufs);
499 return;
500 }
501
502 native_handle_t* handle = nullptr;
503 if (object->mMetadataMode) {
504 if (mem->mBufSize == sizeof(VideoNativeHandleMetadata)) {
505 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700506 ((uint8_t*) mem->mHidlHeapMemData + index * mem->mBufSize);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800507 if (md->eType == VideoNativeHandleMetadata::kMetadataBufferTypeNativeHandleSource) {
508 handle = md->pHandle;
509 }
510 }
511 }
512
513 if (object->mDeviceCallback != nullptr) {
514 if (handle == nullptr) {
515 object->mDeviceCallback->dataCallbackTimestamp(
516 (DataCallbackMsg) msg_type, mem->handle.mId, index, timestamp);
517 } else {
Yin-Chia Yeh1ba83a92017-03-21 17:47:02 -0700518 object->handleCallbackTimestamp(timestamp, msg_type, mem->handle.mId, index, handle);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800519 }
520 }
521}
522
523void CameraDevice::initHalPreviewWindow()
524{
525 mHalPreviewWindow.cancel_buffer = sCancelBuffer;
526 mHalPreviewWindow.lock_buffer = sLockBuffer;
527 mHalPreviewWindow.dequeue_buffer = sDequeueBuffer;
528 mHalPreviewWindow.enqueue_buffer = sEnqueueBuffer;
529 mHalPreviewWindow.set_buffer_count = sSetBufferCount;
530 mHalPreviewWindow.set_buffers_geometry = sSetBuffersGeometry;
531 mHalPreviewWindow.set_crop = sSetCrop;
532 mHalPreviewWindow.set_timestamp = sSetTimestamp;
533 mHalPreviewWindow.set_usage = sSetUsage;
534 mHalPreviewWindow.set_swap_interval = sSetSwapInterval;
535
536 mHalPreviewWindow.get_min_undequeued_buffer_count =
537 sGetMinUndequeuedBufferCount;
538}
539
540// Methods from ::android::hardware::camera::device::V1_0::ICameraDevice follow.
541Return<void> CameraDevice::getResourceCost(getResourceCost_cb _hidl_cb) {
542 Status status = initStatus();
543 CameraResourceCost resCost;
544 if (status == Status::OK) {
545 int cost = 100;
546 std::vector<std::string> conflicting_devices;
547 struct camera_info info;
548
549 // If using post-2.4 module version, query the cost + conflicting devices from the HAL
550 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
551 int ret = mModule->getCameraInfo(mCameraIdInt, &info);
552 if (ret == OK) {
553 cost = info.resource_cost;
554 for (size_t i = 0; i < info.conflicting_devices_length; i++) {
555 std::string cameraId(info.conflicting_devices[i]);
556 for (const auto& pair : mCameraDeviceNames) {
557 if (cameraId == pair.first) {
558 conflicting_devices.push_back(pair.second);
559 }
560 }
561 }
562 } else {
563 status = Status::INTERNAL_ERROR;
564 }
565 }
566
567 if (status == Status::OK) {
568 resCost.resourceCost = cost;
569 resCost.conflictingDevices.resize(conflicting_devices.size());
570 for (size_t i = 0; i < conflicting_devices.size(); i++) {
571 resCost.conflictingDevices[i] = conflicting_devices[i];
572 ALOGV("CamDevice %s is conflicting with camDevice %s",
573 mCameraId.c_str(), resCost.conflictingDevices[i].c_str());
574 }
575 }
576 }
577 _hidl_cb(status, resCost);
578 return Void();
579}
580
581Return<void> CameraDevice::getCameraInfo(getCameraInfo_cb _hidl_cb) {
582 Status status = initStatus();
583 CameraInfo cameraInfo;
584 if (status == Status::OK) {
585 struct camera_info info;
586 int ret = mModule->getCameraInfo(mCameraIdInt, &info);
587 if (ret == OK) {
588 cameraInfo.facing = (CameraFacing) info.facing;
589 // Device 1.0 does not support external camera facing.
590 // The closest approximation would be front camera.
591 // TODO: figure out should we override here or let
592 // camera service handle it.
593 if (cameraInfo.facing == CameraFacing::EXTERNAL) {
594 cameraInfo.facing = CameraFacing::FRONT;
595 }
596 cameraInfo.orientation = info.orientation;
597 } else {
598 ALOGE("%s: get camera info failed!", __FUNCTION__);
599 status = Status::INTERNAL_ERROR;
600 }
601 }
602 _hidl_cb(status, cameraInfo);
603 return Void();
604}
605
606Return<Status> CameraDevice::setTorchMode(TorchMode mode) {
607 if (!mModule->isSetTorchModeSupported()) {
608 return Status::METHOD_NOT_SUPPORTED;
609 }
610
611 Status status = initStatus();
612 if (status == Status::OK) {
613 bool enable = (mode == TorchMode::ON) ? true : false;
614 status = getHidlStatus(mModule->setTorchMode(mCameraId.c_str(), enable));
615 }
616 return status;
617}
618
619Return<Status> CameraDevice::dumpState(const hidl_handle& handle) {
620 Mutex::Autolock _l(mLock);
621 if (handle.getNativeHandle() == nullptr) {
622 ALOGE("%s: handle must not be null", __FUNCTION__);
623 return Status::ILLEGAL_ARGUMENT;
624 }
625 if (handle->numFds != 1 || handle->numInts != 0) {
626 ALOGE("%s: handle must contain 1 FD and 0 integers! Got %d FDs and %d ints",
627 __FUNCTION__, handle->numFds, handle->numInts);
628 return Status::ILLEGAL_ARGUMENT;
629 }
630 int fd = handle->data[0];
631
632 if (mDevice != nullptr) {
633 if (mDevice->ops->dump) { // It's fine if the HAL doesn't implement dump()
634 return getHidlStatus(mDevice->ops->dump(mDevice, fd));
635 }
636 }
637 return Status::OK;
638}
639
640Return<Status> CameraDevice::open(const sp<ICameraDeviceCallback>& callback) {
641 ALOGI("Opening camera %s", mCameraId.c_str());
642 Mutex::Autolock _l(mLock);
643
644 camera_info info;
645 status_t res = mModule->getCameraInfo(mCameraIdInt, &info);
646 if (res != OK) {
647 ALOGE("Could not get camera info: %s: %d", mCameraId.c_str(), res);
648 return getHidlStatus(res);
649 }
650
651 int rc = OK;
652 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
653 info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
654 // Open higher version camera device as HAL1.0 device.
655 rc = mModule->openLegacy(mCameraId.c_str(),
656 CAMERA_DEVICE_API_VERSION_1_0,
657 (hw_device_t **)&mDevice);
658 } else {
659 rc = mModule->open(mCameraId.c_str(), (hw_device_t **)&mDevice);
660 }
661 if (rc != OK) {
662 mDevice = nullptr;
663 ALOGE("Could not open camera %s: %d", mCameraId.c_str(), rc);
664 return getHidlStatus(rc);
665 }
666
667 initHalPreviewWindow();
668 mDeviceCallback = callback;
669
670 if (mDevice->ops->set_callbacks) {
671 mDevice->ops->set_callbacks(mDevice,
672 sNotifyCb, sDataCb, sDataCbTimestamp, sGetMemory, this);
673 }
674
675 return getHidlStatus(rc);
676}
677
678Return<Status> CameraDevice::setPreviewWindow(const sp<ICameraDevicePreviewCallback>& window) {
679 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
680 Mutex::Autolock _l(mLock);
681 if (!mDevice) {
682 ALOGE("%s called while camera is not opened", __FUNCTION__);
683 return Status::OPERATION_NOT_SUPPORTED;
684 }
685
686 mHalPreviewWindow.mPreviewCallback = window;
687 if (mDevice->ops->set_preview_window) {
688 return getHidlStatus(mDevice->ops->set_preview_window(mDevice,
689 (window == nullptr) ? nullptr : &mHalPreviewWindow));
690 }
691 return Status::INTERNAL_ERROR; // HAL should provide set_preview_window
692}
693
694Return<void> CameraDevice::enableMsgType(uint32_t msgType) {
695 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
696 Mutex::Autolock _l(mLock);
697 if (!mDevice) {
698 ALOGE("%s called while camera is not opened", __FUNCTION__);
699 return Void();
700 }
701 if (mDevice->ops->enable_msg_type) {
702 mDevice->ops->enable_msg_type(mDevice, msgType);
703 }
704 return Void();
705}
706
707Return<void> CameraDevice::disableMsgType(uint32_t msgType) {
708 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
709 Mutex::Autolock _l(mLock);
710 if (!mDevice) {
711 ALOGE("%s called while camera is not opened", __FUNCTION__);
712 return Void();
713 }
714 if (mDevice->ops->disable_msg_type) {
715 mDevice->ops->disable_msg_type(mDevice, msgType);
716 }
717 return Void();
718}
719
720Return<bool> CameraDevice::msgTypeEnabled(uint32_t msgType) {
721 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
722 Mutex::Autolock _l(mLock);
723 if (!mDevice) {
724 ALOGE("%s called while camera is not opened", __FUNCTION__);
725 return false;
726 }
727 if (mDevice->ops->msg_type_enabled) {
728 return mDevice->ops->msg_type_enabled(mDevice, msgType);
729 }
730 return false;
731}
732
733Return<Status> CameraDevice::startPreview() {
734 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
735 Mutex::Autolock _l(mLock);
736 if (!mDevice) {
737 ALOGE("%s called while camera is not opened", __FUNCTION__);
738 return Status::OPERATION_NOT_SUPPORTED;
739 }
740 if (mDevice->ops->start_preview) {
741 return getHidlStatus(mDevice->ops->start_preview(mDevice));
742 }
743 return Status::INTERNAL_ERROR; // HAL should provide start_preview
744}
745
746Return<void> CameraDevice::stopPreview() {
747 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
748 Mutex::Autolock _l(mLock);
749 if (!mDevice) {
750 ALOGE("%s called while camera is not opened", __FUNCTION__);
751 return Void();
752 }
753 if (mDevice->ops->stop_preview) {
754 mDevice->ops->stop_preview(mDevice);
755 }
756 return Void();
757}
758
759Return<bool> CameraDevice::previewEnabled() {
760 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
761 Mutex::Autolock _l(mLock);
762 if (!mDevice) {
763 ALOGE("%s called while camera is not opened", __FUNCTION__);
764 return false;
765 }
766 if (mDevice->ops->preview_enabled) {
767 return mDevice->ops->preview_enabled(mDevice);
768 }
769 return false;
770}
771
772Return<Status> CameraDevice::storeMetaDataInBuffers(bool enable) {
773 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
774 Mutex::Autolock _l(mLock);
775 if (!mDevice) {
776 ALOGE("%s called while camera is not opened", __FUNCTION__);
777 return Status::OPERATION_NOT_SUPPORTED;
778 }
779 if (mDevice->ops->store_meta_data_in_buffers) {
780 status_t s = mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
781 if (s == OK && enable) {
782 mMetadataMode = true;
783 }
784 return getHidlStatus(s);
785 }
786 return enable ? Status::ILLEGAL_ARGUMENT : Status::OK;
787}
788
789Return<Status> CameraDevice::startRecording() {
790 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
791 Mutex::Autolock _l(mLock);
792 if (!mDevice) {
793 ALOGE("%s called while camera is not opened", __FUNCTION__);
794 return Status::OPERATION_NOT_SUPPORTED;
795 }
796 if (mDevice->ops->start_recording) {
797 return getHidlStatus(mDevice->ops->start_recording(mDevice));
798 }
799 return Status::ILLEGAL_ARGUMENT;
800}
801
802Return<void> CameraDevice::stopRecording() {
803 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
804 Mutex::Autolock _l(mLock);
805 if (!mDevice) {
806 ALOGE("%s called while camera is not opened", __FUNCTION__);
807 return Void();
808 }
809 if (mDevice->ops->stop_recording) {
810 mDevice->ops->stop_recording(mDevice);
811 }
812 return Void();
813}
814
815Return<bool> CameraDevice::recordingEnabled() {
816 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
817 Mutex::Autolock _l(mLock);
818 if (!mDevice) {
819 ALOGE("%s called while camera is not opened", __FUNCTION__);
820 return false;
821 }
822 if (mDevice->ops->recording_enabled) {
823 return mDevice->ops->recording_enabled(mDevice);
824 }
825 return false;
826}
827
828void CameraDevice::releaseRecordingFrameLocked(
829 uint32_t memId, uint32_t bufferIndex, const native_handle_t* handle) {
830 if (!mDevice) {
831 ALOGE("%s called while camera is not opened", __FUNCTION__);
832 return;
833 }
834 if (mDevice->ops->release_recording_frame) {
835 CameraHeapMemory* camMemory = mMemoryMap.at(memId);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800836 if (bufferIndex >= camMemory->mNumBufs) {
837 ALOGE("%s: bufferIndex %d exceeds number of buffers %d",
838 __FUNCTION__, bufferIndex, camMemory->mNumBufs);
839 return;
840 }
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700841 void *data = ((uint8_t *) camMemory->mHidlHeapMemData) + bufferIndex * camMemory->mBufSize;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800842 if (handle) {
843 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) data;
844 if (md->eType == VideoNativeHandleMetadata::kMetadataBufferTypeNativeHandleSource) {
845 // Input handle will be closed by HIDL transport later, so clone it
846 // HAL implementation is responsible to close/delete the clone
847 native_handle_t* clone = native_handle_clone(handle);
848 if (!clone) {
849 ALOGE("%s: failed to clone buffer %p", __FUNCTION__, handle);
850 return;
851 }
852 md->pHandle = clone;
853 } else {
854 ALOGE("%s:Malform VideoNativeHandleMetadata at memId %d, bufferId %d",
855 __FUNCTION__, memId, bufferIndex);
856 return;
857 }
858 }
859 mDevice->ops->release_recording_frame(mDevice, data);
860 }
861}
862
863Return<void> CameraDevice::releaseRecordingFrame(uint32_t memId, uint32_t bufferIndex) {
864 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
865 Mutex::Autolock _l(mLock);
866 releaseRecordingFrameLocked(memId, bufferIndex, nullptr);
867 return Void();
868}
869
870Return<void> CameraDevice::releaseRecordingFrameHandle(
871 uint32_t memId, uint32_t bufferIndex, const hidl_handle& frame) {
872 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
873 Mutex::Autolock _l(mLock);
874 releaseRecordingFrameLocked(
875 memId, bufferIndex, frame.getNativeHandle());
876 return Void();
877}
878
Yin-Chia Yeh1ba83a92017-03-21 17:47:02 -0700879Return<void> CameraDevice::releaseRecordingFrameHandleBatch(
880 const hidl_vec<VideoFrameMessage>& msgs) {
881 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
882 Mutex::Autolock _l(mLock);
883 for (auto& msg : msgs) {
884 releaseRecordingFrameLocked(
885 msg.data, msg.bufferIndex, msg.frameData.getNativeHandle());
886 }
887 return Void();
888}
889
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800890Return<Status> CameraDevice::autoFocus() {
891 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
892 Mutex::Autolock _l(mLock);
893 if (!mDevice) {
894 ALOGE("%s called while camera is not opened", __FUNCTION__);
895 return Status::OPERATION_NOT_SUPPORTED;
896 }
897 if (mDevice->ops->auto_focus) {
898 return getHidlStatus(mDevice->ops->auto_focus(mDevice));
899 }
900 return Status::ILLEGAL_ARGUMENT;
901}
902
903Return<Status> CameraDevice::cancelAutoFocus() {
904 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
905 Mutex::Autolock _l(mLock);
906 if (!mDevice) {
907 ALOGE("%s called while camera is not opened", __FUNCTION__);
908 return Status::OPERATION_NOT_SUPPORTED;
909 }
910 if (mDevice->ops->cancel_auto_focus) {
911 return getHidlStatus(mDevice->ops->cancel_auto_focus(mDevice));
912 }
913 return Status::ILLEGAL_ARGUMENT;
914}
915
916Return<Status> CameraDevice::takePicture() {
917 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
918 Mutex::Autolock _l(mLock);
919 if (!mDevice) {
920 ALOGE("%s called while camera is not opened", __FUNCTION__);
921 return Status::OPERATION_NOT_SUPPORTED;
922 }
923 if (mDevice->ops->take_picture) {
924 return getHidlStatus(mDevice->ops->take_picture(mDevice));
925 }
926 return Status::ILLEGAL_ARGUMENT;
927}
928
929Return<Status> CameraDevice::cancelPicture() {
930 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
931 Mutex::Autolock _l(mLock);
932 if (!mDevice) {
933 ALOGE("%s called while camera is not opened", __FUNCTION__);
934 return Status::OPERATION_NOT_SUPPORTED;
935 }
936 if (mDevice->ops->cancel_picture) {
937 return getHidlStatus(mDevice->ops->cancel_picture(mDevice));
938 }
939 return Status::ILLEGAL_ARGUMENT;
940}
941
942Return<Status> CameraDevice::setParameters(const hidl_string& params) {
943 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
944 Mutex::Autolock _l(mLock);
945 if (!mDevice) {
946 ALOGE("%s called while camera is not opened", __FUNCTION__);
947 return Status::OPERATION_NOT_SUPPORTED;
948 }
949 if (mDevice->ops->set_parameters) {
950 return getHidlStatus(mDevice->ops->set_parameters(mDevice, params.c_str()));
951 }
952 return Status::ILLEGAL_ARGUMENT;
953}
954
955Return<void> CameraDevice::getParameters(getParameters_cb _hidl_cb) {
956 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
957 Mutex::Autolock _l(mLock);
958 hidl_string outStr;
959 if (!mDevice) {
960 ALOGE("%s called while camera is not opened", __FUNCTION__);
961 _hidl_cb(outStr);
962 return Void();
963 }
964 if (mDevice->ops->get_parameters) {
965 char *temp = mDevice->ops->get_parameters(mDevice);
966 outStr = temp;
967 if (mDevice->ops->put_parameters) {
968 mDevice->ops->put_parameters(mDevice, temp);
969 } else {
970 free(temp);
971 }
972 }
973 _hidl_cb(outStr);
974 return Void();
975}
976
977Return<Status> CameraDevice::sendCommand(CommandType cmd, int32_t arg1, int32_t arg2) {
978 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
979 Mutex::Autolock _l(mLock);
980 if (!mDevice) {
981 ALOGE("%s called while camera is not opened", __FUNCTION__);
982 return Status::OPERATION_NOT_SUPPORTED;
983 }
984 if (mDevice->ops->send_command) {
985 return getHidlStatus(mDevice->ops->send_command(mDevice, (int32_t) cmd, arg1, arg2));
986 }
987 return Status::ILLEGAL_ARGUMENT;
988}
989
990Return<void> CameraDevice::close() {
991 ALOGI("Closing camera %s", mCameraId.c_str());
992 Mutex::Autolock _l(mLock);
993 if(mDevice) {
994 int rc = mDevice->common.close(&mDevice->common);
995 if (rc != OK) {
996 ALOGE("Could not close camera %s: %d", mCameraId.c_str(), rc);
997 }
998 mDevice = nullptr;
999 }
1000 return Void();
1001}
1002
1003} // namespace implementation
1004} // namespace V1_0
1005} // namespace device
1006} // namespace camera
1007} // namespace hardware
1008} // namespace android