1 /*
2 * Copyright (C) 2011 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 /*
18 * Contains implementation of a class EmulatedCameraFactory that manages cameras
19 * available for emulation.
20 */
21
22 #define LOG_NDEBUG 0
23 #define LOG_TAG "EmulatedCamera_Factory"
24 #include <log/log.h>
25 #include <cutils/properties.h>
26 #include "EmulatedFakeCamera.h"
27 #include "guest/libs/platform_support/api_level_fixes.h"
28
29 #if VSOC_PLATFORM_SDK_AFTER(J_MR2)
30 #include "EmulatedCameraHotplugThread.h"
31 #include "EmulatedFakeCamera2.h"
32 #endif
33
34 #if VSOC_PLATFORM_SDK_AFTER(L_MR1)
35 #include "EmulatedFakeCamera3.h"
36 #endif
37
38 #include "EmulatedCameraFactory.h"
39
40 extern camera_module_t HAL_MODULE_INFO_SYM;
41
42 namespace android {
Instance()43 EmulatedCameraFactory& EmulatedCameraFactory::Instance() {
44 static EmulatedCameraFactory* factory = new EmulatedCameraFactory;
45 return *factory;
46 }
47
EmulatedCameraFactory()48 EmulatedCameraFactory::EmulatedCameraFactory()
49 #if VSOC_PLATFORM_SDK_AFTER(J_MR2)
50 : mCallbacks(NULL)
51 #endif
52 {
53 mCameraConfiguration.Init();
54 const std::vector<cvd::CameraDefinition>& cameras =
55 mCameraConfiguration.cameras();
56 for (size_t camera_index = 0; camera_index < cameras.size(); ++camera_index) {
57 mCameraDefinitions.push(cameras[camera_index]);
58 /* Reserve a spot for camera, but don't create just yet. */
59 mEmulatedCameras.push(NULL);
60 }
61
62 ALOGV("%zu cameras are being emulated.", getEmulatedCameraNum());
63
64 #if VSOC_PLATFORM_SDK_AFTER(J_MR2)
65 /* Create hotplug thread */
66 {
67 mHotplugThread = new EmulatedCameraHotplugThread(getEmulatedCameraNum());
68 mHotplugThread->run("EmulatedCameraHotplugThread");
69 }
70 #endif
71 }
72
getOrCreateFakeCamera(size_t cameraId)73 EmulatedBaseCamera* EmulatedCameraFactory::getOrCreateFakeCamera(
74 size_t cameraId) {
75 ::cvd::LockGuard< ::cvd::Mutex> lock(mEmulatedCamerasMutex);
76
77 if (cameraId >= getEmulatedCameraNum()) {
78 ALOGE("%s: Invalid camera ID: %zu", __FUNCTION__, cameraId);
79 return NULL;
80 }
81
82 if (mEmulatedCameras[cameraId] != NULL) {
83 return mEmulatedCameras[cameraId];
84 }
85
86 const cvd::CameraDefinition& definition = mCameraDefinitions[cameraId];
87 bool is_back_facing =
88 (definition.orientation == cvd::CameraDefinition::kBack);
89
90 EmulatedBaseCamera* camera;
91 /* Create, and initialize the fake camera */
92 switch (definition.hal_version) {
93 case cvd::CameraDefinition::kHalV1:
94 camera = new EmulatedFakeCamera(cameraId, is_back_facing,
95 &HAL_MODULE_INFO_SYM.common);
96 break;
97 #if VSOC_PLATFORM_SDK_AFTER(J_MR2)
98 case cvd::CameraDefinition::kHalV2:
99 camera = new EmulatedFakeCamera2(cameraId, is_back_facing,
100 &HAL_MODULE_INFO_SYM.common);
101 break;
102 #endif
103 #if VSOC_PLATFORM_SDK_AFTER(L_MR1)
104 case cvd::CameraDefinition::kHalV3:
105 camera = new EmulatedFakeCamera3(cameraId, is_back_facing,
106 &HAL_MODULE_INFO_SYM.common);
107 break;
108 #endif
109 default:
110 ALOGE("%s: Unsupported camera hal version requested: %d", __FUNCTION__,
111 definition.hal_version);
112 return NULL;
113 }
114
115 ALOGI("%s: Camera device %zu hal version is %d", __FUNCTION__, cameraId,
116 definition.hal_version);
117 int res = camera->Initialize(definition);
118
119 if (res != NO_ERROR) {
120 ALOGE("%s: Unable to intialize camera %zu: %s (%d)", __FUNCTION__, cameraId,
121 strerror(-res), res);
122 delete camera;
123 return NULL;
124 }
125
126 ALOGI("%s: Inserting camera", __FUNCTION__);
127 mEmulatedCameras.replaceAt(camera, cameraId);
128 ALOGI("%s: Done", __FUNCTION__);
129 return camera;
130 }
131
~EmulatedCameraFactory()132 EmulatedCameraFactory::~EmulatedCameraFactory() {
133 for (size_t n = 0; n < mEmulatedCameras.size(); n++) {
134 if (mEmulatedCameras[n] != NULL) {
135 delete mEmulatedCameras[n];
136 }
137 }
138
139 #if VSOC_PLATFORM_SDK_AFTER(J_MR2)
140 if (mHotplugThread != NULL) {
141 mHotplugThread->requestExit();
142 mHotplugThread->join();
143 }
144 #endif
145 }
146
147 /****************************************************************************
148 * Camera HAL API handlers.
149 *
150 * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
151 * instance, and dispatches the call to that instance.
152 *
153 ***************************************************************************/
154
cameraDeviceOpen(int camera_id,hw_device_t ** device)155 int EmulatedCameraFactory::cameraDeviceOpen(int camera_id,
156 hw_device_t** device) {
157 ALOGV("%s: id = %d", __FUNCTION__, camera_id);
158
159 *device = NULL;
160
161 EmulatedBaseCamera* camera = getOrCreateFakeCamera(camera_id);
162 if (camera == NULL) return -EINVAL;
163
164 return camera->connectCamera(device);
165 }
166
getCameraInfo(int camera_id,struct camera_info * info)167 int EmulatedCameraFactory::getCameraInfo(int camera_id,
168 struct camera_info* info) {
169 ALOGV("%s: id = %d", __FUNCTION__, camera_id);
170
171 EmulatedBaseCamera* camera = getOrCreateFakeCamera(camera_id);
172 if (camera == NULL) return -EINVAL;
173
174 return camera->getCameraInfo(info);
175 }
176
177 #if VSOC_PLATFORM_SDK_AFTER(J_MR2)
setCallbacks(const camera_module_callbacks_t * callbacks)178 int EmulatedCameraFactory::setCallbacks(
179 const camera_module_callbacks_t* callbacks) {
180 ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks);
181
182 mCallbacks = callbacks;
183
184 return OK;
185 }
186
getVendorTagOps(vendor_tag_ops_t * ops)187 void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) {
188 ALOGV("%s: ops = %p", __FUNCTION__, ops);
189
190 // No vendor tags defined for emulator yet, so not touching ops
191 }
192 #endif
193
setTorchMode(const char * camera_id,bool enabled)194 int EmulatedCameraFactory::setTorchMode(const char* camera_id, bool enabled) {
195 ALOGV("%s: camera_id = %s, enabled =%d", __FUNCTION__, camera_id, enabled);
196
197 EmulatedBaseCamera* camera = getOrCreateFakeCamera(atoi(camera_id));
198 if (camera == NULL) return -EINVAL;
199
200 return camera->setTorchMode(enabled);
201 }
202
203 /****************************************************************************
204 * Camera HAL API callbacks.
205 ***************************************************************************/
206
device_open(const hw_module_t * module,const char * name,hw_device_t ** device)207 int EmulatedCameraFactory::device_open(const hw_module_t* module,
208 const char* name, hw_device_t** device) {
209 /*
210 * Simply verify the parameters, and dispatch the call inside the
211 * EmulatedCameraFactory instance.
212 */
213
214 if (module != &HAL_MODULE_INFO_SYM.common) {
215 ALOGE("%s: Invalid module %p expected %p", __FUNCTION__, module,
216 &HAL_MODULE_INFO_SYM.common);
217 return -EINVAL;
218 }
219 if (name == NULL) {
220 ALOGE("%s: NULL name is not expected here", __FUNCTION__);
221 return -EINVAL;
222 }
223
224 return EmulatedCameraFactory::Instance().cameraDeviceOpen(atoi(name), device);
225 }
226
get_number_of_cameras(void)227 int EmulatedCameraFactory::get_number_of_cameras(void) {
228 return EmulatedCameraFactory::Instance().getEmulatedCameraNum();
229 }
230
get_camera_info(int camera_id,struct camera_info * info)231 int EmulatedCameraFactory::get_camera_info(int camera_id,
232 struct camera_info* info) {
233 return EmulatedCameraFactory::Instance().getCameraInfo(camera_id, info);
234 }
235
236 #if VSOC_PLATFORM_SDK_AFTER(J_MR2)
set_callbacks(const camera_module_callbacks_t * callbacks)237 int EmulatedCameraFactory::set_callbacks(
238 const camera_module_callbacks_t* callbacks) {
239 return EmulatedCameraFactory::Instance().setCallbacks(callbacks);
240 }
241
get_vendor_tag_ops(vendor_tag_ops_t * ops)242 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t* ops) {
243 EmulatedCameraFactory::Instance().getVendorTagOps(ops);
244 }
245 #endif
246
open_legacy(const struct hw_module_t *,const char *,uint32_t,struct hw_device_t **)247 int EmulatedCameraFactory::open_legacy(const struct hw_module_t* /*module*/,
248 const char* /*id*/,
249 uint32_t /*halVersion*/,
250 struct hw_device_t** /*device*/) {
251 // Not supporting legacy open
252 return -ENOSYS;
253 }
254
set_torch_mode(const char * camera_id,bool enabled)255 int EmulatedCameraFactory::set_torch_mode(const char* camera_id, bool enabled) {
256 return EmulatedCameraFactory::Instance().setTorchMode(camera_id, enabled);
257 }
258
259 /********************************************************************************
260 * Internal API
261 *******************************************************************************/
262
onStatusChanged(int cameraId,int newStatus)263 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {
264 EmulatedBaseCamera* cam = getOrCreateFakeCamera(cameraId);
265 if (!cam) {
266 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
267 return;
268 }
269
270 /**
271 * (Order is important)
272 * Send the callback first to framework, THEN close the camera.
273 */
274
275 #if VSOC_PLATFORM_SDK_AFTER(J_MR2)
276 if (newStatus == cam->getHotplugStatus()) {
277 ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
278 return;
279 }
280
281 const camera_module_callbacks_t* cb = mCallbacks;
282 if (cb != NULL && cb->camera_device_status_change != NULL) {
283 cb->camera_device_status_change(cb, cameraId, newStatus);
284 }
285
286 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
287 cam->unplugCamera();
288 } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
289 cam->plugCamera();
290 }
291 #endif
292 }
293
onTorchModeStatusChanged(int cameraId,int newStatus)294 void EmulatedCameraFactory::onTorchModeStatusChanged(int cameraId,
295 int newStatus) {
296 EmulatedBaseCamera* cam = getOrCreateFakeCamera(cameraId);
297 if (!cam) {
298 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
299 return;
300 }
301
302 #if VSOC_PLATFORM_SDK_AFTER(L_MR1)
303 const camera_module_callbacks_t* cb = mCallbacks;
304 if (cb != NULL && cb->torch_mode_status_change != NULL) {
305 char id[10];
306 sprintf(id, "%d", cameraId);
307 cb->torch_mode_status_change(cb, id, newStatus);
308 }
309 #endif
310 }
311
312 /********************************************************************************
313 * Initializer for the static member structure.
314 *******************************************************************************/
315
316 /* Entry point for camera HAL API. */
317 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
318 VSOC_STATIC_INITIALIZER(open) EmulatedCameraFactory::device_open};
319
320 }; /* namespace android */
321