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