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