• 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 <stdio.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 static const char* kValidFocusModes[] = {
40     CameraParameters::FOCUS_MODE_AUTO,
41     CameraParameters::FOCUS_MODE_INFINITY,
42     CameraParameters::FOCUS_MODE_MACRO,
43     CameraParameters::FOCUS_MODE_FIXED,
44     CameraParameters::FOCUS_MODE_EDOF,
45     CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO,
46     CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
47 };
48 
49 #if DEBUG_PARAM
50 /* Calculates and logs parameter changes.
51  * Param:
52  *  current - Current set of camera parameters.
53  *  new_par - String representation of new parameters.
54  */
55 static void PrintParamDiff(const CameraParameters& current, const char* new_par);
56 #else
57 #define PrintParamDiff(current, new_par)   (void(0))
58 #endif  /* DEBUG_PARAM */
59 
60 /* A helper routine that adds a value to the camera parameter.
61  * Param:
62  *  param - Camera parameter to add a value to.
63  *  val - Value to add.
64  * Return:
65  *  A new string containing parameter with the added value on success, or NULL on
66  *  a failure. If non-NULL string is returned, the caller is responsible for
67  *  freeing it with 'free'.
68  */
69 static char* AddValue(const char* param, const char* val);
70 
71 /*
72  * Check if a given string |value| equals at least one of the strings in |list|
73  */
74 template<size_t N>
IsValueInList(const char * value,const char * const (& list)[N])75 static bool IsValueInList(const char* value, const char* const (&list)[N])
76 {
77     for (size_t i = 0; i < N; ++i) {
78         if (strcmp(value, list[i]) == 0) {
79             return true;
80         }
81     }
82     return false;
83 }
84 
StringsEqual(const char * str1,const char * str2)85 static bool StringsEqual(const char* str1, const char* str2) {
86     if (str1 == nullptr && str2 == nullptr) {
87         return true;
88     }
89     if (str1 == nullptr || str2 == nullptr) {
90         return false;
91     }
92     return strcmp(str1, str2) == 0;
93 }
94 
GetFourCcFormatFromCameraParam(const char * fmt_str,uint32_t * fmt_val)95 static bool GetFourCcFormatFromCameraParam(const char* fmt_str,
96                                            uint32_t* fmt_val) {
97     if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
98         // Despite the name above this is a YVU format, specifically YV12
99         *fmt_val = V4L2_PIX_FMT_YVU420;
100         return true;
101     } else if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
102         *fmt_val = V4L2_PIX_FMT_RGB32;
103         return true;
104     } else if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
105         *fmt_val = V4L2_PIX_FMT_NV21;
106         return true;
107     }
108     return false;
109 }
110 
EmulatedCamera(int cameraId,struct hw_module_t * module)111 EmulatedCamera::EmulatedCamera(int cameraId,
112                                struct hw_module_t* module)
113         : EmulatedBaseCamera(cameraId,
114                 HARDWARE_DEVICE_API_VERSION(1, 0),
115                 &common,
116                 module),
117           mPreviewWindow(),
118           mCallbackNotifier()
119 {
120     /* camera_device v1 fields. */
121     common.close = EmulatedCamera::close;
122     ops = &mDeviceOps;
123     priv = this;
124 }
125 
~EmulatedCamera()126 EmulatedCamera::~EmulatedCamera()
127 {
128 }
129 
130 /****************************************************************************
131  * Public API
132  ***************************************************************************/
133 
Initialize()134 status_t EmulatedCamera::Initialize()
135 {
136     /* Preview formats supported by this HAL. */
137     char preview_formats[1024];
138     snprintf(preview_formats, sizeof(preview_formats), "%s,%s,%s",
139              CameraParameters::PIXEL_FORMAT_YUV420SP,
140              CameraParameters::PIXEL_FORMAT_YUV420P,
141              CameraParameters::PIXEL_FORMAT_RGBA8888);
142 
143     /*
144      * Fake required parameters.
145      */
146 
147     mParameters.set(CameraParameters::KEY_RECORDING_HINT,
148                     CameraParameters::FALSE);
149     mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, "320x240,0x0");
150 
151     mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "320");
152     mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "240");
153     mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90");
154     // Camera values for a Logitech B910 HD Webcam
155     //     Focal length: 4.90 mm (from specs)
156     //     Horizontal view angle: 61 degrees for 4:3 sizes,
157     //         70 degrees for 16:9 sizes (empirical)
158     //     Vertical view angle: 45.8 degrees (= 61 * 3 / 4)
159     // (The Mac has only "4:3" image sizes; the correct angle
160     //  is 51.0 degrees. [MacBook Pro (Retina, 15-inch, Mid 2014)])
161     mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.90");
162     mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "61.0");
163     mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "45.8");
164     mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
165 
166     /* Preview format settings used here are related to panoramic view only. It's
167      * not related to the preview window that works only with RGB frames, which
168      * is explicitly stated when set_buffers_geometry is called on the preview
169      * window object. */
170     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
171                     preview_formats);
172     mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
173 
174     /* We don't rely on the actual frame rates supported by the camera device,
175      * since we will emulate them through timeouts in the emulated camera device
176      * worker thread. */
177     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
178                     "30,24,20,15,10,5");
179     mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(24000,24000)");
180     mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "24000,24000");
181     mParameters.setPreviewFrameRate(24);
182 
183     /* Only PIXEL_FORMAT_YUV420P is accepted by video framework in emulator! */
184     mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
185                     CameraParameters::PIXEL_FORMAT_YUV420P);
186     mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
187                     CameraParameters::PIXEL_FORMAT_JPEG);
188     mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
189 
190     /* Set exposure compensation. */
191     mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6");
192     mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6");
193     mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5");
194     mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0");
195 
196     /* Sets the white balance modes and the device-dependent scale factors. */
197     char supported_white_balance[1024];
198     snprintf(supported_white_balance, sizeof(supported_white_balance),
199              "%s,%s,%s,%s",
200              CameraParameters::WHITE_BALANCE_AUTO,
201              CameraParameters::WHITE_BALANCE_INCANDESCENT,
202              CameraParameters::WHITE_BALANCE_DAYLIGHT,
203              CameraParameters::WHITE_BALANCE_TWILIGHT);
204     mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
205                     supported_white_balance);
206     mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
207                     CameraParameters::WHITE_BALANCE_AUTO);
208     getCameraDevice()->initializeWhiteBalanceModes(
209             CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f);
210     getCameraDevice()->initializeWhiteBalanceModes(
211             CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f);
212     getCameraDevice()->initializeWhiteBalanceModes(
213             CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f);
214     getCameraDevice()->initializeWhiteBalanceModes(
215             CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f);
216     getCameraDevice()->setWhiteBalanceMode(CameraParameters::WHITE_BALANCE_AUTO);
217 
218     /* Set suported antibanding values */
219     mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
220                     CameraParameters::ANTIBANDING_AUTO);
221     mParameters.set(CameraParameters::KEY_ANTIBANDING,
222                     CameraParameters::ANTIBANDING_AUTO);
223 
224     /* Set control effect mode
225      * Bug: 30862244
226      * */
227     mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS,
228                     CameraParameters::EFFECT_NONE);
229     mParameters.set(CameraParameters::KEY_EFFECT,
230                     CameraParameters::EFFECT_NONE);
231 
232     /* Set focus distances for "near,optimal,far" */
233     mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES,
234                     "Infinity,Infinity,Infinity");
235 
236     /* Not supported features
237      */
238     mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
239                     CameraParameters::FOCUS_MODE_FIXED);
240     mParameters.set(CameraParameters::KEY_FOCUS_MODE,
241                     CameraParameters::FOCUS_MODE_FIXED);
242 
243     return NO_ERROR;
244 }
245 
onNextFrameAvailable(nsecs_t timestamp,EmulatedCameraDevice * camera_dev)246 void EmulatedCamera::onNextFrameAvailable(nsecs_t timestamp,
247                                           EmulatedCameraDevice* camera_dev)
248 {
249     /* Notify the preview window first. */
250     mPreviewWindow.onNextFrameAvailable(timestamp, camera_dev);
251 
252     /* Notify callback notifier next. */
253     mCallbackNotifier.onNextFrameAvailable(timestamp, camera_dev);
254 }
255 
onCameraDeviceError(int err)256 void EmulatedCamera::onCameraDeviceError(int err)
257 {
258     /* Errors are reported through the callback notifier */
259     mCallbackNotifier.onCameraDeviceError(err);
260 }
261 
setTakingPicture(bool takingPicture)262 void EmulatedCamera::setTakingPicture(bool takingPicture) {
263     mCallbackNotifier.setTakingPicture(takingPicture);
264 }
265 /****************************************************************************
266  * Camera API implementation.
267  ***************************************************************************/
268 
connectCamera(hw_device_t ** device)269 status_t EmulatedCamera::connectCamera(hw_device_t** device)
270 {
271     ALOGV("%s", __FUNCTION__);
272 
273     status_t res = EINVAL;
274     EmulatedCameraDevice* const camera_dev = getCameraDevice();
275     ALOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__);
276 
277     if (camera_dev != NULL) {
278         /* Connect to the camera device. */
279         res = getCameraDevice()->connectDevice();
280         if (res == NO_ERROR) {
281             *device = &common;
282         }
283     }
284 
285     return -res;
286 }
287 
closeCamera()288 status_t EmulatedCamera::closeCamera()
289 {
290     ALOGV("%s", __FUNCTION__);
291 
292     return cleanupCamera();
293 }
294 
getCameraInfo(struct camera_info * info)295 status_t EmulatedCamera::getCameraInfo(struct camera_info* info)
296 {
297     ALOGV("%s", __FUNCTION__);
298 
299     const char* valstr = NULL;
300 
301     valstr = mParameters.get(EmulatedCamera::FACING_KEY);
302     if (valstr != NULL) {
303         if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) {
304             info->facing = CAMERA_FACING_FRONT;
305         }
306         else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) {
307             info->facing = CAMERA_FACING_BACK;
308         }
309     } else {
310         info->facing = CAMERA_FACING_BACK;
311     }
312 
313     valstr = mParameters.get(EmulatedCamera::ORIENTATION_KEY);
314     if (valstr != NULL) {
315         info->orientation = atoi(valstr);
316     } else {
317         info->orientation = 0;
318     }
319 
320     return EmulatedBaseCamera::getCameraInfo(info);
321 }
322 
autoFocusComplete()323 void EmulatedCamera::autoFocusComplete() {
324     mCallbackNotifier.autoFocusComplete();
325 }
326 
setPreviewWindow(struct preview_stream_ops * window)327 status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window)
328 {
329     /* Callback should return a negative errno. */
330     return -mPreviewWindow.setPreviewWindow(window,
331                                              mParameters.getPreviewFrameRate());
332 }
333 
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)334 void EmulatedCamera::setCallbacks(camera_notify_callback notify_cb,
335                                   camera_data_callback data_cb,
336                                   camera_data_timestamp_callback data_cb_timestamp,
337                                   camera_request_memory get_memory,
338                                   void* user)
339 {
340     mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp,
341                                     get_memory, user);
342 }
343 
enableMsgType(int32_t msg_type)344 void EmulatedCamera::enableMsgType(int32_t msg_type)
345 {
346     mCallbackNotifier.enableMessage(msg_type);
347 }
348 
disableMsgType(int32_t msg_type)349 void EmulatedCamera::disableMsgType(int32_t msg_type)
350 {
351     mCallbackNotifier.disableMessage(msg_type);
352 }
353 
isMsgTypeEnabled(int32_t msg_type)354 int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type)
355 {
356     return mCallbackNotifier.isMessageEnabled(msg_type);
357 }
358 
startPreview()359 status_t EmulatedCamera::startPreview()
360 {
361     /* Callback should return a negative errno. */
362     return -doStartPreview();
363 }
364 
stopPreview()365 void EmulatedCamera::stopPreview()
366 {
367     /* The camera client will not pass on calls to set the preview window to
368      * NULL if the preview is not enabled. If preview is not enabled the camera
369      * client will instead simply destroy the preview window without notifying
370      * the HAL. Later on when preview is enabled again that means the HAL will
371      * attempt to use the old, destroyed window which will cause a crash.
372      * Instead we need to clear the preview window here, the client will set
373      * a preview window when needed. The preview window is cleared here instead
374      * of inside doStopPreview to prevent the window from being cleared when
375      * restarting the preview because of a parameter change. */
376     mPreviewWindow.setPreviewWindow(nullptr, 0);
377 
378     doStopPreview();
379 }
380 
isPreviewEnabled()381 int EmulatedCamera::isPreviewEnabled()
382 {
383     return mPreviewWindow.isPreviewEnabled();
384 }
385 
storeMetaDataInBuffers(int enable)386 status_t EmulatedCamera::storeMetaDataInBuffers(int enable)
387 {
388     /* Callback should return a negative errno. */
389     return mCallbackNotifier.storeMetaDataInBuffers(enable);
390 }
391 
startRecording()392 status_t EmulatedCamera::startRecording()
393 {
394     /* This callback should return a negative errno, hence all the negations */
395     if (!mPreviewWindow.isPreviewEnabled()) {
396         ALOGE("%s: start recording without preview enabled",
397               __FUNCTION__);
398         return INVALID_OPERATION;
399     }
400     int frameRate = mParameters.getPreviewFrameRate();
401     status_t res = mCallbackNotifier.enableVideoRecording(frameRate);
402     if (res != NO_ERROR) {
403         ALOGE("%s: CallbackNotifier failed to enable video recording",
404               __FUNCTION__);
405         stopRecording();
406         return -res;
407     }
408     EmulatedCameraDevice* const camera_dev = getCameraDevice();
409     if (camera_dev == nullptr || !camera_dev->isStarted()) {
410         // No need for restarts, the next preview start will use correct params
411         return NO_ERROR;
412     }
413 
414     // If the camera is running we might have to restart it to accomodate
415     // whatever pixel format and frame size the caller wants.
416     uint32_t conf_fmt = 0;
417     res = getConfiguredPixelFormat(&conf_fmt);
418     if (res != NO_ERROR) {
419         stopRecording();
420         return -res;
421     }
422     uint32_t cur_fmt = camera_dev->getOriginalPixelFormat();
423     int conf_width = -1, conf_height = -1;
424     res = getConfiguredFrameSize(&conf_width, &conf_height);
425     if (res != NO_ERROR) {
426         stopRecording();
427         return -res;
428     }
429     int cur_width = camera_dev->getFrameWidth();
430     int cur_height = camera_dev->getFrameHeight();
431 
432     if (cur_fmt != conf_fmt ||
433             cur_width != conf_width ||
434             cur_height != conf_height) {
435         // We need to perform a restart to use the new format or size and it
436         // has to be an asynchronous restart or this might block if the camera
437         // thread is currently delivering a frame.
438         if (!camera_dev->requestRestart(conf_width, conf_height, conf_fmt,
439                                         false /* takingPicture */,
440                                         false /* oneBurst */)) {
441             ALOGE("%s: Could not restart preview with new pixel format",
442                   __FUNCTION__);
443             stopRecording();
444             return -EINVAL;
445         }
446     }
447     ALOGD("go all the way to the end");
448     return NO_ERROR;
449 }
450 
stopRecording()451 void EmulatedCamera::stopRecording()
452 {
453     mCallbackNotifier.disableVideoRecording();
454 }
455 
isRecordingEnabled()456 int EmulatedCamera::isRecordingEnabled()
457 {
458     return mCallbackNotifier.isVideoRecordingEnabled();
459 }
460 
releaseRecordingFrame(const void * opaque)461 void EmulatedCamera::releaseRecordingFrame(const void* opaque)
462 {
463     mCallbackNotifier.releaseRecordingFrame(opaque);
464 }
465 
setAutoFocus()466 status_t EmulatedCamera::setAutoFocus()
467 {
468     // Make sure to check that a preview is in progress. Otherwise this will
469     // silently fail because no callback will be called until the preview starts
470     // which might be never.
471     if (!isPreviewEnabled()) {
472         return EINVAL;
473     }
474     EmulatedCameraDevice* const camera_dev = getCameraDevice();
475     if (camera_dev && camera_dev->isStarted()) {
476         return camera_dev->setAutoFocus();
477     }
478     return EINVAL;
479 }
480 
cancelAutoFocus()481 status_t EmulatedCamera::cancelAutoFocus()
482 {
483     // In this case we don't check if a preview is in progress or not. Unlike
484     // setAutoFocus this call will not silently fail without the check. If an
485     // auto-focus request is somehow pending without having preview enabled this
486     // will correctly cancel that pending auto-focus which seems reasonable.
487     EmulatedCameraDevice* const camera_dev = getCameraDevice();
488     if (camera_dev && camera_dev->isStarted()) {
489         return camera_dev->cancelAutoFocus();
490     }
491     return EINVAL;
492 }
493 
takePicture()494 status_t EmulatedCamera::takePicture()
495 {
496     ALOGV("%s", __FUNCTION__);
497 
498     status_t res;
499     int width, height;
500     uint32_t org_fmt;
501 
502     /* Collect frame info for the picture. */
503     mParameters.getPictureSize(&width, &height);
504     const char* pix_fmt = mParameters.getPictureFormat();
505     if (!GetFourCcFormatFromCameraParam(pix_fmt, &org_fmt)) {
506         // Also check for JPEG here, the function above does not do this since
507         // this is very specific to this use case.
508         if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
509             /* We only have JPEG converted for NV21 format. */
510             org_fmt = V4L2_PIX_FMT_NV21;
511         } else {
512             ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
513             return EINVAL;
514         }
515     }
516 
517     /* Get JPEG quality. */
518     int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
519     if (jpeg_quality <= 0) {
520         jpeg_quality = 90;  /* Fall back to default. */
521     }
522 
523     /*
524      * Make sure preview is not running, and device is stopped before taking
525      * picture.
526      */
527 
528     EmulatedCameraDevice* const camera_dev = getCameraDevice();
529     mCallbackNotifier.setJpegQuality(jpeg_quality);
530     mCallbackNotifier.setCameraParameters(mParameters);
531 
532     ALOGD("Starting camera for picture: %.4s(%s)[%dx%d]",
533           reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height);
534     if (mPreviewWindow.isPreviewEnabled()) {
535         mPreviewWindow.stopPreview();
536         /* If the camera preview is enabled we need to perform an asynchronous
537          * restart. A blocking restart could deadlock this thread as it's
538          * currently holding the camera client lock and the frame delivery could
539          * be stuck on waiting for that lock. If this was synchronous then this
540          * thread would in turn get stuck on waiting for the delivery thread. */
541         if (!camera_dev->requestRestart(width, height, org_fmt,
542                                         true /* takingPicture */,
543                                         true /* oneBurst */)) {
544             return UNKNOWN_ERROR;
545         }
546         return NO_ERROR;
547     } else {
548         /* Start camera device for the picture frame. */
549         res = camera_dev->startDevice(width, height, org_fmt);
550         if (res != NO_ERROR) {
551             return res;
552         }
553 
554         /* Deliver one frame only. */
555         mCallbackNotifier.setTakingPicture(true);
556         res = camera_dev->startDeliveringFrames(true);
557         if (res != NO_ERROR) {
558             mCallbackNotifier.setTakingPicture(false);
559         }
560         return res;
561     }
562 }
563 
cancelPicture()564 status_t EmulatedCamera::cancelPicture()
565 {
566     ALOGV("%s", __FUNCTION__);
567 
568     return NO_ERROR;
569 }
570 
setParameters(const char * parms)571 status_t EmulatedCamera::setParameters(const char* parms)
572 {
573     ALOGV("%s", __FUNCTION__);
574     PrintParamDiff(mParameters, parms);
575 
576     CameraParameters new_param;
577     String8 str8_param(parms);
578     new_param.unflatten(str8_param);
579     bool restartPreview = false;
580 
581     /*
582      * Check for new exposure compensation parameter.
583      */
584     int new_exposure_compensation = new_param.getInt(
585             CameraParameters::KEY_EXPOSURE_COMPENSATION);
586     const int min_exposure_compensation = new_param.getInt(
587             CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
588     const int max_exposure_compensation = new_param.getInt(
589             CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);
590 
591     // Checks if the exposure compensation change is supported.
592     if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) {
593         if (new_exposure_compensation > max_exposure_compensation) {
594             new_exposure_compensation = max_exposure_compensation;
595         }
596         if (new_exposure_compensation < min_exposure_compensation) {
597             new_exposure_compensation = min_exposure_compensation;
598         }
599 
600         const int current_exposure_compensation = mParameters.getInt(
601                 CameraParameters::KEY_EXPOSURE_COMPENSATION);
602         if (current_exposure_compensation != new_exposure_compensation) {
603             const float exposure_value = new_exposure_compensation *
604                     new_param.getFloat(
605                             CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP);
606 
607             getCameraDevice()->setExposureCompensation(
608                     exposure_value);
609         }
610     }
611 
612     const char* new_white_balance = new_param.get(
613             CameraParameters::KEY_WHITE_BALANCE);
614     const char* supported_white_balance = new_param.get(
615             CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);
616 
617     if ((supported_white_balance != NULL) && (new_white_balance != NULL) &&
618         (strstr(supported_white_balance, new_white_balance) != NULL)) {
619 
620         const char* current_white_balance = mParameters.get(
621                 CameraParameters::KEY_WHITE_BALANCE);
622         if ((current_white_balance == NULL) ||
623             (strcmp(current_white_balance, new_white_balance) != 0)) {
624             ALOGV("Setting white balance to %s", new_white_balance);
625             getCameraDevice()->setWhiteBalanceMode(new_white_balance);
626         }
627     }
628     int old_frame_rate = mParameters.getPreviewFrameRate();
629     int new_frame_rate = new_param.getPreviewFrameRate();
630     if (old_frame_rate != new_frame_rate) {
631         getCameraDevice()->setPreviewFrameRate(new_frame_rate);
632     }
633 
634     // Validate focus mode
635     const char* focus_mode = new_param.get(CameraParameters::KEY_FOCUS_MODE);
636     if (focus_mode && !IsValueInList(focus_mode, kValidFocusModes)) {
637         return BAD_VALUE;
638     }
639 
640     // Validate preview size, if there is no preview size the initial values of
641     // the integers below will be preserved thus intentionally failing the test
642     int new_preview_width = -1, new_preview_height = -1;
643     new_param.getPreviewSize(&new_preview_width, &new_preview_height);
644     if (new_preview_width < 0 || new_preview_height < 0) {
645         return BAD_VALUE;
646     }
647     // If the preview size has changed we have to restart the preview to make
648     // sure we provide frames of the correct size. The receiver assumes the
649     // frame size is correct and will copy all data provided into a buffer whose
650     // size is determined by the preview size without checks, potentially
651     // causing buffer overruns or underruns if there is a size mismatch.
652     int old_preview_width = -1, old_preview_height = -1;
653     mParameters.getPreviewSize(&old_preview_width, &old_preview_height);
654     if (old_preview_width != new_preview_width ||
655             old_preview_height != new_preview_height) {
656         restartPreview = true;
657     }
658 
659     // For the same reasons as with the preview size we have to look for changes
660     // in video size and restart the preview if the size has changed.
661     int old_video_width = -1, old_video_height = -1;
662     int new_video_width = -1, new_video_height = -1;
663     mParameters.getVideoSize(&old_video_width, &old_video_height);
664     new_param.getVideoSize(&new_video_width, &new_video_height);
665     if (old_video_width != new_video_width ||
666         old_video_height != new_video_height) {
667         restartPreview = true;
668     }
669     // Restart the preview if the pixel format changes to make sure we serve
670     // the selected encoding to the client.
671     const char* old_format = mParameters.getPreviewFormat();
672     const char* new_format = new_param.getPreviewFormat();
673     if (!StringsEqual(old_format, new_format)) {
674         restartPreview = true;
675     }
676 
677     const char* old_hint =
678         mParameters.get(CameraParameters::KEY_RECORDING_HINT);
679     const char* new_hint = new_param.get(CameraParameters::KEY_RECORDING_HINT);
680     if (!StringsEqual(old_hint, new_hint)) {
681         // The recording hint changed, this indicates we transitioned from
682         // recording to non-recording or the other way around. We need to look
683         // at a new pixel format for this and that requires a restart.
684         restartPreview = true;
685     }
686 
687     mParameters = new_param;
688 
689     // Now that the parameters have been assigned check if the preview needs to
690     // be restarted. If necessary this will then use the new parameters to set
691     // up the preview as requested by the caller.
692     if (restartPreview && isPreviewEnabled()) {
693         status_t status = doStopPreview();
694         if (status != NO_ERROR) {
695             ALOGE("%s: Stopping preview failed: %d", __FUNCTION__, status);
696             return status;
697         }
698         status = doStartPreview();
699         if (status != NO_ERROR) {
700             ALOGE("%s: Starting preview failed: %d", __FUNCTION__, status);
701             return status;
702         }
703     }
704     return NO_ERROR;
705 }
706 
707 /* A dumb variable indicating "no params" / error on the exit from
708  * EmulatedCamera::getParameters(). */
709 static char lNoParam = '\0';
getParameters()710 char* EmulatedCamera::getParameters()
711 {
712     // Read the image size and set the camera's Field of View.
713     // These values are valid for a Logitech B910 HD Webcam.
714     int width=0, height=0;
715     mParameters.getPictureSize(&width, &height);
716     if (height > 0) {
717         if (((double)width / height) < 1.55) {
718             // Closer to 4:3 (1.33), set the FOV to 61.0 degrees
719             mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "61.0");
720         } else {
721             // Closer to 16:9 (1.77), set the FOV to 70.0 degrees
722             mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "70.0");
723         }
724     }
725 
726     String8 params(mParameters.flatten());
727     char* ret_str =
728         reinterpret_cast<char*>(malloc(sizeof(char) * (params.length()+1)));
729     memset(ret_str, 0, params.length()+1);
730     if (ret_str != NULL) {
731         strncpy(ret_str, params.string(), params.length()+1);
732         return ret_str;
733     } else {
734         ALOGE("%s: Unable to allocate string for %s", __FUNCTION__, params.string());
735         /* Apparently, we can't return NULL fron this routine. */
736         return &lNoParam;
737     }
738 }
739 
putParameters(char * params)740 void EmulatedCamera::putParameters(char* params)
741 {
742     /* This method simply frees parameters allocated in getParameters(). */
743     if (params != NULL && params != &lNoParam) {
744         free(params);
745     }
746 }
747 
sendCommand(int32_t cmd,int32_t arg1,int32_t arg2)748 status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
749 {
750     ALOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2);
751 
752     switch (cmd) {
753         case CAMERA_CMD_START_FACE_DETECTION:
754         case CAMERA_CMD_STOP_FACE_DETECTION:
755             // We do not support hardware face detection so we need to indicate
756             // that any attempt to start/stop face detection is invalid
757             return BAD_VALUE;
758     }
759     /* TODO: Future enhancements. */
760     return 0;
761 }
762 
releaseCamera()763 void EmulatedCamera::releaseCamera()
764 {
765     ALOGV("%s", __FUNCTION__);
766 
767     cleanupCamera();
768 }
769 
dumpCamera(int fd)770 status_t EmulatedCamera::dumpCamera(int fd)
771 {
772     ALOGV("%s", __FUNCTION__);
773 
774     /* TODO: Future enhancements. */
775     dprintf(fd, "dump camera unimplemented\n");
776     return 0;
777 }
778 
getConfiguredPixelFormat(uint32_t * pixelFormat) const779 status_t EmulatedCamera::getConfiguredPixelFormat(uint32_t* pixelFormat) const {
780     const char* pix_fmt = nullptr;
781     const char* recordingHint =
782         mParameters.get(CameraParameters::KEY_RECORDING_HINT);
783     bool recordingHintOn = recordingHint && strcmp(recordingHint,
784                                                    CameraParameters::TRUE) == 0;
785     bool recordingEnabled = mCallbackNotifier.isVideoRecordingEnabled();
786     if (recordingHintOn || recordingEnabled) {
787         // We're recording a video, use the video pixel format
788         pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
789     }
790     if (pix_fmt == nullptr) {
791         pix_fmt = mParameters.getPreviewFormat();
792     }
793     if (pix_fmt == nullptr) {
794         ALOGE("%s: Unable to obtain configured pixel format", __FUNCTION__);
795         return EINVAL;
796     }
797     /* Convert framework's pixel format to the FOURCC one. */
798     if (!GetFourCcFormatFromCameraParam(pix_fmt, pixelFormat)) {
799         ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
800         return EINVAL;
801     }
802     return NO_ERROR;
803 }
804 
getConfiguredFrameSize(int * outWidth,int * outHeight) const805 status_t EmulatedCamera::getConfiguredFrameSize(int* outWidth,
806                                                 int* outHeight) const {
807     int width = -1, height = -1;
808     if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != nullptr) {
809         mParameters.getVideoSize(&width, &height);
810     } else {
811         mParameters.getPreviewSize(&width, &height);
812     }
813     if (width < 0 || height < 0) {
814         ALOGE("%s: No frame size configured for camera", __FUNCTION__);
815         return EINVAL;
816     }
817     // Only modify the out parameters once we know we succeeded
818     *outWidth = width;
819     *outHeight = height;
820     return NO_ERROR;
821 }
822 
823 /****************************************************************************
824  * Preview management.
825  ***************************************************************************/
826 
doStartPreview()827 status_t EmulatedCamera::doStartPreview()
828 {
829     ALOGV("%s", __FUNCTION__);
830 
831     EmulatedCameraDevice* camera_dev = getCameraDevice();
832     if (camera_dev->isStarted()) {
833         camera_dev->stopDeliveringFrames();
834         camera_dev->stopDevice();
835     }
836 
837     status_t res = mPreviewWindow.startPreview();
838     if (res != NO_ERROR) {
839         return res;
840     }
841 
842     /* Make sure camera device is connected. */
843     if (!camera_dev->isConnected()) {
844         res = camera_dev->connectDevice();
845         if (res != NO_ERROR) {
846             mPreviewWindow.stopPreview();
847             return res;
848         }
849     }
850 
851     /* Lets see what should we use for frame width, and height. */
852     int width, height;
853     res = getConfiguredFrameSize(&width, &height);
854     if (res != NO_ERROR) {
855         mPreviewWindow.stopPreview();
856         return res;
857     }
858 
859     uint32_t org_fmt = 0;
860     res = getConfiguredPixelFormat(&org_fmt);
861     if (res != NO_ERROR) {
862         mPreviewWindow.stopPreview();
863         return res;
864     }
865 
866     camera_dev->setPreviewFrameRate(mParameters.getPreviewFrameRate());
867     ALOGD("Starting camera: %dx%d -> %.4s",
868          width, height, reinterpret_cast<const char*>(&org_fmt));
869     res = camera_dev->startDevice(width, height, org_fmt);
870     if (res != NO_ERROR) {
871         mPreviewWindow.stopPreview();
872         return res;
873     }
874 
875     res = camera_dev->startDeliveringFrames(false);
876     if (res != NO_ERROR) {
877         camera_dev->stopDevice();
878         mPreviewWindow.stopPreview();
879     }
880 
881     return res;
882 }
883 
doStopPreview()884 status_t EmulatedCamera::doStopPreview()
885 {
886     ALOGV("%s", __FUNCTION__);
887 
888     status_t res = NO_ERROR;
889     if (mPreviewWindow.isPreviewEnabled()) {
890         /* Stop the camera. */
891         if (getCameraDevice()->isStarted()) {
892             getCameraDevice()->stopDeliveringFrames();
893             res = getCameraDevice()->stopDevice();
894         }
895 
896         if (res == NO_ERROR) {
897             /* Disable preview as well. */
898             mPreviewWindow.stopPreview();
899         }
900     }
901 
902     return NO_ERROR;
903 }
904 
905 /****************************************************************************
906  * Private API.
907  ***************************************************************************/
908 
cleanupCamera()909 status_t EmulatedCamera::cleanupCamera()
910 {
911     status_t res = NO_ERROR;
912 
913     /* If preview is running - stop it. */
914     res = doStopPreview();
915     if (res != NO_ERROR) {
916         return -res;
917     }
918 
919     /* Stop and disconnect the camera device. */
920     EmulatedCameraDevice* const camera_dev = getCameraDevice();
921     if (camera_dev != NULL) {
922         if (camera_dev->isStarted()) {
923             camera_dev->stopDeliveringFrames();
924             res = camera_dev->stopDevice();
925             if (res != NO_ERROR) {
926                 return -res;
927             }
928         }
929         if (camera_dev->isConnected()) {
930             res = camera_dev->disconnectDevice();
931             if (res != NO_ERROR) {
932                 return -res;
933             }
934         }
935     }
936 
937     mCallbackNotifier.cleanupCBNotifier();
938 
939     /* Re-init the camera settings in case settings were changed */
940     Initialize();
941 
942     return NO_ERROR;
943 }
944 
945 /****************************************************************************
946  * Camera API callbacks as defined by camera_device_ops structure.
947  *
948  * Callbacks here simply dispatch the calls to an appropriate method inside
949  * EmulatedCamera instance, defined by the 'dev' parameter.
950  ***************************************************************************/
951 
set_preview_window(struct camera_device * dev,struct preview_stream_ops * window)952 int EmulatedCamera::set_preview_window(struct camera_device* dev,
953                                        struct preview_stream_ops* window)
954 {
955     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
956     if (ec == NULL) {
957         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
958         return -EINVAL;
959     }
960     return ec->setPreviewWindow(window);
961 }
962 
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)963 void EmulatedCamera::set_callbacks(
964         struct camera_device* dev,
965         camera_notify_callback notify_cb,
966         camera_data_callback data_cb,
967         camera_data_timestamp_callback data_cb_timestamp,
968         camera_request_memory get_memory,
969         void* user)
970 {
971     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
972     if (ec == NULL) {
973         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
974         return;
975     }
976     ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
977 }
978 
enable_msg_type(struct camera_device * dev,int32_t msg_type)979 void EmulatedCamera::enable_msg_type(struct camera_device* dev, int32_t msg_type)
980 {
981     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
982     if (ec == NULL) {
983         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
984         return;
985     }
986     ec->enableMsgType(msg_type);
987 }
988 
disable_msg_type(struct camera_device * dev,int32_t msg_type)989 void EmulatedCamera::disable_msg_type(struct camera_device* dev, int32_t msg_type)
990 {
991     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
992     if (ec == NULL) {
993         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
994         return;
995     }
996     ec->disableMsgType(msg_type);
997 }
998 
msg_type_enabled(struct camera_device * dev,int32_t msg_type)999 int EmulatedCamera::msg_type_enabled(struct camera_device* dev, int32_t msg_type)
1000 {
1001     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1002     if (ec == NULL) {
1003         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1004         return -EINVAL;
1005     }
1006     return ec->isMsgTypeEnabled(msg_type);
1007 }
1008 
start_preview(struct camera_device * dev)1009 int EmulatedCamera::start_preview(struct camera_device* dev)
1010 {
1011     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1012     if (ec == NULL) {
1013         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1014         return -EINVAL;
1015     }
1016     return ec->startPreview();
1017 }
1018 
stop_preview(struct camera_device * dev)1019 void EmulatedCamera::stop_preview(struct camera_device* dev)
1020 {
1021     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1022     if (ec == NULL) {
1023         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1024         return;
1025     }
1026     ec->stopPreview();
1027 }
1028 
preview_enabled(struct camera_device * dev)1029 int EmulatedCamera::preview_enabled(struct camera_device* dev)
1030 {
1031     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1032     if (ec == NULL) {
1033         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1034         return -EINVAL;
1035     }
1036     return ec->isPreviewEnabled();
1037 }
1038 
store_meta_data_in_buffers(struct camera_device * dev,int enable)1039 int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev,
1040                                                int enable)
1041 {
1042     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1043     if (ec == NULL) {
1044         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1045         return -EINVAL;
1046     }
1047     return ec->storeMetaDataInBuffers(enable);
1048 }
1049 
start_recording(struct camera_device * dev)1050 int EmulatedCamera::start_recording(struct camera_device* dev)
1051 {
1052     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1053     if (ec == NULL) {
1054         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1055         return -EINVAL;
1056     }
1057     return ec->startRecording();
1058 }
1059 
stop_recording(struct camera_device * dev)1060 void EmulatedCamera::stop_recording(struct camera_device* dev)
1061 {
1062     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1063     if (ec == NULL) {
1064         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1065         return;
1066     }
1067     ec->stopRecording();
1068 }
1069 
recording_enabled(struct camera_device * dev)1070 int EmulatedCamera::recording_enabled(struct camera_device* dev)
1071 {
1072     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1073     if (ec == NULL) {
1074         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1075         return -EINVAL;
1076     }
1077     return ec->isRecordingEnabled();
1078 }
1079 
release_recording_frame(struct camera_device * dev,const void * opaque)1080 void EmulatedCamera::release_recording_frame(struct camera_device* dev,
1081                                              const void* opaque)
1082 {
1083     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1084     if (ec == NULL) {
1085         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1086         return;
1087     }
1088     ec->releaseRecordingFrame(opaque);
1089 }
1090 
auto_focus(struct camera_device * dev)1091 int EmulatedCamera::auto_focus(struct camera_device* dev)
1092 {
1093     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1094     if (ec == NULL) {
1095         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1096         return -EINVAL;
1097     }
1098     return ec->setAutoFocus();
1099 }
1100 
cancel_auto_focus(struct camera_device * dev)1101 int EmulatedCamera::cancel_auto_focus(struct camera_device* dev)
1102 {
1103     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1104     if (ec == NULL) {
1105         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1106         return -EINVAL;
1107     }
1108     return ec->cancelAutoFocus();
1109 }
1110 
take_picture(struct camera_device * dev)1111 int EmulatedCamera::take_picture(struct camera_device* dev)
1112 {
1113     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1114     if (ec == NULL) {
1115         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1116         return -EINVAL;
1117     }
1118     return ec->takePicture();
1119 }
1120 
cancel_picture(struct camera_device * dev)1121 int EmulatedCamera::cancel_picture(struct camera_device* dev)
1122 {
1123     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1124     if (ec == NULL) {
1125         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1126         return -EINVAL;
1127     }
1128     return ec->cancelPicture();
1129 }
1130 
set_parameters(struct camera_device * dev,const char * parms)1131 int EmulatedCamera::set_parameters(struct camera_device* dev, const char* parms)
1132 {
1133     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1134     if (ec == NULL) {
1135         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1136         return -EINVAL;
1137     }
1138     return ec->setParameters(parms);
1139 }
1140 
get_parameters(struct camera_device * dev)1141 char* EmulatedCamera::get_parameters(struct camera_device* dev)
1142 {
1143     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1144     if (ec == NULL) {
1145         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1146         return NULL;
1147     }
1148     return ec->getParameters();
1149 }
1150 
put_parameters(struct camera_device * dev,char * params)1151 void EmulatedCamera::put_parameters(struct camera_device* dev, char* params)
1152 {
1153     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1154     if (ec == NULL) {
1155         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1156         return;
1157     }
1158     ec->putParameters(params);
1159 }
1160 
send_command(struct camera_device * dev,int32_t cmd,int32_t arg1,int32_t arg2)1161 int EmulatedCamera::send_command(struct camera_device* dev,
1162                                  int32_t cmd,
1163                                  int32_t arg1,
1164                                  int32_t arg2)
1165 {
1166     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1167     if (ec == NULL) {
1168         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1169         return -EINVAL;
1170     }
1171     return ec->sendCommand(cmd, arg1, arg2);
1172 }
1173 
release(struct camera_device * dev)1174 void EmulatedCamera::release(struct camera_device* dev)
1175 {
1176     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1177     if (ec == NULL) {
1178         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1179         return;
1180     }
1181     ec->releaseCamera();
1182 }
1183 
dump(struct camera_device * dev,int fd)1184 int EmulatedCamera::dump(struct camera_device* dev, int fd)
1185 {
1186     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1187     if (ec == NULL) {
1188         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1189         return -EINVAL;
1190     }
1191     return ec->dumpCamera(fd);
1192 }
1193 
close(struct hw_device_t * device)1194 int EmulatedCamera::close(struct hw_device_t* device)
1195 {
1196     EmulatedCamera* ec =
1197         reinterpret_cast<EmulatedCamera*>(reinterpret_cast<struct camera_device*>(device)->priv);
1198     if (ec == NULL) {
1199         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1200         return -EINVAL;
1201     }
1202     return ec->closeCamera();
1203 }
1204 
1205 /****************************************************************************
1206  * Static initializer for the camera callback API
1207  ****************************************************************************/
1208 
1209 camera_device_ops_t EmulatedCamera::mDeviceOps = {
1210     EmulatedCamera::set_preview_window,
1211     EmulatedCamera::set_callbacks,
1212     EmulatedCamera::enable_msg_type,
1213     EmulatedCamera::disable_msg_type,
1214     EmulatedCamera::msg_type_enabled,
1215     EmulatedCamera::start_preview,
1216     EmulatedCamera::stop_preview,
1217     EmulatedCamera::preview_enabled,
1218     EmulatedCamera::store_meta_data_in_buffers,
1219     EmulatedCamera::start_recording,
1220     EmulatedCamera::stop_recording,
1221     EmulatedCamera::recording_enabled,
1222     EmulatedCamera::release_recording_frame,
1223     EmulatedCamera::auto_focus,
1224     EmulatedCamera::cancel_auto_focus,
1225     EmulatedCamera::take_picture,
1226     EmulatedCamera::cancel_picture,
1227     EmulatedCamera::set_parameters,
1228     EmulatedCamera::get_parameters,
1229     EmulatedCamera::put_parameters,
1230     EmulatedCamera::send_command,
1231     EmulatedCamera::release,
1232     EmulatedCamera::dump
1233 };
1234 
1235 /****************************************************************************
1236  * Common keys
1237  ***************************************************************************/
1238 
1239 const char EmulatedCamera::FACING_KEY[]         = "prop-facing";
1240 const char EmulatedCamera::ORIENTATION_KEY[]    = "prop-orientation";
1241 const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint";
1242 
1243 /****************************************************************************
1244  * Common string values
1245  ***************************************************************************/
1246 
1247 const char EmulatedCamera::FACING_BACK[]      = "back";
1248 const char EmulatedCamera::FACING_FRONT[]     = "front";
1249 
1250 /****************************************************************************
1251  * Helper routines
1252  ***************************************************************************/
1253 
AddValue(const char * param,const char * val)1254 static char* AddValue(const char* param, const char* val)
1255 {
1256     const size_t len1 = strlen(param);
1257     const size_t len2 = strlen(val);
1258     char* ret = reinterpret_cast<char*>(malloc(len1 + len2 + 2));
1259     ALOGE_IF(ret == NULL, "%s: Memory failure", __FUNCTION__);
1260     if (ret != NULL) {
1261         memcpy(ret, param, len1);
1262         ret[len1] = ',';
1263         memcpy(ret + len1 + 1, val, len2);
1264         ret[len1 + len2 + 1] = '\0';
1265     }
1266     return ret;
1267 }
1268 
1269 /****************************************************************************
1270  * Parameter debugging helpers
1271  ***************************************************************************/
1272 
1273 #if DEBUG_PARAM
PrintParamDiff(const CameraParameters & current,const char * new_par)1274 static void PrintParamDiff(const CameraParameters& current,
1275                             const char* new_par)
1276 {
1277     char tmp[2048];
1278     const char* wrk = new_par;
1279 
1280     /* Divided with ';' */
1281     const char* next = strchr(wrk, ';');
1282     while (next != NULL) {
1283         snprintf(tmp, sizeof(tmp), "%.*s", (int)(intptr_t)(next-wrk), wrk);
1284         /* in the form key=value */
1285         char* val = strchr(tmp, '=');
1286         if (val != NULL) {
1287             *val = '\0'; val++;
1288             const char* in_current = current.get(tmp);
1289             if (in_current != NULL) {
1290                 if (strcmp(in_current, val)) {
1291                     ALOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val);
1292                 }
1293             } else {
1294                 ALOGD("+++ New parameter: %s=%s", tmp, val);
1295             }
1296         } else {
1297             ALOGW("No value separator in %s", tmp);
1298         }
1299         wrk = next + 1;
1300         next = strchr(wrk, ';');
1301     }
1302 }
1303 #endif  /* DEBUG_PARAM */
1304 
1305 }; /* namespace android */
1306