blob: 15a44ca7dfa8d532d7277a2147432a8ce6a240db [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"
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080018#include <hardware/camera.h>
19#include <hardware/gralloc1.h>
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -070020#include <hidlmemory/mapping.h>
Steven Moreland4e7a3072017-04-06 12:15:23 -070021#include <log/log.h>
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080022#include <utils/Trace.h>
23
Yin-Chia Yeh1ee279d2017-04-17 17:44:52 -070024#include <media/hardware/HardwareAPI.h> // For VideoNativeHandleMetadata
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080025#include "CameraDevice_1_0.h"
26
27namespace android {
28namespace hardware {
29namespace camera {
30namespace device {
31namespace V1_0 {
32namespace implementation {
33
Chia-I Wu79d13ff2017-03-31 12:48:11 -070034using ::android::hardware::graphics::common::V1_0::BufferUsage;
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();
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700263 return getStatusT(object->mPreviewCallback->setUsage((BufferUsage)usage));
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800264}
265
266int CameraDevice::sSetSwapInterval(struct preview_stream_ops *w, int interval) {
267 CameraPreviewWindow* object = static_cast<CameraPreviewWindow*>(w);
268 if (object->mPreviewCallback == nullptr) {
269 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
270 return INVALID_OPERATION;
271 }
272
273 return getStatusT(object->mPreviewCallback->setSwapInterval(interval));
274}
275
276int CameraDevice::sGetMinUndequeuedBufferCount(
277 const struct preview_stream_ops *w,
278 int *count) {
279 const CameraPreviewWindow* object = static_cast<const CameraPreviewWindow*>(w);
280 if (object->mPreviewCallback == nullptr) {
281 ALOGE("%s: camera HAL calling preview ops while there is no preview window!", __FUNCTION__);
282 return INVALID_OPERATION;
283 }
284 if (count == nullptr) {
285 ALOGE("%s: count is null!", __FUNCTION__);
286 return BAD_VALUE;
287 }
288
289 Status s;
290 object->mPreviewCallback->getMinUndequeuedBufferCount(
291 [&](auto status, uint32_t cnt) {
292 s = status;
293 if (s == Status::OK) {
294 *count = cnt;
295 }
296 });
297 return getStatusT(s);
298}
299
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700300CameraDevice::CameraHeapMemory::CameraHeapMemory(
301 int fd, size_t buf_size, uint_t num_buffers) :
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800302 mBufSize(buf_size),
303 mNumBufs(num_buffers) {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700304 mHidlHandle = native_handle_create(1,0);
305 mHidlHandle->data[0] = fcntl(fd, F_DUPFD_CLOEXEC, 0);
306 const size_t pagesize = getpagesize();
307 size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1));
308 mHidlHeap = hidl_memory("ashmem", mHidlHandle, size);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800309 commonInitialization();
310}
311
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700312CameraDevice::CameraHeapMemory::CameraHeapMemory(
313 sp<IAllocator> ashmemAllocator,
314 size_t buf_size, uint_t num_buffers) :
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800315 mBufSize(buf_size),
316 mNumBufs(num_buffers) {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700317 const size_t pagesize = getpagesize();
318 size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1));
319 ashmemAllocator->allocate(size,
320 [&](bool success, const hidl_memory& mem) {
321 if (!success) {
322 ALOGE("%s: allocating ashmem of %zu bytes failed!",
323 __FUNCTION__, buf_size * num_buffers);
324 return;
325 }
326 mHidlHandle = native_handle_clone(mem.handle());
327 mHidlHeap = hidl_memory("ashmem", mHidlHandle, size);
328 });
329
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800330 commonInitialization();
331}
332
333void CameraDevice::CameraHeapMemory::commonInitialization() {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700334 mHidlHeapMemory = mapMemory(mHidlHeap);
335 if (mHidlHeapMemory == nullptr) {
336 ALOGE("%s: memory map failed!", __FUNCTION__);
337 native_handle_close(mHidlHandle); // close FD for the shared memory
338 native_handle_delete(mHidlHandle);
339 mHidlHeap = hidl_memory();
340 mHidlHandle = nullptr;
341 return;
342 }
343 mHidlHeapMemData = mHidlHeapMemory->getPointer();
344 handle.data = mHidlHeapMemData;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800345 handle.size = mBufSize * mNumBufs;
346 handle.handle = this;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800347 handle.release = sPutMemory;
348}
349
350CameraDevice::CameraHeapMemory::~CameraHeapMemory() {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700351 if (mHidlHeapMemory != nullptr) {
352 mHidlHeapMemData = nullptr;
353 mHidlHeapMemory.clear(); // The destructor will trigger munmap
354 }
355
356 if (mHidlHandle) {
357 native_handle_close(mHidlHandle); // close FD for the shared memory
358 native_handle_delete(mHidlHandle);
359 }
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800360}
361
362// shared memory methods
363camera_memory_t* CameraDevice::sGetMemory(int fd, size_t buf_size, uint_t num_bufs, void *user) {
364 ALOGV("%s", __FUNCTION__);
365 CameraDevice* object = static_cast<CameraDevice*>(user);
366 if (object->mDeviceCallback == nullptr) {
367 ALOGE("%s: camera HAL request memory while camera is not opened!", __FUNCTION__);
368 return nullptr;
369 }
370
371 CameraHeapMemory* mem;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800372 if (fd < 0) {
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700373 mem = new CameraHeapMemory(object->mAshmemAllocator, buf_size, num_bufs);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800374 } else {
375 mem = new CameraHeapMemory(fd, buf_size, num_bufs);
376 }
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800377 mem->incStrong(mem);
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700378 hidl_handle hidlHandle = mem->mHidlHandle;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800379 MemoryId id = object->mDeviceCallback->registerMemory(hidlHandle, buf_size, num_bufs);
380 mem->handle.mId = id;
381 if (object->mMemoryMap.count(id) != 0) {
382 ALOGE("%s: duplicate MemoryId %d returned by client!", __FUNCTION__, id);
383 }
384 object->mMemoryMap[id] = mem;
385 mem->handle.mDevice = object;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800386 return &mem->handle;
387}
388
389void CameraDevice::sPutMemory(camera_memory_t *data) {
390 if (!data)
391 return;
392
393 CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle);
394 CameraDevice* device = mem->handle.mDevice;
395 if (device == nullptr) {
396 ALOGE("%s: camera HAL return memory for a null device!", __FUNCTION__);
397 }
398 if (device->mDeviceCallback == nullptr) {
399 ALOGE("%s: camera HAL return memory while camera is not opened!", __FUNCTION__);
400 }
401 device->mDeviceCallback->unregisterMemory(mem->handle.mId);
402 device->mMemoryMap.erase(mem->handle.mId);
403 mem->decStrong(mem);
404}
405
406// Callback forwarding methods
407void CameraDevice::sNotifyCb(int32_t msg_type, int32_t ext1, int32_t ext2, void *user) {
408 ALOGV("%s", __FUNCTION__);
409 CameraDevice* object = static_cast<CameraDevice*>(user);
410 if (object->mDeviceCallback != nullptr) {
411 object->mDeviceCallback->notifyCallback((NotifyCallbackMsg) msg_type, ext1, ext2);
412 }
413}
414
415void CameraDevice::sDataCb(int32_t msg_type, const camera_memory_t *data, unsigned int index,
416 camera_frame_metadata_t *metadata, void *user) {
417 ALOGV("%s", __FUNCTION__);
418 CameraDevice* object = static_cast<CameraDevice*>(user);
419 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory*>(data->handle));
420 if (index >= mem->mNumBufs) {
421 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
422 index, mem->mNumBufs);
423 return;
424 }
425 if (object->mDeviceCallback != nullptr) {
426 CameraFrameMetadata hidlMetadata;
427 if (metadata) {
428 hidlMetadata.faces.resize(metadata->number_of_faces);
429 for (size_t i = 0; i < hidlMetadata.faces.size(); i++) {
430 hidlMetadata.faces[i].score = metadata->faces[i].score;
431 hidlMetadata.faces[i].id = metadata->faces[i].id;
432 for (int k = 0; k < 4; k++) {
433 hidlMetadata.faces[i].rect[k] = metadata->faces[i].rect[k];
434 }
435 for (int k = 0; k < 2; k++) {
436 hidlMetadata.faces[i].leftEye[k] = metadata->faces[i].left_eye[k];
437 }
438 for (int k = 0; k < 2; k++) {
439 hidlMetadata.faces[i].rightEye[k] = metadata->faces[i].right_eye[k];
440 }
441 for (int k = 0; k < 2; k++) {
442 hidlMetadata.faces[i].mouth[k] = metadata->faces[i].mouth[k];
443 }
444 }
445 }
446 CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle);
447 object->mDeviceCallback->dataCallback(
448 (DataCallbackMsg) msg_type, mem->handle.mId, index, hidlMetadata);
449 }
450}
451
Yin-Chia Yeh1ba83a92017-03-21 17:47:02 -0700452void CameraDevice::handleCallbackTimestamp(
453 nsecs_t timestamp, int32_t msg_type,
454 MemoryId memId , unsigned index, native_handle_t* handle) {
455 uint32_t batchSize = 0;
456 {
457 Mutex::Autolock _l(mBatchLock);
458 batchSize = mBatchSize;
459 }
460
461 if (batchSize == 0) { // non-batch mode
462 mDeviceCallback->handleCallbackTimestamp(
463 (DataCallbackMsg) msg_type, handle, memId, index, timestamp);
464 } else { // batch mode
465 Mutex::Autolock _l(mBatchLock);
466 size_t inflightSize = mInflightBatch.size();
467 if (inflightSize == 0) {
468 mBatchMsgType = msg_type;
469 } else if (mBatchMsgType != msg_type) {
470 ALOGE("%s: msg_type change (from %d to %d) is not supported!",
471 __FUNCTION__, mBatchMsgType, msg_type);
472 return;
473 }
474 mInflightBatch.push_back({handle, memId, index, timestamp});
475
476 // Send batched frames to camera framework
477 if (mInflightBatch.size() >= batchSize) {
478 mDeviceCallback->handleCallbackTimestampBatch(
479 (DataCallbackMsg) mBatchMsgType, mInflightBatch);
480 mInflightBatch.clear();
481 }
482 }
483}
484
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800485void CameraDevice::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
486 const camera_memory_t *data, unsigned index, void *user) {
487 ALOGV("%s", __FUNCTION__);
488 CameraDevice* object = static_cast<CameraDevice*>(user);
489 // Start refcounting the heap object from here on. When the clients
490 // drop all references, it will be destroyed (as well as the enclosed
491 // MemoryHeapBase.
492 sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory*>(data->handle));
493 if (index >= mem->mNumBufs) {
494 ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
495 index, mem->mNumBufs);
496 return;
497 }
498
499 native_handle_t* handle = nullptr;
500 if (object->mMetadataMode) {
501 if (mem->mBufSize == sizeof(VideoNativeHandleMetadata)) {
502 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700503 ((uint8_t*) mem->mHidlHeapMemData + index * mem->mBufSize);
Yin-Chia Yeh1ee279d2017-04-17 17:44:52 -0700504 if (md->eType == kMetadataBufferTypeNativeHandleSource) {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800505 handle = md->pHandle;
506 }
507 }
508 }
509
510 if (object->mDeviceCallback != nullptr) {
511 if (handle == nullptr) {
512 object->mDeviceCallback->dataCallbackTimestamp(
513 (DataCallbackMsg) msg_type, mem->handle.mId, index, timestamp);
514 } else {
Yin-Chia Yeh1ba83a92017-03-21 17:47:02 -0700515 object->handleCallbackTimestamp(timestamp, msg_type, mem->handle.mId, index, handle);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800516 }
517 }
518}
519
520void CameraDevice::initHalPreviewWindow()
521{
522 mHalPreviewWindow.cancel_buffer = sCancelBuffer;
523 mHalPreviewWindow.lock_buffer = sLockBuffer;
524 mHalPreviewWindow.dequeue_buffer = sDequeueBuffer;
525 mHalPreviewWindow.enqueue_buffer = sEnqueueBuffer;
526 mHalPreviewWindow.set_buffer_count = sSetBufferCount;
527 mHalPreviewWindow.set_buffers_geometry = sSetBuffersGeometry;
528 mHalPreviewWindow.set_crop = sSetCrop;
529 mHalPreviewWindow.set_timestamp = sSetTimestamp;
530 mHalPreviewWindow.set_usage = sSetUsage;
531 mHalPreviewWindow.set_swap_interval = sSetSwapInterval;
532
533 mHalPreviewWindow.get_min_undequeued_buffer_count =
534 sGetMinUndequeuedBufferCount;
535}
536
537// Methods from ::android::hardware::camera::device::V1_0::ICameraDevice follow.
538Return<void> CameraDevice::getResourceCost(getResourceCost_cb _hidl_cb) {
539 Status status = initStatus();
540 CameraResourceCost resCost;
541 if (status == Status::OK) {
542 int cost = 100;
543 std::vector<std::string> conflicting_devices;
544 struct camera_info info;
545
546 // If using post-2.4 module version, query the cost + conflicting devices from the HAL
547 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
548 int ret = mModule->getCameraInfo(mCameraIdInt, &info);
549 if (ret == OK) {
550 cost = info.resource_cost;
551 for (size_t i = 0; i < info.conflicting_devices_length; i++) {
552 std::string cameraId(info.conflicting_devices[i]);
553 for (const auto& pair : mCameraDeviceNames) {
554 if (cameraId == pair.first) {
555 conflicting_devices.push_back(pair.second);
556 }
557 }
558 }
559 } else {
560 status = Status::INTERNAL_ERROR;
561 }
562 }
563
564 if (status == Status::OK) {
565 resCost.resourceCost = cost;
566 resCost.conflictingDevices.resize(conflicting_devices.size());
567 for (size_t i = 0; i < conflicting_devices.size(); i++) {
568 resCost.conflictingDevices[i] = conflicting_devices[i];
569 ALOGV("CamDevice %s is conflicting with camDevice %s",
570 mCameraId.c_str(), resCost.conflictingDevices[i].c_str());
571 }
572 }
573 }
574 _hidl_cb(status, resCost);
575 return Void();
576}
577
578Return<void> CameraDevice::getCameraInfo(getCameraInfo_cb _hidl_cb) {
579 Status status = initStatus();
580 CameraInfo cameraInfo;
581 if (status == Status::OK) {
582 struct camera_info info;
583 int ret = mModule->getCameraInfo(mCameraIdInt, &info);
584 if (ret == OK) {
585 cameraInfo.facing = (CameraFacing) info.facing;
586 // Device 1.0 does not support external camera facing.
587 // The closest approximation would be front camera.
588 // TODO: figure out should we override here or let
589 // camera service handle it.
590 if (cameraInfo.facing == CameraFacing::EXTERNAL) {
591 cameraInfo.facing = CameraFacing::FRONT;
592 }
593 cameraInfo.orientation = info.orientation;
594 } else {
595 ALOGE("%s: get camera info failed!", __FUNCTION__);
596 status = Status::INTERNAL_ERROR;
597 }
598 }
599 _hidl_cb(status, cameraInfo);
600 return Void();
601}
602
603Return<Status> CameraDevice::setTorchMode(TorchMode mode) {
604 if (!mModule->isSetTorchModeSupported()) {
605 return Status::METHOD_NOT_SUPPORTED;
606 }
607
608 Status status = initStatus();
609 if (status == Status::OK) {
610 bool enable = (mode == TorchMode::ON) ? true : false;
611 status = getHidlStatus(mModule->setTorchMode(mCameraId.c_str(), enable));
612 }
613 return status;
614}
615
616Return<Status> CameraDevice::dumpState(const hidl_handle& handle) {
617 Mutex::Autolock _l(mLock);
618 if (handle.getNativeHandle() == nullptr) {
619 ALOGE("%s: handle must not be null", __FUNCTION__);
620 return Status::ILLEGAL_ARGUMENT;
621 }
622 if (handle->numFds != 1 || handle->numInts != 0) {
623 ALOGE("%s: handle must contain 1 FD and 0 integers! Got %d FDs and %d ints",
624 __FUNCTION__, handle->numFds, handle->numInts);
625 return Status::ILLEGAL_ARGUMENT;
626 }
627 int fd = handle->data[0];
628
629 if (mDevice != nullptr) {
630 if (mDevice->ops->dump) { // It's fine if the HAL doesn't implement dump()
631 return getHidlStatus(mDevice->ops->dump(mDevice, fd));
632 }
633 }
634 return Status::OK;
635}
636
637Return<Status> CameraDevice::open(const sp<ICameraDeviceCallback>& callback) {
638 ALOGI("Opening camera %s", mCameraId.c_str());
639 Mutex::Autolock _l(mLock);
640
641 camera_info info;
642 status_t res = mModule->getCameraInfo(mCameraIdInt, &info);
643 if (res != OK) {
644 ALOGE("Could not get camera info: %s: %d", mCameraId.c_str(), res);
645 return getHidlStatus(res);
646 }
647
648 int rc = OK;
649 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
650 info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
651 // Open higher version camera device as HAL1.0 device.
652 rc = mModule->openLegacy(mCameraId.c_str(),
653 CAMERA_DEVICE_API_VERSION_1_0,
654 (hw_device_t **)&mDevice);
655 } else {
656 rc = mModule->open(mCameraId.c_str(), (hw_device_t **)&mDevice);
657 }
658 if (rc != OK) {
659 mDevice = nullptr;
660 ALOGE("Could not open camera %s: %d", mCameraId.c_str(), rc);
661 return getHidlStatus(rc);
662 }
663
664 initHalPreviewWindow();
665 mDeviceCallback = callback;
666
667 if (mDevice->ops->set_callbacks) {
668 mDevice->ops->set_callbacks(mDevice,
669 sNotifyCb, sDataCb, sDataCbTimestamp, sGetMemory, this);
670 }
671
672 return getHidlStatus(rc);
673}
674
675Return<Status> CameraDevice::setPreviewWindow(const sp<ICameraDevicePreviewCallback>& window) {
676 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
677 Mutex::Autolock _l(mLock);
678 if (!mDevice) {
679 ALOGE("%s called while camera is not opened", __FUNCTION__);
680 return Status::OPERATION_NOT_SUPPORTED;
681 }
682
683 mHalPreviewWindow.mPreviewCallback = window;
684 if (mDevice->ops->set_preview_window) {
685 return getHidlStatus(mDevice->ops->set_preview_window(mDevice,
686 (window == nullptr) ? nullptr : &mHalPreviewWindow));
687 }
688 return Status::INTERNAL_ERROR; // HAL should provide set_preview_window
689}
690
691Return<void> CameraDevice::enableMsgType(uint32_t msgType) {
692 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
693 Mutex::Autolock _l(mLock);
694 if (!mDevice) {
695 ALOGE("%s called while camera is not opened", __FUNCTION__);
696 return Void();
697 }
698 if (mDevice->ops->enable_msg_type) {
699 mDevice->ops->enable_msg_type(mDevice, msgType);
700 }
701 return Void();
702}
703
704Return<void> CameraDevice::disableMsgType(uint32_t msgType) {
705 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
706 Mutex::Autolock _l(mLock);
707 if (!mDevice) {
708 ALOGE("%s called while camera is not opened", __FUNCTION__);
709 return Void();
710 }
711 if (mDevice->ops->disable_msg_type) {
712 mDevice->ops->disable_msg_type(mDevice, msgType);
713 }
714 return Void();
715}
716
717Return<bool> CameraDevice::msgTypeEnabled(uint32_t msgType) {
718 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
719 Mutex::Autolock _l(mLock);
720 if (!mDevice) {
721 ALOGE("%s called while camera is not opened", __FUNCTION__);
722 return false;
723 }
724 if (mDevice->ops->msg_type_enabled) {
725 return mDevice->ops->msg_type_enabled(mDevice, msgType);
726 }
727 return false;
728}
729
730Return<Status> CameraDevice::startPreview() {
731 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
732 Mutex::Autolock _l(mLock);
733 if (!mDevice) {
734 ALOGE("%s called while camera is not opened", __FUNCTION__);
735 return Status::OPERATION_NOT_SUPPORTED;
736 }
737 if (mDevice->ops->start_preview) {
738 return getHidlStatus(mDevice->ops->start_preview(mDevice));
739 }
740 return Status::INTERNAL_ERROR; // HAL should provide start_preview
741}
742
743Return<void> CameraDevice::stopPreview() {
744 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
745 Mutex::Autolock _l(mLock);
746 if (!mDevice) {
747 ALOGE("%s called while camera is not opened", __FUNCTION__);
748 return Void();
749 }
750 if (mDevice->ops->stop_preview) {
751 mDevice->ops->stop_preview(mDevice);
752 }
753 return Void();
754}
755
756Return<bool> CameraDevice::previewEnabled() {
757 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
758 Mutex::Autolock _l(mLock);
759 if (!mDevice) {
760 ALOGE("%s called while camera is not opened", __FUNCTION__);
761 return false;
762 }
763 if (mDevice->ops->preview_enabled) {
764 return mDevice->ops->preview_enabled(mDevice);
765 }
766 return false;
767}
768
769Return<Status> CameraDevice::storeMetaDataInBuffers(bool enable) {
770 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
771 Mutex::Autolock _l(mLock);
772 if (!mDevice) {
773 ALOGE("%s called while camera is not opened", __FUNCTION__);
774 return Status::OPERATION_NOT_SUPPORTED;
775 }
776 if (mDevice->ops->store_meta_data_in_buffers) {
777 status_t s = mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
778 if (s == OK && enable) {
779 mMetadataMode = true;
780 }
781 return getHidlStatus(s);
782 }
783 return enable ? Status::ILLEGAL_ARGUMENT : Status::OK;
784}
785
786Return<Status> CameraDevice::startRecording() {
787 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
788 Mutex::Autolock _l(mLock);
789 if (!mDevice) {
790 ALOGE("%s called while camera is not opened", __FUNCTION__);
791 return Status::OPERATION_NOT_SUPPORTED;
792 }
793 if (mDevice->ops->start_recording) {
794 return getHidlStatus(mDevice->ops->start_recording(mDevice));
795 }
796 return Status::ILLEGAL_ARGUMENT;
797}
798
799Return<void> CameraDevice::stopRecording() {
800 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
801 Mutex::Autolock _l(mLock);
802 if (!mDevice) {
803 ALOGE("%s called while camera is not opened", __FUNCTION__);
804 return Void();
805 }
806 if (mDevice->ops->stop_recording) {
807 mDevice->ops->stop_recording(mDevice);
808 }
809 return Void();
810}
811
812Return<bool> CameraDevice::recordingEnabled() {
813 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
814 Mutex::Autolock _l(mLock);
815 if (!mDevice) {
816 ALOGE("%s called while camera is not opened", __FUNCTION__);
817 return false;
818 }
819 if (mDevice->ops->recording_enabled) {
820 return mDevice->ops->recording_enabled(mDevice);
821 }
822 return false;
823}
824
825void CameraDevice::releaseRecordingFrameLocked(
826 uint32_t memId, uint32_t bufferIndex, const native_handle_t* handle) {
827 if (!mDevice) {
828 ALOGE("%s called while camera is not opened", __FUNCTION__);
829 return;
830 }
831 if (mDevice->ops->release_recording_frame) {
832 CameraHeapMemory* camMemory = mMemoryMap.at(memId);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800833 if (bufferIndex >= camMemory->mNumBufs) {
834 ALOGE("%s: bufferIndex %d exceeds number of buffers %d",
835 __FUNCTION__, bufferIndex, camMemory->mNumBufs);
836 return;
837 }
Yin-Chia Yeh12b364b2017-03-24 17:55:42 -0700838 void *data = ((uint8_t *) camMemory->mHidlHeapMemData) + bufferIndex * camMemory->mBufSize;
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800839 if (handle) {
840 VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) data;
Yin-Chia Yeh1ee279d2017-04-17 17:44:52 -0700841 if (md->eType == kMetadataBufferTypeNativeHandleSource) {
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800842 // Input handle will be closed by HIDL transport later, so clone it
843 // HAL implementation is responsible to close/delete the clone
844 native_handle_t* clone = native_handle_clone(handle);
845 if (!clone) {
846 ALOGE("%s: failed to clone buffer %p", __FUNCTION__, handle);
847 return;
848 }
849 md->pHandle = clone;
850 } else {
851 ALOGE("%s:Malform VideoNativeHandleMetadata at memId %d, bufferId %d",
852 __FUNCTION__, memId, bufferIndex);
853 return;
854 }
855 }
856 mDevice->ops->release_recording_frame(mDevice, data);
857 }
858}
859
860Return<void> CameraDevice::releaseRecordingFrame(uint32_t memId, uint32_t bufferIndex) {
861 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
862 Mutex::Autolock _l(mLock);
863 releaseRecordingFrameLocked(memId, bufferIndex, nullptr);
864 return Void();
865}
866
867Return<void> CameraDevice::releaseRecordingFrameHandle(
868 uint32_t memId, uint32_t bufferIndex, const hidl_handle& frame) {
869 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
870 Mutex::Autolock _l(mLock);
871 releaseRecordingFrameLocked(
872 memId, bufferIndex, frame.getNativeHandle());
873 return Void();
874}
875
Yin-Chia Yeh1ba83a92017-03-21 17:47:02 -0700876Return<void> CameraDevice::releaseRecordingFrameHandleBatch(
877 const hidl_vec<VideoFrameMessage>& msgs) {
878 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
879 Mutex::Autolock _l(mLock);
880 for (auto& msg : msgs) {
881 releaseRecordingFrameLocked(
882 msg.data, msg.bufferIndex, msg.frameData.getNativeHandle());
883 }
884 return Void();
885}
886
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800887Return<Status> CameraDevice::autoFocus() {
888 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
889 Mutex::Autolock _l(mLock);
890 if (!mDevice) {
891 ALOGE("%s called while camera is not opened", __FUNCTION__);
892 return Status::OPERATION_NOT_SUPPORTED;
893 }
894 if (mDevice->ops->auto_focus) {
895 return getHidlStatus(mDevice->ops->auto_focus(mDevice));
896 }
897 return Status::ILLEGAL_ARGUMENT;
898}
899
900Return<Status> CameraDevice::cancelAutoFocus() {
901 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
902 Mutex::Autolock _l(mLock);
903 if (!mDevice) {
904 ALOGE("%s called while camera is not opened", __FUNCTION__);
905 return Status::OPERATION_NOT_SUPPORTED;
906 }
907 if (mDevice->ops->cancel_auto_focus) {
908 return getHidlStatus(mDevice->ops->cancel_auto_focus(mDevice));
909 }
910 return Status::ILLEGAL_ARGUMENT;
911}
912
913Return<Status> CameraDevice::takePicture() {
914 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
915 Mutex::Autolock _l(mLock);
916 if (!mDevice) {
917 ALOGE("%s called while camera is not opened", __FUNCTION__);
918 return Status::OPERATION_NOT_SUPPORTED;
919 }
920 if (mDevice->ops->take_picture) {
921 return getHidlStatus(mDevice->ops->take_picture(mDevice));
922 }
923 return Status::ILLEGAL_ARGUMENT;
924}
925
926Return<Status> CameraDevice::cancelPicture() {
927 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
928 Mutex::Autolock _l(mLock);
929 if (!mDevice) {
930 ALOGE("%s called while camera is not opened", __FUNCTION__);
931 return Status::OPERATION_NOT_SUPPORTED;
932 }
933 if (mDevice->ops->cancel_picture) {
934 return getHidlStatus(mDevice->ops->cancel_picture(mDevice));
935 }
936 return Status::ILLEGAL_ARGUMENT;
937}
938
939Return<Status> CameraDevice::setParameters(const hidl_string& params) {
940 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
941 Mutex::Autolock _l(mLock);
942 if (!mDevice) {
943 ALOGE("%s called while camera is not opened", __FUNCTION__);
944 return Status::OPERATION_NOT_SUPPORTED;
945 }
946 if (mDevice->ops->set_parameters) {
947 return getHidlStatus(mDevice->ops->set_parameters(mDevice, params.c_str()));
948 }
949 return Status::ILLEGAL_ARGUMENT;
950}
951
952Return<void> CameraDevice::getParameters(getParameters_cb _hidl_cb) {
953 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
954 Mutex::Autolock _l(mLock);
955 hidl_string outStr;
956 if (!mDevice) {
957 ALOGE("%s called while camera is not opened", __FUNCTION__);
958 _hidl_cb(outStr);
959 return Void();
960 }
961 if (mDevice->ops->get_parameters) {
962 char *temp = mDevice->ops->get_parameters(mDevice);
963 outStr = temp;
964 if (mDevice->ops->put_parameters) {
965 mDevice->ops->put_parameters(mDevice, temp);
966 } else {
967 free(temp);
968 }
969 }
970 _hidl_cb(outStr);
971 return Void();
972}
973
974Return<Status> CameraDevice::sendCommand(CommandType cmd, int32_t arg1, int32_t arg2) {
975 ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str());
976 Mutex::Autolock _l(mLock);
977 if (!mDevice) {
978 ALOGE("%s called while camera is not opened", __FUNCTION__);
979 return Status::OPERATION_NOT_SUPPORTED;
980 }
981 if (mDevice->ops->send_command) {
982 return getHidlStatus(mDevice->ops->send_command(mDevice, (int32_t) cmd, arg1, arg2));
983 }
984 return Status::ILLEGAL_ARGUMENT;
985}
986
987Return<void> CameraDevice::close() {
988 ALOGI("Closing camera %s", mCameraId.c_str());
989 Mutex::Autolock _l(mLock);
990 if(mDevice) {
991 int rc = mDevice->common.close(&mDevice->common);
992 if (rc != OK) {
993 ALOGE("Could not close camera %s: %d", mCameraId.c_str(), rc);
994 }
995 mDevice = nullptr;
996 }
997 return Void();
998}
999
1000} // namespace implementation
1001} // namespace V1_0
1002} // namespace device
1003} // namespace camera
1004} // namespace hardware
1005} // namespace android