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