• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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