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 EmulatedCamera that encapsulates
19  * functionality common to all emulated cameras ("fake", "webcam", "video file",
20  * etc.). Instances of this class (for each emulated camera) are created during
21  * the construction of the EmulatedCameraFactory instance. This class serves as
22  * an entry point for all camera API calls that defined by camera_device_ops_t
23  * API.
24  */
25 
26 #define LOG_NDEBUG 0
27 #define LOG_TAG "EmulatedCamera_Camera"
28 #include <log/log.h>
29 #include "EmulatedCamera.h"
30 //#include "EmulatedFakeCameraDevice.h"
31 #include "Converters.h"
32 
33 /* Defines whether we should trace parameter changes. */
34 #define DEBUG_PARAM 1
35 
36 namespace android {
37 namespace {
38 const char* kSupportedFlashModes[] = {
39     CameraParameters::FLASH_MODE_OFF,   CameraParameters::FLASH_MODE_AUTO,
40     CameraParameters::FLASH_MODE_ON,    CameraParameters::FLASH_MODE_RED_EYE,
41     CameraParameters::FLASH_MODE_TORCH, NULL};
42 
BuildParameterValue(const char ** value_array)43 std::string BuildParameterValue(const char** value_array) {
44   std::string result;
45 
46   for (int index = 0; value_array[index] != NULL; ++index) {
47     if (index) result.append(",");
48     result.append(value_array[index]);
49   }
50   return result;
51 }
52 
CheckParameterValue(const char * value,const char ** supported_values)53 bool CheckParameterValue(const char* value, const char** supported_values) {
54   for (int index = 0; supported_values[index] != NULL; ++index) {
55     if (!strcmp(value, supported_values[index])) return true;
56   }
57   return false;
58 }
59 
60 }  // namespace
61 
62 #if DEBUG_PARAM
63 /* Calculates and logs parameter changes.
64  * Param:
65  *  current - Current set of camera parameters.
66  *  new_par - String representation of new parameters.
67  */
68 static void PrintParamDiff(const CameraParameters& current,
69                            const char* new_par);
70 #else
71 #define PrintParamDiff(current, new_par) (void(0))
72 #endif /* DEBUG_PARAM */
73 
EmulatedCamera(int cameraId,struct hw_module_t * module)74 EmulatedCamera::EmulatedCamera(int cameraId, struct hw_module_t* module)
75     : EmulatedBaseCamera(cameraId, HARDWARE_DEVICE_API_VERSION(1, 0), &common,
76                          module),
77       mPreviewWindow(),
78       mCallbackNotifier() {
79   /* camera_device v1 fields. */
80   common.close = EmulatedCamera::close;
81   ops = &mDeviceOps;
82   priv = this;
83 }
84 
~EmulatedCamera()85 EmulatedCamera::~EmulatedCamera() {}
86 
87 /****************************************************************************
88  * Public API
89  ***************************************************************************/
90 
Initialize(const cvd::CameraDefinition &)91 status_t EmulatedCamera::Initialize(const cvd::CameraDefinition&) {
92   /* Preview formats supported by this HAL. */
93   char preview_formats[1024];
94   snprintf(preview_formats, sizeof(preview_formats), "%s,%s,%s",
95            CameraParameters::PIXEL_FORMAT_YUV420SP,
96            CameraParameters::PIXEL_FORMAT_YUV420P,
97            CameraParameters::PIXEL_FORMAT_RGBA8888);
98 
99   /*
100    * Fake required parameters.
101    */
102 
103   mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
104                   "320x240,0x0");
105 
106   mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "512");
107   mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "384");
108   mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90");
109   mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.31");
110   mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "54.8");
111   mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "42.5");
112   mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
113 
114   /* Preview format settings used here are related to panoramic view only. It's
115    * not related to the preview window that works only with RGB frames, which
116    * is explicitly stated when set_buffers_geometry is called on the preview
117    * window object. */
118   mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
119                   preview_formats);
120   mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
121 
122   /* We don't relay on the actual frame rates supported by the camera device,
123    * since we will emulate them through timeouts in the emulated camera device
124    * worker thread. */
125   mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
126                   "30,24,20,15,10,5");
127   mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
128                   "(5000,30000),(15000,15000),(30000,30000)");
129   mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "5000,30000");
130   mParameters.setPreviewFrameRate(30000);
131 
132   /* Only PIXEL_FORMAT_YUV420P is accepted by video framework in emulator! */
133   mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
134                   CameraParameters::PIXEL_FORMAT_YUV420P);
135   mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
136                   CameraParameters::PIXEL_FORMAT_JPEG);
137   mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
138 
139   /* Set exposure compensation. */
140   mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6");
141   mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6");
142   mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5");
143   mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0");
144 
145   /* Sets the white balance modes and the device-dependent scale factors. */
146   char supported_white_balance[1024];
147   snprintf(supported_white_balance, sizeof(supported_white_balance),
148            "%s,%s,%s,%s", CameraParameters::WHITE_BALANCE_AUTO,
149            CameraParameters::WHITE_BALANCE_INCANDESCENT,
150            CameraParameters::WHITE_BALANCE_DAYLIGHT,
151            CameraParameters::WHITE_BALANCE_TWILIGHT);
152   mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
153                   supported_white_balance);
154   mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
155                   CameraParameters::WHITE_BALANCE_AUTO);
156   getCameraDevice()->initializeWhiteBalanceModes(
157       CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f);
158   getCameraDevice()->initializeWhiteBalanceModes(
159       CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f);
160   getCameraDevice()->initializeWhiteBalanceModes(
161       CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f);
162   getCameraDevice()->initializeWhiteBalanceModes(
163       CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f);
164   getCameraDevice()->setWhiteBalanceMode(CameraParameters::WHITE_BALANCE_AUTO);
165 
166   /*
167    * Not supported features
168    */
169   mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
170                   CameraParameters::FOCUS_MODE_FIXED);
171   mParameters.set(CameraParameters::KEY_FOCUS_MODE,
172                   CameraParameters::FOCUS_MODE_FIXED);
173   mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
174                   BuildParameterValue(kSupportedFlashModes).c_str());
175   mParameters.set(CameraParameters::KEY_FLASH_MODE,
176                   CameraParameters::FLASH_MODE_OFF);
177   mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, "0.1,0.1,0.1");
178   mParameters.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, "0");
179   mParameters.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW, "0");
180   mParameters.set(CameraParameters::KEY_ZOOM_RATIOS, "100");
181   mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED,
182                   CameraParameters::FALSE);
183   mParameters.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
184                   CameraParameters::FALSE);
185   mParameters.set(CameraParameters::KEY_ZOOM, "0");
186   mParameters.set(CameraParameters::KEY_MAX_ZOOM, "0");
187 
188   return NO_ERROR;
189 }
190 
onNextFrameAvailable(const void * frame,nsecs_t timestamp,EmulatedCameraDevice * camera_dev)191 void EmulatedCamera::onNextFrameAvailable(const void* frame, nsecs_t timestamp,
192                                           EmulatedCameraDevice* camera_dev) {
193   /* Notify the preview window first. */
194   mPreviewWindow.onNextFrameAvailable(frame, timestamp, camera_dev);
195 
196   /* Notify callback notifier next. */
197   mCallbackNotifier.onNextFrameAvailable(frame, timestamp, camera_dev);
198 }
199 
onCameraDeviceError(int err)200 void EmulatedCamera::onCameraDeviceError(int err) {
201   /* Errors are reported through the callback notifier */
202   mCallbackNotifier.onCameraDeviceError(err);
203 }
204 
onCameraFocusAcquired()205 void EmulatedCamera::onCameraFocusAcquired() {
206   mCallbackNotifier.onCameraFocusAcquired();
207 }
208 
209 /****************************************************************************
210  * Camera API implementation.
211  ***************************************************************************/
212 
connectCamera(hw_device_t ** device)213 status_t EmulatedCamera::connectCamera(hw_device_t** device) {
214   ALOGV("%s", __FUNCTION__);
215 
216   status_t res = EINVAL;
217   EmulatedCameraDevice* const camera_dev = getCameraDevice();
218   ALOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__);
219 
220   if (camera_dev != NULL) {
221     /* Connect to the camera device. */
222     res = getCameraDevice()->connectDevice();
223     if (res == NO_ERROR) {
224       *device = &common;
225     }
226   }
227 
228   return -res;
229 }
230 
closeCamera()231 status_t EmulatedCamera::closeCamera() {
232   ALOGV("%s", __FUNCTION__);
233 
234   return cleanupCamera();
235 }
236 
getCameraInfo(struct camera_info * info)237 status_t EmulatedCamera::getCameraInfo(struct camera_info* info) {
238   ALOGV("%s", __FUNCTION__);
239 
240   const char* valstr = NULL;
241 
242   valstr = mParameters.get(EmulatedCamera::FACING_KEY);
243   if (valstr != NULL) {
244     if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) {
245       info->facing = CAMERA_FACING_FRONT;
246     } else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) {
247       info->facing = CAMERA_FACING_BACK;
248     }
249   } else {
250     info->facing = CAMERA_FACING_BACK;
251   }
252 
253   valstr = mParameters.get(EmulatedCamera::ORIENTATION_KEY);
254   if (valstr != NULL) {
255     info->orientation = atoi(valstr);
256   } else {
257     info->orientation = 0;
258   }
259 
260   info->resource_cost = 100;
261   info->conflicting_devices = NULL;
262   info->conflicting_devices_length = 0;
263 
264   return EmulatedBaseCamera::getCameraInfo(info);
265 }
266 
getCameraParameters()267 const CameraParameters* EmulatedCamera::getCameraParameters() {
268   return &mParameters;
269 }
270 
setPreviewWindow(struct preview_stream_ops * window)271 status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window) {
272   /* Callback should return a negative errno. */
273   return -mPreviewWindow.setPreviewWindow(window,
274                                           mParameters.getPreviewFrameRate());
275 }
276 
setCallbacks(camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)277 void EmulatedCamera::setCallbacks(
278     camera_notify_callback notify_cb, camera_data_callback data_cb,
279     camera_data_timestamp_callback data_cb_timestamp,
280     camera_request_memory get_memory, void* user) {
281   mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp,
282                                  get_memory, user);
283 }
284 
enableMsgType(int32_t msg_type)285 void EmulatedCamera::enableMsgType(int32_t msg_type) {
286   mCallbackNotifier.enableMessage(msg_type);
287 }
288 
disableMsgType(int32_t msg_type)289 void EmulatedCamera::disableMsgType(int32_t msg_type) {
290   mCallbackNotifier.disableMessage(msg_type);
291 }
292 
isMsgTypeEnabled(int32_t msg_type)293 int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type) {
294   return mCallbackNotifier.isMessageEnabled(msg_type);
295 }
296 
startPreview()297 status_t EmulatedCamera::startPreview() {
298   /* Callback should return a negative errno. */
299   return -doStartPreview();
300 }
301 
stopPreview()302 void EmulatedCamera::stopPreview() { doStopPreview(); }
303 
isPreviewEnabled()304 int EmulatedCamera::isPreviewEnabled() {
305   return mPreviewWindow.isPreviewEnabled();
306 }
307 
storeMetaDataInBuffers(int enable)308 status_t EmulatedCamera::storeMetaDataInBuffers(int enable) {
309   /* Callback should return a negative errno. */
310   return -mCallbackNotifier.storeMetaDataInBuffers(enable);
311 }
312 
startRecording()313 status_t EmulatedCamera::startRecording() {
314   /* Callback should return a negative errno. */
315   return -mCallbackNotifier.enableVideoRecording(
316       mParameters.getPreviewFrameRate());
317 }
318 
stopRecording()319 void EmulatedCamera::stopRecording() {
320   mCallbackNotifier.disableVideoRecording();
321 }
322 
isRecordingEnabled()323 int EmulatedCamera::isRecordingEnabled() {
324   return mCallbackNotifier.isVideoRecordingEnabled();
325 }
326 
releaseRecordingFrame(const void * opaque)327 void EmulatedCamera::releaseRecordingFrame(const void* opaque) {
328   mCallbackNotifier.releaseRecordingFrame(opaque);
329 }
330 
setAutoFocus()331 status_t EmulatedCamera::setAutoFocus() {
332   ALOGV("%s", __FUNCTION__);
333 
334   /* Trigger auto-focus. Focus response cannot be sent directly from here. */
335   getCameraDevice()->startAutoFocus();
336 
337   /* TODO: Future enhancements. */
338   return NO_ERROR;
339 }
340 
cancelAutoFocus()341 status_t EmulatedCamera::cancelAutoFocus() {
342   ALOGV("%s", __FUNCTION__);
343 
344   /* TODO: Future enhancements. */
345   return NO_ERROR;
346 }
347 
takePicture()348 status_t EmulatedCamera::takePicture() {
349   ALOGV("%s", __FUNCTION__);
350 
351   status_t res;
352   int width, height;
353   uint32_t org_fmt;
354 
355   /* Collect frame info for the picture. */
356   mParameters.getPictureSize(&width, &height);
357   const char* pix_fmt = mParameters.getPictureFormat();
358   if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
359     org_fmt = V4L2_PIX_FMT_YUV420;
360   } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
361     org_fmt = V4L2_PIX_FMT_RGB32;
362   } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
363     org_fmt = V4L2_PIX_FMT_NV21;
364   } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
365     /* We only have JPEG converted for NV21 format. */
366     org_fmt = V4L2_PIX_FMT_NV21;
367   } else {
368     ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
369     return EINVAL;
370   }
371   /* Get JPEG quality. */
372   int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
373   if (jpeg_quality <= 0) {
374     jpeg_quality = 90; /* Fall back to default. */
375   }
376 
377   /*
378    * Make sure preview is not running, and device is stopped before taking
379    * picture.
380    */
381 
382   const bool preview_on = mPreviewWindow.isPreviewEnabled();
383   if (preview_on) {
384     doStopPreview();
385   }
386 
387   /* Camera device should have been stopped when the shutter message has been
388    * enabled. */
389   EmulatedCameraDevice* const camera_dev = getCameraDevice();
390   if (camera_dev->isStarted()) {
391     ALOGW("%s: Camera device is started", __FUNCTION__);
392     camera_dev->stopDeliveringFrames();
393     camera_dev->stopDevice();
394   }
395 
396   /* Compute target FPS rate.
397    * Pretend to simulate generation of (max_fps_rate) */
398   int min_fps_rate, max_fps_rate;
399   mParameters.getPreviewFpsRange(&min_fps_rate, &max_fps_rate);
400 
401   /*
402    * Take the picture now.
403    */
404 
405   /* Start camera device for the picture frame. */
406   ALOGD("Starting camera for picture: %.4s(%s)[%dx%d]",
407         reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height);
408   res = camera_dev->startDevice(width, height, org_fmt, max_fps_rate);
409   if (res != NO_ERROR) {
410     if (preview_on) {
411       doStartPreview();
412     }
413     return res;
414   }
415 
416   /* Deliver one frame only. */
417   mCallbackNotifier.setJpegQuality(jpeg_quality);
418   mCallbackNotifier.setTakingPicture(true);
419   res = camera_dev->startDeliveringFrames(true);
420   if (res != NO_ERROR) {
421     mCallbackNotifier.setTakingPicture(false);
422     if (preview_on) {
423       doStartPreview();
424     }
425   }
426   return res;
427 }
428 
cancelPicture()429 status_t EmulatedCamera::cancelPicture() {
430   ALOGV("%s", __FUNCTION__);
431 
432   return NO_ERROR;
433 }
434 
setParameters(const char * parms)435 status_t EmulatedCamera::setParameters(const char* parms) {
436   ALOGV("%s", __FUNCTION__);
437   PrintParamDiff(mParameters, parms);
438 
439   CameraParameters new_param;
440   String8 str8_param(parms);
441   new_param.unflatten(str8_param);
442 
443   /*
444    * Check if requested dimensions are valid.
445    */
446   if (!CheckParameterValue(new_param.get(CameraParameters::KEY_FLASH_MODE),
447                            kSupportedFlashModes)) {
448     ALOGE("%s: Unsupported flash mode: %s", __FUNCTION__,
449           new_param.get(CameraParameters::KEY_FLASH_MODE));
450     return -EINVAL;
451   }
452   if (strcmp(new_param.get(CameraParameters::KEY_FOCUS_MODE),
453              CameraParameters::FOCUS_MODE_FIXED)) {
454     ALOGE("%s: Unsupported flash mode: %s", __FUNCTION__,
455           new_param.get(CameraParameters::KEY_FOCUS_MODE));
456     return -EINVAL;
457   }
458 
459   int preview_width, preview_height;
460   new_param.getPreviewSize(&preview_width, &preview_height);
461   if (preview_width <= 0 || preview_height <= 0) return -EINVAL;
462 
463   /*
464    * Check for new exposure compensation parameter.
465    */
466   int new_exposure_compensation =
467       new_param.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
468   const int min_exposure_compensation =
469       new_param.getInt(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
470   const int max_exposure_compensation =
471       new_param.getInt(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);
472 
473   // Checks if the exposure compensation change is supported.
474   if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) {
475     if (new_exposure_compensation > max_exposure_compensation) {
476       new_exposure_compensation = max_exposure_compensation;
477     }
478     if (new_exposure_compensation < min_exposure_compensation) {
479       new_exposure_compensation = min_exposure_compensation;
480     }
481 
482     const int current_exposure_compensation =
483         mParameters.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
484     if (current_exposure_compensation != new_exposure_compensation) {
485       const float exposure_value =
486           new_exposure_compensation *
487           new_param.getFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP);
488 
489       getCameraDevice()->setExposureCompensation(exposure_value);
490     }
491   }
492 
493   const char* new_white_balance =
494       new_param.get(CameraParameters::KEY_WHITE_BALANCE);
495   const char* supported_white_balance =
496       new_param.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);
497 
498   if ((supported_white_balance != NULL) && (new_white_balance != NULL) &&
499       (strstr(supported_white_balance, new_white_balance) != NULL)) {
500     const char* current_white_balance =
501         mParameters.get(CameraParameters::KEY_WHITE_BALANCE);
502     if ((current_white_balance == NULL) ||
503         (strcmp(current_white_balance, new_white_balance) != 0)) {
504       ALOGV("Setting white balance to %s", new_white_balance);
505       getCameraDevice()->setWhiteBalanceMode(new_white_balance);
506     }
507   }
508 
509   mParameters = new_param;
510 
511   return NO_ERROR;
512 }
513 
514 /* A dumb variable indicating "no params" / error on the exit from
515  * EmulatedCamera::getParameters(). */
516 static char lNoParam = '\0';
getParameters()517 char* EmulatedCamera::getParameters() {
518   String8 params(mParameters.flatten());
519   char* ret_str =
520       reinterpret_cast<char*>(malloc(sizeof(char) * (params.length() + 1)));
521   memset(ret_str, 0, params.length() + 1);
522   if (ret_str != NULL) {
523     strncpy(ret_str, params.string(), params.length() + 1);
524     return ret_str;
525   } else {
526     ALOGE("%s: Unable to allocate string for %s", __FUNCTION__,
527           params.string());
528     /* Apparently, we can't return NULL fron this routine. */
529     return &lNoParam;
530   }
531 }
532 
putParameters(char * params)533 void EmulatedCamera::putParameters(char* params) {
534   /* This method simply frees parameters allocated in getParameters(). */
535   if (params != NULL && params != &lNoParam) {
536     free(params);
537   }
538 }
539 
sendCommand(int32_t cmd,int32_t arg1,int32_t arg2)540 status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
541   ALOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2);
542 
543   switch (cmd) {
544     case CAMERA_CMD_START_FACE_DETECTION:
545     case CAMERA_CMD_STOP_FACE_DETECTION:
546       return -EINVAL;
547   }
548 
549   /* TODO: Future enhancements. */
550   return 0;
551 }
552 
releaseCamera()553 void EmulatedCamera::releaseCamera() {
554   ALOGV("%s", __FUNCTION__);
555 
556   cleanupCamera();
557 }
558 
dumpCamera(int)559 status_t EmulatedCamera::dumpCamera(int /*fd*/) {
560   ALOGV("%s", __FUNCTION__);
561 
562   /* TODO: Future enhancements. */
563   return -EINVAL;
564 }
565 
566 /****************************************************************************
567  * Preview management.
568  ***************************************************************************/
569 
doStartPreview()570 status_t EmulatedCamera::doStartPreview() {
571   ALOGV("%s", __FUNCTION__);
572 
573   EmulatedCameraDevice* camera_dev = getCameraDevice();
574   if (camera_dev->isStarted()) {
575     camera_dev->stopDeliveringFrames();
576     camera_dev->stopDevice();
577   }
578 
579   status_t res = mPreviewWindow.startPreview();
580   if (res != NO_ERROR) {
581     return res;
582   }
583 
584   /* Make sure camera device is connected. */
585   if (!camera_dev->isConnected()) {
586     res = camera_dev->connectDevice();
587     if (res != NO_ERROR) {
588       mPreviewWindow.stopPreview();
589       return res;
590     }
591   }
592 
593   int width, height;
594   /* Lets see what should we use for frame width, and height. */
595   if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != NULL) {
596     mParameters.getVideoSize(&width, &height);
597   } else {
598     mParameters.getPreviewSize(&width, &height);
599   }
600   /* Lets see what should we use for the frame pixel format. Note that there
601    * are two parameters that define pixel formats for frames sent to the
602    * application via notification callbacks:
603    * - KEY_VIDEO_FRAME_FORMAT, that is used when recording video, and
604    * - KEY_PREVIEW_FORMAT, that is used for preview frame notification.
605    * We choose one or the other, depending on "recording-hint" property set by
606    * the framework that indicating intention: video, or preview. */
607   const char* pix_fmt = NULL;
608   const char* is_video = mParameters.get(EmulatedCamera::RECORDING_HINT_KEY);
609   if (is_video == NULL) {
610     is_video = CameraParameters::FALSE;
611   }
612   if (strcmp(is_video, CameraParameters::TRUE) == 0) {
613     /* Video recording is requested. Lets see if video frame format is set. */
614     pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
615   }
616   /* If this was not video recording, or video frame format is not set, lets
617    * use preview pixel format for the main framebuffer. */
618   if (pix_fmt == NULL) {
619     pix_fmt = mParameters.getPreviewFormat();
620   }
621   if (pix_fmt == NULL) {
622     ALOGE("%s: Unable to obtain video format", __FUNCTION__);
623     mPreviewWindow.stopPreview();
624     return EINVAL;
625   }
626 
627   /* Convert framework's pixel format to the FOURCC one. */
628   uint32_t org_fmt;
629   if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
630     org_fmt = V4L2_PIX_FMT_YUV420;
631   } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
632     org_fmt = V4L2_PIX_FMT_RGB32;
633   } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
634     org_fmt = V4L2_PIX_FMT_NV21;
635   } else {
636     ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
637     mPreviewWindow.stopPreview();
638     return EINVAL;
639   }
640 
641   /* Fetch the desired frame rate. */
642   int min_fps_rate, max_fps_rate;
643   mParameters.getPreviewFpsRange(&min_fps_rate, &max_fps_rate);
644 
645   ALOGD("Starting camera: %dx%d -> %.4s(%s)", width, height,
646         reinterpret_cast<const char*>(&org_fmt), pix_fmt);
647   res = camera_dev->startDevice(width, height, org_fmt, max_fps_rate);
648   if (res != NO_ERROR) {
649     mPreviewWindow.stopPreview();
650     return res;
651   }
652 
653   res = camera_dev->startDeliveringFrames(false);
654   if (res != NO_ERROR) {
655     camera_dev->stopDevice();
656     mPreviewWindow.stopPreview();
657   }
658 
659   return res;
660 }
661 
doStopPreview()662 status_t EmulatedCamera::doStopPreview() {
663   ALOGV("%s", __FUNCTION__);
664 
665   status_t res = NO_ERROR;
666   if (mPreviewWindow.isPreviewEnabled()) {
667     /* Stop the camera. */
668     if (getCameraDevice()->isStarted()) {
669       getCameraDevice()->stopDeliveringFrames();
670       res = getCameraDevice()->stopDevice();
671     }
672 
673     if (res == NO_ERROR) {
674       /* Disable preview as well. */
675       mPreviewWindow.stopPreview();
676     }
677   }
678 
679   return NO_ERROR;
680 }
681 
682 /****************************************************************************
683  * Private API.
684  ***************************************************************************/
685 
cleanupCamera()686 status_t EmulatedCamera::cleanupCamera() {
687   status_t res = NO_ERROR;
688 
689   /* If preview is running - stop it. */
690   res = doStopPreview();
691   if (res != NO_ERROR) {
692     return -res;
693   }
694 
695   /* Stop and disconnect the camera device. */
696   EmulatedCameraDevice* const camera_dev = getCameraDevice();
697   if (camera_dev != NULL) {
698     if (camera_dev->isStarted()) {
699       camera_dev->stopDeliveringFrames();
700       res = camera_dev->stopDevice();
701       if (res != NO_ERROR) {
702         return -res;
703       }
704     }
705     if (camera_dev->isConnected()) {
706       res = camera_dev->disconnectDevice();
707       if (res != NO_ERROR) {
708         return -res;
709       }
710     }
711   }
712 
713   mCallbackNotifier.cleanupCBNotifier();
714 
715   return NO_ERROR;
716 }
717 
718 /****************************************************************************
719  * Camera API callbacks as defined by camera_device_ops structure.
720  *
721  * Callbacks here simply dispatch the calls to an appropriate method inside
722  * EmulatedCamera instance, defined by the 'dev' parameter.
723  ***************************************************************************/
724 
set_preview_window(struct camera_device * dev,struct preview_stream_ops * window)725 int EmulatedCamera::set_preview_window(struct camera_device* dev,
726                                        struct preview_stream_ops* window) {
727   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
728   if (ec == NULL) {
729     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
730     return -EINVAL;
731   }
732   return ec->setPreviewWindow(window);
733 }
734 
set_callbacks(struct camera_device * dev,camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)735 void EmulatedCamera::set_callbacks(
736     struct camera_device* dev, camera_notify_callback notify_cb,
737     camera_data_callback data_cb,
738     camera_data_timestamp_callback data_cb_timestamp,
739     camera_request_memory get_memory, void* user) {
740   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
741   if (ec == NULL) {
742     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
743     return;
744   }
745   ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
746 }
747 
enable_msg_type(struct camera_device * dev,int32_t msg_type)748 void EmulatedCamera::enable_msg_type(struct camera_device* dev,
749                                      int32_t msg_type) {
750   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
751   if (ec == NULL) {
752     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
753     return;
754   }
755   ec->enableMsgType(msg_type);
756 }
757 
disable_msg_type(struct camera_device * dev,int32_t msg_type)758 void EmulatedCamera::disable_msg_type(struct camera_device* dev,
759                                       int32_t msg_type) {
760   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
761   if (ec == NULL) {
762     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
763     return;
764   }
765   ec->disableMsgType(msg_type);
766 }
767 
msg_type_enabled(struct camera_device * dev,int32_t msg_type)768 int EmulatedCamera::msg_type_enabled(struct camera_device* dev,
769                                      int32_t msg_type) {
770   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
771   if (ec == NULL) {
772     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
773     return -EINVAL;
774   }
775   return ec->isMsgTypeEnabled(msg_type);
776 }
777 
start_preview(struct camera_device * dev)778 int EmulatedCamera::start_preview(struct camera_device* dev) {
779   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
780   if (ec == NULL) {
781     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
782     return -EINVAL;
783   }
784   return ec->startPreview();
785 }
786 
stop_preview(struct camera_device * dev)787 void EmulatedCamera::stop_preview(struct camera_device* dev) {
788   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
789   if (ec == NULL) {
790     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
791     return;
792   }
793   ec->stopPreview();
794 }
795 
preview_enabled(struct camera_device * dev)796 int EmulatedCamera::preview_enabled(struct camera_device* dev) {
797   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
798   if (ec == NULL) {
799     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
800     return -EINVAL;
801   }
802   return ec->isPreviewEnabled();
803 }
804 
store_meta_data_in_buffers(struct camera_device * dev,int enable)805 int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev,
806                                                int enable) {
807   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
808   if (ec == NULL) {
809     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
810     return -EINVAL;
811   }
812   return ec->storeMetaDataInBuffers(enable);
813 }
814 
start_recording(struct camera_device * dev)815 int EmulatedCamera::start_recording(struct camera_device* dev) {
816   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
817   if (ec == NULL) {
818     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
819     return -EINVAL;
820   }
821   return ec->startRecording();
822 }
823 
stop_recording(struct camera_device * dev)824 void EmulatedCamera::stop_recording(struct camera_device* dev) {
825   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
826   if (ec == NULL) {
827     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
828     return;
829   }
830   ec->stopRecording();
831 }
832 
recording_enabled(struct camera_device * dev)833 int EmulatedCamera::recording_enabled(struct camera_device* dev) {
834   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
835   if (ec == NULL) {
836     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
837     return -EINVAL;
838   }
839   return ec->isRecordingEnabled();
840 }
841 
release_recording_frame(struct camera_device * dev,const void * opaque)842 void EmulatedCamera::release_recording_frame(struct camera_device* dev,
843                                              const void* opaque) {
844   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
845   if (ec == NULL) {
846     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
847     return;
848   }
849   ec->releaseRecordingFrame(opaque);
850 }
851 
auto_focus(struct camera_device * dev)852 int EmulatedCamera::auto_focus(struct camera_device* dev) {
853   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
854   if (ec == NULL) {
855     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
856     return -EINVAL;
857   }
858   return ec->setAutoFocus();
859 }
860 
cancel_auto_focus(struct camera_device * dev)861 int EmulatedCamera::cancel_auto_focus(struct camera_device* dev) {
862   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
863   if (ec == NULL) {
864     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
865     return -EINVAL;
866   }
867   return ec->cancelAutoFocus();
868 }
869 
take_picture(struct camera_device * dev)870 int EmulatedCamera::take_picture(struct camera_device* dev) {
871   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
872   if (ec == NULL) {
873     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
874     return -EINVAL;
875   }
876   return ec->takePicture();
877 }
878 
cancel_picture(struct camera_device * dev)879 int EmulatedCamera::cancel_picture(struct camera_device* dev) {
880   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
881   if (ec == NULL) {
882     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
883     return -EINVAL;
884   }
885   return ec->cancelPicture();
886 }
887 
set_parameters(struct camera_device * dev,const char * parms)888 int EmulatedCamera::set_parameters(struct camera_device* dev,
889                                    const char* parms) {
890   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
891   if (ec == NULL) {
892     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
893     return -EINVAL;
894   }
895   return ec->setParameters(parms);
896 }
897 
get_parameters(struct camera_device * dev)898 char* EmulatedCamera::get_parameters(struct camera_device* dev) {
899   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
900   if (ec == NULL) {
901     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
902     return NULL;
903   }
904   return ec->getParameters();
905 }
906 
put_parameters(struct camera_device * dev,char * params)907 void EmulatedCamera::put_parameters(struct camera_device* dev, char* params) {
908   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
909   if (ec == NULL) {
910     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
911     return;
912   }
913   ec->putParameters(params);
914 }
915 
send_command(struct camera_device * dev,int32_t cmd,int32_t arg1,int32_t arg2)916 int EmulatedCamera::send_command(struct camera_device* dev, int32_t cmd,
917                                  int32_t arg1, int32_t arg2) {
918   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
919   if (ec == NULL) {
920     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
921     return -EINVAL;
922   }
923   return ec->sendCommand(cmd, arg1, arg2);
924 }
925 
release(struct camera_device * dev)926 void EmulatedCamera::release(struct camera_device* dev) {
927   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
928   if (ec == NULL) {
929     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
930     return;
931   }
932   ec->releaseCamera();
933 }
934 
dump(struct camera_device * dev,int fd)935 int EmulatedCamera::dump(struct camera_device* dev, int fd) {
936   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
937   if (ec == NULL) {
938     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
939     return -EINVAL;
940   }
941   return ec->dumpCamera(fd);
942 }
943 
close(struct hw_device_t * device)944 int EmulatedCamera::close(struct hw_device_t* device) {
945   EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(
946       reinterpret_cast<struct camera_device*>(device)->priv);
947   if (ec == NULL) {
948     ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
949     return -EINVAL;
950   }
951   return ec->closeCamera();
952 }
953 
954 /****************************************************************************
955  * Static initializer for the camera callback API
956  ****************************************************************************/
957 
958 camera_device_ops_t EmulatedCamera::mDeviceOps = {
959     EmulatedCamera::set_preview_window,
960     EmulatedCamera::set_callbacks,
961     EmulatedCamera::enable_msg_type,
962     EmulatedCamera::disable_msg_type,
963     EmulatedCamera::msg_type_enabled,
964     EmulatedCamera::start_preview,
965     EmulatedCamera::stop_preview,
966     EmulatedCamera::preview_enabled,
967     EmulatedCamera::store_meta_data_in_buffers,
968     EmulatedCamera::start_recording,
969     EmulatedCamera::stop_recording,
970     EmulatedCamera::recording_enabled,
971     EmulatedCamera::release_recording_frame,
972     EmulatedCamera::auto_focus,
973     EmulatedCamera::cancel_auto_focus,
974     EmulatedCamera::take_picture,
975     EmulatedCamera::cancel_picture,
976     EmulatedCamera::set_parameters,
977     EmulatedCamera::get_parameters,
978     EmulatedCamera::put_parameters,
979     EmulatedCamera::send_command,
980     EmulatedCamera::release,
981     EmulatedCamera::dump};
982 
983 /****************************************************************************
984  * Common keys
985  ***************************************************************************/
986 
987 const char EmulatedCamera::FACING_KEY[] = "prop-facing";
988 const char EmulatedCamera::ORIENTATION_KEY[] = "prop-orientation";
989 const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint";
990 
991 /****************************************************************************
992  * Common string values
993  ***************************************************************************/
994 
995 const char EmulatedCamera::FACING_BACK[] = "back";
996 const char EmulatedCamera::FACING_FRONT[] = "front";
997 
998 /****************************************************************************
999  * Parameter debugging helpers
1000  ***************************************************************************/
1001 
1002 #if DEBUG_PARAM
PrintParamDiff(const CameraParameters & current,const char * new_par)1003 static void PrintParamDiff(const CameraParameters& current,
1004                            const char* new_par) {
1005   char tmp[2048];
1006   const char* wrk = new_par;
1007 
1008   /* Divided with ';' */
1009   const char* next = strchr(wrk, ';');
1010   while (next != NULL) {
1011     snprintf(tmp, sizeof(tmp), "%.*s", (int)(intptr_t)(next - wrk), wrk);
1012     /* in the form key=value */
1013     char* val = strchr(tmp, '=');
1014     if (val != NULL) {
1015       *val = '\0';
1016       val++;
1017       const char* in_current = current.get(tmp);
1018       if (in_current != NULL) {
1019         if (strcmp(in_current, val)) {
1020           ALOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val);
1021         }
1022       } else {
1023         ALOGD("+++ New parameter: %s=%s", tmp, val);
1024       }
1025     } else {
1026       ALOGW("No value separator in %s", tmp);
1027     }
1028     wrk = next + 1;
1029     next = strchr(wrk, ';');
1030   }
1031 }
1032 #endif /* DEBUG_PARAM */
1033 
1034 }; /* namespace android */
1035