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