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