• 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 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     int frameRate = mParameters.getPreviewFrameRate();
396     status_t res = mCallbackNotifier.enableVideoRecording(frameRate);
397     if (res != NO_ERROR) {
398         ALOGE("%s: CallbackNotifier failed to enable video recording",
399               __FUNCTION__);
400         stopRecording();
401         return -res;
402     }
403     EmulatedCameraDevice* const camera_dev = getCameraDevice();
404     if (camera_dev == nullptr || !camera_dev->isStarted()) {
405         // No need for restarts, the next preview start will use correct params
406         return NO_ERROR;
407     }
408 
409     // If the camera is running we might have to restart it to accomodate
410     // whatever pixel format and frame size the caller wants.
411     uint32_t conf_fmt = 0;
412     res = getConfiguredPixelFormat(&conf_fmt);
413     if (res != NO_ERROR) {
414         stopRecording();
415         return -res;
416     }
417     uint32_t cur_fmt = camera_dev->getOriginalPixelFormat();
418     int conf_width = -1, conf_height = -1;
419     res = getConfiguredFrameSize(&conf_width, &conf_height);
420     if (res != NO_ERROR) {
421         stopRecording();
422         return -res;
423     }
424     int cur_width = camera_dev->getFrameWidth();
425     int cur_height = camera_dev->getFrameHeight();
426 
427     if (cur_fmt != conf_fmt ||
428             cur_width != conf_width ||
429             cur_height != conf_height) {
430         // We need to perform a restart to use the new format or size and it
431         // has to be an asynchronous restart or this might block if the camera
432         // thread is currently delivering a frame.
433         if (!camera_dev->requestRestart(conf_width, conf_height, conf_fmt,
434                                         false /* takingPicture */,
435                                         false /* oneBurst */)) {
436             ALOGE("%s: Could not restart preview with new pixel format",
437                   __FUNCTION__);
438             stopRecording();
439             return -EINVAL;
440         }
441     }
442     return NO_ERROR;
443 }
444 
stopRecording()445 void EmulatedCamera::stopRecording()
446 {
447     mCallbackNotifier.disableVideoRecording();
448 }
449 
isRecordingEnabled()450 int EmulatedCamera::isRecordingEnabled()
451 {
452     return mCallbackNotifier.isVideoRecordingEnabled();
453 }
454 
releaseRecordingFrame(const void * opaque)455 void EmulatedCamera::releaseRecordingFrame(const void* opaque)
456 {
457     mCallbackNotifier.releaseRecordingFrame(opaque);
458 }
459 
setAutoFocus()460 status_t EmulatedCamera::setAutoFocus()
461 {
462     // Make sure to check that a preview is in progress. Otherwise this will
463     // silently fail because no callback will be called until the preview starts
464     // which might be never.
465     if (!isPreviewEnabled()) {
466         return EINVAL;
467     }
468     EmulatedCameraDevice* const camera_dev = getCameraDevice();
469     if (camera_dev && camera_dev->isStarted()) {
470         return camera_dev->setAutoFocus();
471     }
472     return EINVAL;
473 }
474 
cancelAutoFocus()475 status_t EmulatedCamera::cancelAutoFocus()
476 {
477     // In this case we don't check if a preview is in progress or not. Unlike
478     // setAutoFocus this call will not silently fail without the check. If an
479     // auto-focus request is somehow pending without having preview enabled this
480     // will correctly cancel that pending auto-focus which seems reasonable.
481     EmulatedCameraDevice* const camera_dev = getCameraDevice();
482     if (camera_dev && camera_dev->isStarted()) {
483         return camera_dev->cancelAutoFocus();
484     }
485     return EINVAL;
486 }
487 
takePicture()488 status_t EmulatedCamera::takePicture()
489 {
490     ALOGV("%s", __FUNCTION__);
491 
492     status_t res;
493     int width, height;
494     uint32_t org_fmt;
495 
496     /* Collect frame info for the picture. */
497     mParameters.getPictureSize(&width, &height);
498     const char* pix_fmt = mParameters.getPictureFormat();
499     if (!GetFourCcFormatFromCameraParam(pix_fmt, &org_fmt)) {
500         // Also check for JPEG here, the function above does not do this since
501         // this is very specific to this use case.
502         if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
503             /* We only have JPEG converted for NV21 format. */
504             org_fmt = V4L2_PIX_FMT_NV21;
505         } else {
506             ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
507             return EINVAL;
508         }
509     }
510 
511     /* Get JPEG quality. */
512     int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
513     if (jpeg_quality <= 0) {
514         jpeg_quality = 90;  /* Fall back to default. */
515     }
516 
517     /*
518      * Make sure preview is not running, and device is stopped before taking
519      * picture.
520      */
521 
522     EmulatedCameraDevice* const camera_dev = getCameraDevice();
523     mCallbackNotifier.setJpegQuality(jpeg_quality);
524     mCallbackNotifier.setCameraParameters(mParameters);
525 
526     ALOGD("Starting camera for picture: %.4s(%s)[%dx%d]",
527           reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height);
528     if (mPreviewWindow.isPreviewEnabled()) {
529         mPreviewWindow.stopPreview();
530         /* If the camera preview is enabled we need to perform an asynchronous
531          * restart. A blocking restart could deadlock this thread as it's
532          * currently holding the camera client lock and the frame delivery could
533          * be stuck on waiting for that lock. If this was synchronous then this
534          * thread would in turn get stuck on waiting for the delivery thread. */
535         if (!camera_dev->requestRestart(width, height, org_fmt,
536                                         true /* takingPicture */,
537                                         true /* oneBurst */)) {
538             return UNKNOWN_ERROR;
539         }
540         return NO_ERROR;
541     } else {
542         /* Start camera device for the picture frame. */
543         res = camera_dev->startDevice(width, height, org_fmt);
544         if (res != NO_ERROR) {
545             return res;
546         }
547 
548         /* Deliver one frame only. */
549         mCallbackNotifier.setTakingPicture(true);
550         res = camera_dev->startDeliveringFrames(true);
551         if (res != NO_ERROR) {
552             mCallbackNotifier.setTakingPicture(false);
553         }
554         return res;
555     }
556 }
557 
cancelPicture()558 status_t EmulatedCamera::cancelPicture()
559 {
560     ALOGV("%s", __FUNCTION__);
561 
562     return NO_ERROR;
563 }
564 
setParameters(const char * parms)565 status_t EmulatedCamera::setParameters(const char* parms)
566 {
567     ALOGV("%s", __FUNCTION__);
568     PrintParamDiff(mParameters, parms);
569 
570     CameraParameters new_param;
571     String8 str8_param(parms);
572     new_param.unflatten(str8_param);
573     bool restartPreview = false;
574 
575     /*
576      * Check for new exposure compensation parameter.
577      */
578     int new_exposure_compensation = new_param.getInt(
579             CameraParameters::KEY_EXPOSURE_COMPENSATION);
580     const int min_exposure_compensation = new_param.getInt(
581             CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
582     const int max_exposure_compensation = new_param.getInt(
583             CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);
584 
585     // Checks if the exposure compensation change is supported.
586     if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) {
587         if (new_exposure_compensation > max_exposure_compensation) {
588             new_exposure_compensation = max_exposure_compensation;
589         }
590         if (new_exposure_compensation < min_exposure_compensation) {
591             new_exposure_compensation = min_exposure_compensation;
592         }
593 
594         const int current_exposure_compensation = mParameters.getInt(
595                 CameraParameters::KEY_EXPOSURE_COMPENSATION);
596         if (current_exposure_compensation != new_exposure_compensation) {
597             const float exposure_value = new_exposure_compensation *
598                     new_param.getFloat(
599                             CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP);
600 
601             getCameraDevice()->setExposureCompensation(
602                     exposure_value);
603         }
604     }
605 
606     const char* new_white_balance = new_param.get(
607             CameraParameters::KEY_WHITE_BALANCE);
608     const char* supported_white_balance = new_param.get(
609             CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);
610 
611     if ((supported_white_balance != NULL) && (new_white_balance != NULL) &&
612         (strstr(supported_white_balance, new_white_balance) != NULL)) {
613 
614         const char* current_white_balance = mParameters.get(
615                 CameraParameters::KEY_WHITE_BALANCE);
616         if ((current_white_balance == NULL) ||
617             (strcmp(current_white_balance, new_white_balance) != 0)) {
618             ALOGV("Setting white balance to %s", new_white_balance);
619             getCameraDevice()->setWhiteBalanceMode(new_white_balance);
620         }
621     }
622     int old_frame_rate = mParameters.getPreviewFrameRate();
623     int new_frame_rate = new_param.getPreviewFrameRate();
624     if (old_frame_rate != new_frame_rate) {
625         getCameraDevice()->setPreviewFrameRate(new_frame_rate);
626     }
627 
628     // Validate focus mode
629     const char* focus_mode = new_param.get(CameraParameters::KEY_FOCUS_MODE);
630     if (focus_mode && !IsValueInList(focus_mode, kValidFocusModes)) {
631         return BAD_VALUE;
632     }
633 
634     // Validate preview size, if there is no preview size the initial values of
635     // the integers below will be preserved thus intentionally failing the test
636     int new_preview_width = -1, new_preview_height = -1;
637     new_param.getPreviewSize(&new_preview_width, &new_preview_height);
638     if (new_preview_width < 0 || new_preview_height < 0) {
639         return BAD_VALUE;
640     }
641     // If the preview size has changed we have to restart the preview to make
642     // sure we provide frames of the correct size. The receiver assumes the
643     // frame size is correct and will copy all data provided into a buffer whose
644     // size is determined by the preview size without checks, potentially
645     // causing buffer overruns or underruns if there is a size mismatch.
646     int old_preview_width = -1, old_preview_height = -1;
647     mParameters.getPreviewSize(&old_preview_width, &old_preview_height);
648     if (old_preview_width != new_preview_width ||
649             old_preview_height != new_preview_height) {
650         restartPreview = true;
651     }
652 
653     // For the same reasons as with the preview size we have to look for changes
654     // in video size and restart the preview if the size has changed.
655     int old_video_width = -1, old_video_height = -1;
656     int new_video_width = -1, new_video_height = -1;
657     mParameters.getVideoSize(&old_video_width, &old_video_height);
658     new_param.getVideoSize(&new_video_width, &new_video_height);
659     if (old_video_width != new_video_width ||
660         old_video_height != new_video_height) {
661         restartPreview = true;
662     }
663     // Restart the preview if the pixel format changes to make sure we serve
664     // the selected encoding to the client.
665     const char* old_format = mParameters.getPreviewFormat();
666     const char* new_format = new_param.getPreviewFormat();
667     if (!StringsEqual(old_format, new_format)) {
668         restartPreview = true;
669     }
670 
671     const char* old_hint =
672         mParameters.get(CameraParameters::KEY_RECORDING_HINT);
673     const char* new_hint = new_param.get(CameraParameters::KEY_RECORDING_HINT);
674     if (!StringsEqual(old_hint, new_hint)) {
675         // The recording hint changed, this indicates we transitioned from
676         // recording to non-recording or the other way around. We need to look
677         // at a new pixel format for this and that requires a restart.
678         restartPreview = true;
679     }
680 
681     mParameters = new_param;
682 
683     // Now that the parameters have been assigned check if the preview needs to
684     // be restarted. If necessary this will then use the new parameters to set
685     // up the preview as requested by the caller.
686     if (restartPreview && isPreviewEnabled()) {
687         status_t status = doStopPreview();
688         if (status != NO_ERROR) {
689             ALOGE("%s: Stopping preview failed: %d", __FUNCTION__, status);
690             return status;
691         }
692         status = doStartPreview();
693         if (status != NO_ERROR) {
694             ALOGE("%s: Starting preview failed: %d", __FUNCTION__, status);
695             return status;
696         }
697     }
698     return NO_ERROR;
699 }
700 
701 /* A dumb variable indicating "no params" / error on the exit from
702  * EmulatedCamera::getParameters(). */
703 static char lNoParam = '\0';
getParameters()704 char* EmulatedCamera::getParameters()
705 {
706     // Read the image size and set the camera's Field of View.
707     // These values are valid for a Logitech B910 HD Webcam.
708     int width=0, height=0;
709     mParameters.getPictureSize(&width, &height);
710     if (height > 0) {
711         if (((double)width / height) < 1.55) {
712             // Closer to 4:3 (1.33), set the FOV to 61.0 degrees
713             mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "61.0");
714         } else {
715             // Closer to 16:9 (1.77), set the FOV to 70.0 degrees
716             mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "70.0");
717         }
718     }
719 
720     String8 params(mParameters.flatten());
721     char* ret_str =
722         reinterpret_cast<char*>(malloc(sizeof(char) * (params.length()+1)));
723     memset(ret_str, 0, params.length()+1);
724     if (ret_str != NULL) {
725         strncpy(ret_str, params.string(), params.length()+1);
726         return ret_str;
727     } else {
728         ALOGE("%s: Unable to allocate string for %s", __FUNCTION__, params.string());
729         /* Apparently, we can't return NULL fron this routine. */
730         return &lNoParam;
731     }
732 }
733 
putParameters(char * params)734 void EmulatedCamera::putParameters(char* params)
735 {
736     /* This method simply frees parameters allocated in getParameters(). */
737     if (params != NULL && params != &lNoParam) {
738         free(params);
739     }
740 }
741 
sendCommand(int32_t cmd,int32_t arg1,int32_t arg2)742 status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
743 {
744     ALOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2);
745 
746     switch (cmd) {
747         case CAMERA_CMD_START_FACE_DETECTION:
748         case CAMERA_CMD_STOP_FACE_DETECTION:
749             // We do not support hardware face detection so we need to indicate
750             // that any attempt to start/stop face detection is invalid
751             return BAD_VALUE;
752     }
753     /* TODO: Future enhancements. */
754     return 0;
755 }
756 
releaseCamera()757 void EmulatedCamera::releaseCamera()
758 {
759     ALOGV("%s", __FUNCTION__);
760 
761     cleanupCamera();
762 }
763 
dumpCamera(int fd)764 status_t EmulatedCamera::dumpCamera(int fd)
765 {
766     ALOGV("%s", __FUNCTION__);
767 
768     /* TODO: Future enhancements. */
769     return -EINVAL;
770 }
771 
getConfiguredPixelFormat(uint32_t * pixelFormat) const772 status_t EmulatedCamera::getConfiguredPixelFormat(uint32_t* pixelFormat) const {
773     const char* pix_fmt = nullptr;
774     const char* recordingHint =
775         mParameters.get(CameraParameters::KEY_RECORDING_HINT);
776     bool recordingHintOn = recordingHint && strcmp(recordingHint,
777                                                    CameraParameters::TRUE) == 0;
778     bool recordingEnabled = mCallbackNotifier.isVideoRecordingEnabled();
779     if (recordingHintOn || recordingEnabled) {
780         // We're recording a video, use the video pixel format
781         pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
782     }
783     if (pix_fmt == nullptr) {
784         pix_fmt = mParameters.getPreviewFormat();
785     }
786     if (pix_fmt == nullptr) {
787         ALOGE("%s: Unable to obtain configured pixel format", __FUNCTION__);
788         return EINVAL;
789     }
790     /* Convert framework's pixel format to the FOURCC one. */
791     if (!GetFourCcFormatFromCameraParam(pix_fmt, pixelFormat)) {
792         ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
793         return EINVAL;
794     }
795     return NO_ERROR;
796 }
797 
getConfiguredFrameSize(int * outWidth,int * outHeight) const798 status_t EmulatedCamera::getConfiguredFrameSize(int* outWidth,
799                                                 int* outHeight) const {
800     int width = -1, height = -1;
801     if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != nullptr) {
802         mParameters.getVideoSize(&width, &height);
803     } else {
804         mParameters.getPreviewSize(&width, &height);
805     }
806     if (width < 0 || height < 0) {
807         ALOGE("%s: No frame size configured for camera", __FUNCTION__);
808         return EINVAL;
809     }
810     // Only modify the out parameters once we know we succeeded
811     *outWidth = width;
812     *outHeight = height;
813     return NO_ERROR;
814 }
815 
816 /****************************************************************************
817  * Preview management.
818  ***************************************************************************/
819 
doStartPreview()820 status_t EmulatedCamera::doStartPreview()
821 {
822     ALOGV("%s", __FUNCTION__);
823 
824     EmulatedCameraDevice* camera_dev = getCameraDevice();
825     if (camera_dev->isStarted()) {
826         camera_dev->stopDeliveringFrames();
827         camera_dev->stopDevice();
828     }
829 
830     status_t res = mPreviewWindow.startPreview();
831     if (res != NO_ERROR) {
832         return res;
833     }
834 
835     /* Make sure camera device is connected. */
836     if (!camera_dev->isConnected()) {
837         res = camera_dev->connectDevice();
838         if (res != NO_ERROR) {
839             mPreviewWindow.stopPreview();
840             return res;
841         }
842     }
843 
844     /* Lets see what should we use for frame width, and height. */
845     int width, height;
846     res = getConfiguredFrameSize(&width, &height);
847     if (res != NO_ERROR) {
848         mPreviewWindow.stopPreview();
849         return res;
850     }
851 
852     uint32_t org_fmt = 0;
853     res = getConfiguredPixelFormat(&org_fmt);
854     if (res != NO_ERROR) {
855         mPreviewWindow.stopPreview();
856         return res;
857     }
858 
859     camera_dev->setPreviewFrameRate(mParameters.getPreviewFrameRate());
860     ALOGD("Starting camera: %dx%d -> %.4s",
861          width, height, reinterpret_cast<const char*>(&org_fmt));
862     res = camera_dev->startDevice(width, height, org_fmt);
863     if (res != NO_ERROR) {
864         mPreviewWindow.stopPreview();
865         return res;
866     }
867 
868     res = camera_dev->startDeliveringFrames(false);
869     if (res != NO_ERROR) {
870         camera_dev->stopDevice();
871         mPreviewWindow.stopPreview();
872     }
873 
874     return res;
875 }
876 
doStopPreview()877 status_t EmulatedCamera::doStopPreview()
878 {
879     ALOGV("%s", __FUNCTION__);
880 
881     status_t res = NO_ERROR;
882     if (mPreviewWindow.isPreviewEnabled()) {
883         /* Stop the camera. */
884         if (getCameraDevice()->isStarted()) {
885             getCameraDevice()->stopDeliveringFrames();
886             res = getCameraDevice()->stopDevice();
887         }
888 
889         if (res == NO_ERROR) {
890             /* Disable preview as well. */
891             mPreviewWindow.stopPreview();
892         }
893     }
894 
895     return NO_ERROR;
896 }
897 
898 /****************************************************************************
899  * Private API.
900  ***************************************************************************/
901 
cleanupCamera()902 status_t EmulatedCamera::cleanupCamera()
903 {
904     status_t res = NO_ERROR;
905 
906     /* If preview is running - stop it. */
907     res = doStopPreview();
908     if (res != NO_ERROR) {
909         return -res;
910     }
911 
912     /* Stop and disconnect the camera device. */
913     EmulatedCameraDevice* const camera_dev = getCameraDevice();
914     if (camera_dev != NULL) {
915         if (camera_dev->isStarted()) {
916             camera_dev->stopDeliveringFrames();
917             res = camera_dev->stopDevice();
918             if (res != NO_ERROR) {
919                 return -res;
920             }
921         }
922         if (camera_dev->isConnected()) {
923             res = camera_dev->disconnectDevice();
924             if (res != NO_ERROR) {
925                 return -res;
926             }
927         }
928     }
929 
930     mCallbackNotifier.cleanupCBNotifier();
931 
932     /* Re-init the camera settings in case settings were changed */
933     Initialize();
934 
935     return NO_ERROR;
936 }
937 
938 /****************************************************************************
939  * Camera API callbacks as defined by camera_device_ops structure.
940  *
941  * Callbacks here simply dispatch the calls to an appropriate method inside
942  * EmulatedCamera instance, defined by the 'dev' parameter.
943  ***************************************************************************/
944 
set_preview_window(struct camera_device * dev,struct preview_stream_ops * window)945 int EmulatedCamera::set_preview_window(struct camera_device* dev,
946                                        struct preview_stream_ops* window)
947 {
948     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
949     if (ec == NULL) {
950         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
951         return -EINVAL;
952     }
953     return ec->setPreviewWindow(window);
954 }
955 
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)956 void EmulatedCamera::set_callbacks(
957         struct camera_device* dev,
958         camera_notify_callback notify_cb,
959         camera_data_callback data_cb,
960         camera_data_timestamp_callback data_cb_timestamp,
961         camera_request_memory get_memory,
962         void* user)
963 {
964     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
965     if (ec == NULL) {
966         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
967         return;
968     }
969     ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
970 }
971 
enable_msg_type(struct camera_device * dev,int32_t msg_type)972 void EmulatedCamera::enable_msg_type(struct camera_device* dev, int32_t msg_type)
973 {
974     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
975     if (ec == NULL) {
976         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
977         return;
978     }
979     ec->enableMsgType(msg_type);
980 }
981 
disable_msg_type(struct camera_device * dev,int32_t msg_type)982 void EmulatedCamera::disable_msg_type(struct camera_device* dev, int32_t msg_type)
983 {
984     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
985     if (ec == NULL) {
986         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
987         return;
988     }
989     ec->disableMsgType(msg_type);
990 }
991 
msg_type_enabled(struct camera_device * dev,int32_t msg_type)992 int EmulatedCamera::msg_type_enabled(struct camera_device* dev, int32_t msg_type)
993 {
994     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
995     if (ec == NULL) {
996         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
997         return -EINVAL;
998     }
999     return ec->isMsgTypeEnabled(msg_type);
1000 }
1001 
start_preview(struct camera_device * dev)1002 int EmulatedCamera::start_preview(struct camera_device* dev)
1003 {
1004     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1005     if (ec == NULL) {
1006         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1007         return -EINVAL;
1008     }
1009     return ec->startPreview();
1010 }
1011 
stop_preview(struct camera_device * dev)1012 void EmulatedCamera::stop_preview(struct camera_device* dev)
1013 {
1014     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1015     if (ec == NULL) {
1016         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1017         return;
1018     }
1019     ec->stopPreview();
1020 }
1021 
preview_enabled(struct camera_device * dev)1022 int EmulatedCamera::preview_enabled(struct camera_device* dev)
1023 {
1024     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1025     if (ec == NULL) {
1026         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1027         return -EINVAL;
1028     }
1029     return ec->isPreviewEnabled();
1030 }
1031 
store_meta_data_in_buffers(struct camera_device * dev,int enable)1032 int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev,
1033                                                int enable)
1034 {
1035     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1036     if (ec == NULL) {
1037         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1038         return -EINVAL;
1039     }
1040     return ec->storeMetaDataInBuffers(enable);
1041 }
1042 
start_recording(struct camera_device * dev)1043 int EmulatedCamera::start_recording(struct camera_device* dev)
1044 {
1045     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1046     if (ec == NULL) {
1047         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1048         return -EINVAL;
1049     }
1050     return ec->startRecording();
1051 }
1052 
stop_recording(struct camera_device * dev)1053 void EmulatedCamera::stop_recording(struct camera_device* dev)
1054 {
1055     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1056     if (ec == NULL) {
1057         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1058         return;
1059     }
1060     ec->stopRecording();
1061 }
1062 
recording_enabled(struct camera_device * dev)1063 int EmulatedCamera::recording_enabled(struct camera_device* dev)
1064 {
1065     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1066     if (ec == NULL) {
1067         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1068         return -EINVAL;
1069     }
1070     return ec->isRecordingEnabled();
1071 }
1072 
release_recording_frame(struct camera_device * dev,const void * opaque)1073 void EmulatedCamera::release_recording_frame(struct camera_device* dev,
1074                                              const void* opaque)
1075 {
1076     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1077     if (ec == NULL) {
1078         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1079         return;
1080     }
1081     ec->releaseRecordingFrame(opaque);
1082 }
1083 
auto_focus(struct camera_device * dev)1084 int EmulatedCamera::auto_focus(struct camera_device* dev)
1085 {
1086     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1087     if (ec == NULL) {
1088         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1089         return -EINVAL;
1090     }
1091     return ec->setAutoFocus();
1092 }
1093 
cancel_auto_focus(struct camera_device * dev)1094 int EmulatedCamera::cancel_auto_focus(struct camera_device* dev)
1095 {
1096     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1097     if (ec == NULL) {
1098         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1099         return -EINVAL;
1100     }
1101     return ec->cancelAutoFocus();
1102 }
1103 
take_picture(struct camera_device * dev)1104 int EmulatedCamera::take_picture(struct camera_device* dev)
1105 {
1106     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1107     if (ec == NULL) {
1108         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1109         return -EINVAL;
1110     }
1111     return ec->takePicture();
1112 }
1113 
cancel_picture(struct camera_device * dev)1114 int EmulatedCamera::cancel_picture(struct camera_device* dev)
1115 {
1116     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1117     if (ec == NULL) {
1118         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1119         return -EINVAL;
1120     }
1121     return ec->cancelPicture();
1122 }
1123 
set_parameters(struct camera_device * dev,const char * parms)1124 int EmulatedCamera::set_parameters(struct camera_device* dev, const char* parms)
1125 {
1126     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1127     if (ec == NULL) {
1128         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1129         return -EINVAL;
1130     }
1131     return ec->setParameters(parms);
1132 }
1133 
get_parameters(struct camera_device * dev)1134 char* EmulatedCamera::get_parameters(struct camera_device* dev)
1135 {
1136     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1137     if (ec == NULL) {
1138         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1139         return NULL;
1140     }
1141     return ec->getParameters();
1142 }
1143 
put_parameters(struct camera_device * dev,char * params)1144 void EmulatedCamera::put_parameters(struct camera_device* dev, char* params)
1145 {
1146     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1147     if (ec == NULL) {
1148         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1149         return;
1150     }
1151     ec->putParameters(params);
1152 }
1153 
send_command(struct camera_device * dev,int32_t cmd,int32_t arg1,int32_t arg2)1154 int EmulatedCamera::send_command(struct camera_device* dev,
1155                                  int32_t cmd,
1156                                  int32_t arg1,
1157                                  int32_t arg2)
1158 {
1159     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1160     if (ec == NULL) {
1161         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1162         return -EINVAL;
1163     }
1164     return ec->sendCommand(cmd, arg1, arg2);
1165 }
1166 
release(struct camera_device * dev)1167 void EmulatedCamera::release(struct camera_device* dev)
1168 {
1169     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1170     if (ec == NULL) {
1171         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1172         return;
1173     }
1174     ec->releaseCamera();
1175 }
1176 
dump(struct camera_device * dev,int fd)1177 int EmulatedCamera::dump(struct camera_device* dev, int fd)
1178 {
1179     EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
1180     if (ec == NULL) {
1181         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1182         return -EINVAL;
1183     }
1184     return ec->dumpCamera(fd);
1185 }
1186 
close(struct hw_device_t * device)1187 int EmulatedCamera::close(struct hw_device_t* device)
1188 {
1189     EmulatedCamera* ec =
1190         reinterpret_cast<EmulatedCamera*>(reinterpret_cast<struct camera_device*>(device)->priv);
1191     if (ec == NULL) {
1192         ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
1193         return -EINVAL;
1194     }
1195     return ec->closeCamera();
1196 }
1197 
1198 /****************************************************************************
1199  * Static initializer for the camera callback API
1200  ****************************************************************************/
1201 
1202 camera_device_ops_t EmulatedCamera::mDeviceOps = {
1203     EmulatedCamera::set_preview_window,
1204     EmulatedCamera::set_callbacks,
1205     EmulatedCamera::enable_msg_type,
1206     EmulatedCamera::disable_msg_type,
1207     EmulatedCamera::msg_type_enabled,
1208     EmulatedCamera::start_preview,
1209     EmulatedCamera::stop_preview,
1210     EmulatedCamera::preview_enabled,
1211     EmulatedCamera::store_meta_data_in_buffers,
1212     EmulatedCamera::start_recording,
1213     EmulatedCamera::stop_recording,
1214     EmulatedCamera::recording_enabled,
1215     EmulatedCamera::release_recording_frame,
1216     EmulatedCamera::auto_focus,
1217     EmulatedCamera::cancel_auto_focus,
1218     EmulatedCamera::take_picture,
1219     EmulatedCamera::cancel_picture,
1220     EmulatedCamera::set_parameters,
1221     EmulatedCamera::get_parameters,
1222     EmulatedCamera::put_parameters,
1223     EmulatedCamera::send_command,
1224     EmulatedCamera::release,
1225     EmulatedCamera::dump
1226 };
1227 
1228 /****************************************************************************
1229  * Common keys
1230  ***************************************************************************/
1231 
1232 const char EmulatedCamera::FACING_KEY[]         = "prop-facing";
1233 const char EmulatedCamera::ORIENTATION_KEY[]    = "prop-orientation";
1234 const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint";
1235 
1236 /****************************************************************************
1237  * Common string values
1238  ***************************************************************************/
1239 
1240 const char EmulatedCamera::FACING_BACK[]      = "back";
1241 const char EmulatedCamera::FACING_FRONT[]     = "front";
1242 
1243 /****************************************************************************
1244  * Helper routines
1245  ***************************************************************************/
1246 
AddValue(const char * param,const char * val)1247 static char* AddValue(const char* param, const char* val)
1248 {
1249     const size_t len1 = strlen(param);
1250     const size_t len2 = strlen(val);
1251     char* ret = reinterpret_cast<char*>(malloc(len1 + len2 + 2));
1252     ALOGE_IF(ret == NULL, "%s: Memory failure", __FUNCTION__);
1253     if (ret != NULL) {
1254         memcpy(ret, param, len1);
1255         ret[len1] = ',';
1256         memcpy(ret + len1 + 1, val, len2);
1257         ret[len1 + len2 + 1] = '\0';
1258     }
1259     return ret;
1260 }
1261 
1262 /****************************************************************************
1263  * Parameter debugging helpers
1264  ***************************************************************************/
1265 
1266 #if DEBUG_PARAM
PrintParamDiff(const CameraParameters & current,const char * new_par)1267 static void PrintParamDiff(const CameraParameters& current,
1268                             const char* new_par)
1269 {
1270     char tmp[2048];
1271     const char* wrk = new_par;
1272 
1273     /* Divided with ';' */
1274     const char* next = strchr(wrk, ';');
1275     while (next != NULL) {
1276         snprintf(tmp, sizeof(tmp), "%.*s", (int)(intptr_t)(next-wrk), wrk);
1277         /* in the form key=value */
1278         char* val = strchr(tmp, '=');
1279         if (val != NULL) {
1280             *val = '\0'; val++;
1281             const char* in_current = current.get(tmp);
1282             if (in_current != NULL) {
1283                 if (strcmp(in_current, val)) {
1284                     ALOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val);
1285                 }
1286             } else {
1287                 ALOGD("+++ New parameter: %s=%s", tmp, val);
1288             }
1289         } else {
1290             ALOGW("No value separator in %s", tmp);
1291         }
1292         wrk = next + 1;
1293         next = strchr(wrk, ';');
1294     }
1295 }
1296 #endif  /* DEBUG_PARAM */
1297 
1298 }; /* namespace android */
1299