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