1 /* 2 * Copyright (C) 2014 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 package android.hardware.camera2.legacy; 18 19 import android.graphics.Rect; 20 import android.hardware.Camera; 21 import android.hardware.Camera.Parameters; 22 import android.hardware.camera2.CameraCharacteristics; 23 import android.hardware.camera2.CaptureRequest; 24 import android.hardware.camera2.params.MeteringRectangle; 25 import android.hardware.camera2.utils.ListUtils; 26 import android.hardware.camera2.utils.ParamsUtils; 27 import android.location.Location; 28 import android.util.Log; 29 import android.util.Range; 30 import android.util.Size; 31 32 import java.util.ArrayList; 33 import java.util.Arrays; 34 import java.util.List; 35 import java.util.Objects; 36 37 import static android.hardware.camera2.CaptureRequest.*; 38 39 /** 40 * Provide legacy-specific implementations of camera2 CaptureRequest for legacy devices. 41 */ 42 @SuppressWarnings("deprecation") 43 public class LegacyRequestMapper { 44 private static final String TAG = "LegacyRequestMapper"; 45 private static final boolean DEBUG = false; 46 47 /** Default quality for android.jpeg.quality, android.jpeg.thumbnailQuality */ 48 private static final byte DEFAULT_JPEG_QUALITY = 85; 49 50 /** 51 * Set the legacy parameters using the {@link LegacyRequest legacy request}. 52 * 53 * <p>The legacy request's parameters are changed as a side effect of calling this 54 * method.</p> 55 * 56 * @param legacyRequest a non-{@code null} legacy request 57 */ convertRequestMetadata(LegacyRequest legacyRequest)58 public static void convertRequestMetadata(LegacyRequest legacyRequest) { 59 CameraCharacteristics characteristics = legacyRequest.characteristics; 60 CaptureRequest request = legacyRequest.captureRequest; 61 Size previewSize = legacyRequest.previewSize; 62 Camera.Parameters params = legacyRequest.parameters; 63 64 Rect activeArray = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); 65 66 /* 67 * scaler.cropRegion 68 */ 69 ParameterUtils.ZoomData zoomData; 70 { 71 zoomData = ParameterUtils.convertScalerCropRegion(activeArray, 72 request.get(SCALER_CROP_REGION), 73 previewSize, 74 params); 75 76 if (params.isZoomSupported()) { 77 params.setZoom(zoomData.zoomIndex); 78 } else if (DEBUG) { 79 Log.v(TAG, "convertRequestToMetadata - zoom is not supported"); 80 } 81 } 82 83 /* 84 * colorCorrection.* 85 */ 86 // colorCorrection.aberrationMode 87 { 88 int aberrationMode = ParamsUtils.getOrDefault(request, 89 COLOR_CORRECTION_ABERRATION_MODE, 90 /*defaultValue*/COLOR_CORRECTION_ABERRATION_MODE_FAST); 91 92 if (aberrationMode != COLOR_CORRECTION_ABERRATION_MODE_FAST && 93 aberrationMode != COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY) { 94 Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " + 95 "colorCorrection.aberrationMode = " + aberrationMode); 96 } 97 } 98 99 /* 100 * control.ae* 101 */ 102 // control.aeAntibandingMode 103 { 104 String legacyMode; 105 Integer antiBandingMode = request.get(CONTROL_AE_ANTIBANDING_MODE); 106 if (antiBandingMode != null) { 107 legacyMode = convertAeAntiBandingModeToLegacy(antiBandingMode); 108 } else { 109 legacyMode = ListUtils.listSelectFirstFrom(params.getSupportedAntibanding(), 110 new String[] { 111 Parameters.ANTIBANDING_AUTO, 112 Parameters.ANTIBANDING_OFF, 113 Parameters.ANTIBANDING_50HZ, 114 Parameters.ANTIBANDING_60HZ, 115 }); 116 } 117 118 if (legacyMode != null) { 119 params.setAntibanding(legacyMode); 120 } 121 } 122 123 /* 124 * control.aeRegions, afRegions 125 */ 126 { 127 // aeRegions 128 { 129 // Use aeRegions if available, fall back to using awbRegions if present 130 MeteringRectangle[] aeRegions = request.get(CONTROL_AE_REGIONS); 131 if (request.get(CONTROL_AWB_REGIONS) != null) { 132 Log.w(TAG, "convertRequestMetadata - control.awbRegions setting is not " + 133 "supported, ignoring value"); 134 } 135 int maxNumMeteringAreas = params.getMaxNumMeteringAreas(); 136 List<Camera.Area> meteringAreaList = convertMeteringRegionsToLegacy( 137 activeArray, zoomData, aeRegions, maxNumMeteringAreas, 138 /*regionName*/"AE"); 139 140 // WAR: for b/17252693, some devices can't handle params.setFocusAreas(null). 141 if (maxNumMeteringAreas > 0) { 142 params.setMeteringAreas(meteringAreaList); 143 } 144 } 145 146 // afRegions 147 { 148 MeteringRectangle[] afRegions = request.get(CONTROL_AF_REGIONS); 149 int maxNumFocusAreas = params.getMaxNumFocusAreas(); 150 List<Camera.Area> focusAreaList = convertMeteringRegionsToLegacy( 151 activeArray, zoomData, afRegions, maxNumFocusAreas, 152 /*regionName*/"AF"); 153 154 // WAR: for b/17252693, some devices can't handle params.setFocusAreas(null). 155 if (maxNumFocusAreas > 0) { 156 params.setFocusAreas(focusAreaList); 157 } 158 } 159 } 160 161 // control.aeTargetFpsRange 162 Range<Integer> aeFpsRange = request.get(CONTROL_AE_TARGET_FPS_RANGE); 163 if (aeFpsRange != null) { 164 int[] legacyFps = convertAeFpsRangeToLegacy(aeFpsRange); 165 166 int[] rangeToApply = null; 167 for(int[] range : params.getSupportedPreviewFpsRange()) { 168 // Round range up/down to integer FPS value 169 int intRangeLow = (int) Math.floor(range[0] / 1000.0) * 1000; 170 int intRangeHigh = (int) Math.ceil(range[1] / 1000.0) * 1000; 171 if (legacyFps[0] == intRangeLow && legacyFps[1] == intRangeHigh) { 172 rangeToApply = range; 173 break; 174 } 175 } 176 if (rangeToApply != null) { 177 params.setPreviewFpsRange(rangeToApply[Camera.Parameters.PREVIEW_FPS_MIN_INDEX], 178 rangeToApply[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); 179 } else { 180 Log.w(TAG, "Unsupported FPS range set [" + legacyFps[0] + "," + legacyFps[1] + "]"); 181 } 182 } 183 184 /* 185 * control 186 */ 187 188 // control.aeExposureCompensation 189 { 190 Range<Integer> compensationRange = 191 characteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE); 192 int compensation = ParamsUtils.getOrDefault(request, 193 CONTROL_AE_EXPOSURE_COMPENSATION, 194 /*defaultValue*/0); 195 196 if (!compensationRange.contains(compensation)) { 197 Log.w(TAG, 198 "convertRequestMetadata - control.aeExposureCompensation " + 199 "is out of range, ignoring value"); 200 compensation = 0; 201 } 202 203 params.setExposureCompensation(compensation); 204 } 205 206 // control.aeLock 207 { 208 Boolean aeLock = getIfSupported(request, CONTROL_AE_LOCK, /*defaultValue*/false, 209 params.isAutoExposureLockSupported(), 210 /*allowedValue*/false); 211 212 if (aeLock != null) { 213 params.setAutoExposureLock(aeLock); 214 } 215 216 if (DEBUG) { 217 Log.v(TAG, "convertRequestToMetadata - control.aeLock set to " + aeLock); 218 } 219 220 // TODO: Don't add control.aeLock to availableRequestKeys if it's not supported 221 } 222 223 // control.aeMode, flash.mode 224 mapAeAndFlashMode(request, /*out*/params); 225 226 // control.afMode 227 { 228 int afMode = ParamsUtils.getOrDefault(request, CONTROL_AF_MODE, 229 /*defaultValue*/CONTROL_AF_MODE_OFF); 230 String focusMode = LegacyMetadataMapper.convertAfModeToLegacy(afMode, 231 params.getSupportedFocusModes()); 232 233 if (focusMode != null) { 234 params.setFocusMode(focusMode); 235 } 236 237 if (DEBUG) { 238 Log.v(TAG, "convertRequestToMetadata - control.afMode " 239 + afMode + " mapped to " + focusMode); 240 } 241 } 242 243 // control.awbMode 244 { 245 Integer awbMode = getIfSupported(request, CONTROL_AWB_MODE, 246 /*defaultValue*/CONTROL_AWB_MODE_AUTO, 247 params.getSupportedWhiteBalance() != null, 248 /*allowedValue*/CONTROL_AWB_MODE_AUTO); 249 250 String whiteBalanceMode = null; 251 if (awbMode != null) { // null iff AWB is not supported by camera1 api 252 whiteBalanceMode = convertAwbModeToLegacy(awbMode); 253 params.setWhiteBalance(whiteBalanceMode); 254 } 255 256 if (DEBUG) { 257 Log.v(TAG, "convertRequestToMetadata - control.awbMode " 258 + awbMode + " mapped to " + whiteBalanceMode); 259 } 260 } 261 262 // control.awbLock 263 { 264 Boolean awbLock = getIfSupported(request, CONTROL_AWB_LOCK, /*defaultValue*/false, 265 params.isAutoWhiteBalanceLockSupported(), 266 /*allowedValue*/false); 267 268 if (awbLock != null) { 269 params.setAutoWhiteBalanceLock(awbLock); 270 } 271 272 // TODO: Don't add control.awbLock to availableRequestKeys if it's not supported 273 } 274 275 // control.captureIntent 276 { 277 int captureIntent = ParamsUtils.getOrDefault(request, 278 CONTROL_CAPTURE_INTENT, 279 /*defaultValue*/CONTROL_CAPTURE_INTENT_PREVIEW); 280 281 captureIntent = filterSupportedCaptureIntent(captureIntent); 282 283 params.setRecordingHint( 284 captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_RECORD || 285 captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT); 286 } 287 288 // control.videoStabilizationMode 289 { 290 Integer stabMode = getIfSupported(request, CONTROL_VIDEO_STABILIZATION_MODE, 291 /*defaultValue*/CONTROL_VIDEO_STABILIZATION_MODE_OFF, 292 params.isVideoStabilizationSupported(), 293 /*allowedValue*/CONTROL_VIDEO_STABILIZATION_MODE_OFF); 294 295 if (stabMode != null) { 296 params.setVideoStabilization(stabMode == CONTROL_VIDEO_STABILIZATION_MODE_ON); 297 } 298 } 299 300 // lens.focusDistance 301 { 302 boolean infinityFocusSupported = 303 ListUtils.listContains(params.getSupportedFocusModes(), 304 Parameters.FOCUS_MODE_INFINITY); 305 Float focusDistance = getIfSupported(request, LENS_FOCUS_DISTANCE, 306 /*defaultValue*/0f, infinityFocusSupported, /*allowedValue*/0f); 307 308 if (focusDistance == null || focusDistance != 0f) { 309 Log.w(TAG, 310 "convertRequestToMetadata - Ignoring android.lens.focusDistance " 311 + infinityFocusSupported + ", only 0.0f is supported"); 312 } 313 } 314 315 // control.sceneMode, control.mode 316 { 317 // TODO: Map FACE_PRIORITY scene mode to face detection. 318 319 if (params.getSupportedSceneModes() != null) { 320 int controlMode = ParamsUtils.getOrDefault(request, CONTROL_MODE, 321 /*defaultValue*/CONTROL_MODE_AUTO); 322 String modeToSet; 323 switch (controlMode) { 324 case CONTROL_MODE_USE_SCENE_MODE: { 325 int sceneMode = ParamsUtils.getOrDefault(request, CONTROL_SCENE_MODE, 326 /*defaultValue*/CONTROL_SCENE_MODE_DISABLED); 327 String legacySceneMode = LegacyMetadataMapper. 328 convertSceneModeToLegacy(sceneMode); 329 if (legacySceneMode != null) { 330 modeToSet = legacySceneMode; 331 } else { 332 modeToSet = Parameters.SCENE_MODE_AUTO; 333 Log.w(TAG, "Skipping unknown requested scene mode: " + sceneMode); 334 } 335 break; 336 } 337 case CONTROL_MODE_AUTO: { 338 modeToSet = Parameters.SCENE_MODE_AUTO; 339 break; 340 } 341 default: { 342 Log.w(TAG, "Control mode " + controlMode + 343 " is unsupported, defaulting to AUTO"); 344 modeToSet = Parameters.SCENE_MODE_AUTO; 345 } 346 } 347 params.setSceneMode(modeToSet); 348 } 349 } 350 351 // control.effectMode 352 { 353 if (params.getSupportedColorEffects() != null) { 354 int effectMode = ParamsUtils.getOrDefault(request, CONTROL_EFFECT_MODE, 355 /*defaultValue*/CONTROL_EFFECT_MODE_OFF); 356 String legacyEffectMode = LegacyMetadataMapper.convertEffectModeToLegacy(effectMode); 357 if (legacyEffectMode != null) { 358 params.setColorEffect(legacyEffectMode); 359 } else { 360 params.setColorEffect(Parameters.EFFECT_NONE); 361 Log.w(TAG, "Skipping unknown requested effect mode: " + effectMode); 362 } 363 } 364 } 365 366 /* 367 * sensor 368 */ 369 370 // sensor.testPattern 371 { 372 int testPatternMode = ParamsUtils.getOrDefault(request, SENSOR_TEST_PATTERN_MODE, 373 /*defaultValue*/SENSOR_TEST_PATTERN_MODE_OFF); 374 if (testPatternMode != SENSOR_TEST_PATTERN_MODE_OFF) { 375 Log.w(TAG, "convertRequestToMetadata - ignoring sensor.testPatternMode " 376 + testPatternMode + "; only OFF is supported"); 377 } 378 } 379 380 /* 381 * jpeg.* 382 */ 383 384 // jpeg.gpsLocation 385 { 386 Location location = request.get(JPEG_GPS_LOCATION); 387 if (location != null) { 388 if (checkForCompleteGpsData(location)) { 389 params.setGpsAltitude(location.getAltitude()); 390 params.setGpsLatitude(location.getLatitude()); 391 params.setGpsLongitude(location.getLongitude()); 392 params.setGpsProcessingMethod(location.getProvider().toUpperCase()); 393 params.setGpsTimestamp(location.getTime()); 394 } else { 395 Log.w(TAG, "Incomplete GPS parameters provided in location " + location); 396 } 397 } else { 398 params.removeGpsData(); 399 } 400 } 401 402 // jpeg.orientation 403 { 404 Integer orientation = request.get(CaptureRequest.JPEG_ORIENTATION); 405 params.setRotation(ParamsUtils.getOrDefault(request, JPEG_ORIENTATION, 406 (orientation == null) ? 0 : orientation)); 407 } 408 409 // jpeg.quality 410 { 411 params.setJpegQuality(0xFF & ParamsUtils.getOrDefault(request, JPEG_QUALITY, 412 DEFAULT_JPEG_QUALITY)); 413 } 414 415 // jpeg.thumbnailQuality 416 { 417 params.setJpegThumbnailQuality(0xFF & ParamsUtils.getOrDefault(request, 418 JPEG_THUMBNAIL_QUALITY, DEFAULT_JPEG_QUALITY)); 419 } 420 421 // jpeg.thumbnailSize 422 { 423 List<Camera.Size> sizes = params.getSupportedJpegThumbnailSizes(); 424 425 if (sizes != null && sizes.size() > 0) { 426 Size s = request.get(JPEG_THUMBNAIL_SIZE); 427 boolean invalidSize = (s == null) ? false : !ParameterUtils.containsSize(sizes, 428 s.getWidth(), s.getHeight()); 429 if (invalidSize) { 430 Log.w(TAG, "Invalid JPEG thumbnail size set " + s + ", skipping thumbnail..."); 431 } 432 if (s == null || invalidSize) { 433 // (0,0) = "no thumbnail" in Camera API 1 434 params.setJpegThumbnailSize(/*width*/0, /*height*/0); 435 } else { 436 params.setJpegThumbnailSize(s.getWidth(), s.getHeight()); 437 } 438 } 439 } 440 441 /* 442 * noiseReduction.* 443 */ 444 // noiseReduction.mode 445 { 446 int mode = ParamsUtils.getOrDefault(request, 447 NOISE_REDUCTION_MODE, 448 /*defaultValue*/NOISE_REDUCTION_MODE_FAST); 449 450 if (mode != NOISE_REDUCTION_MODE_FAST && 451 mode != NOISE_REDUCTION_MODE_HIGH_QUALITY) { 452 Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " + 453 "noiseReduction.mode = " + mode); 454 } 455 } 456 } 457 checkForCompleteGpsData(Location location)458 private static boolean checkForCompleteGpsData(Location location) { 459 return location != null && location.getProvider() != null && location.getTime() != 0; 460 } 461 filterSupportedCaptureIntent(int captureIntent)462 static int filterSupportedCaptureIntent(int captureIntent) { 463 switch (captureIntent) { 464 case CONTROL_CAPTURE_INTENT_CUSTOM: 465 case CONTROL_CAPTURE_INTENT_PREVIEW: 466 case CONTROL_CAPTURE_INTENT_STILL_CAPTURE: 467 case CONTROL_CAPTURE_INTENT_VIDEO_RECORD: 468 case CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT: 469 break; 470 case CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG: 471 case CONTROL_CAPTURE_INTENT_MANUAL: 472 captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW; 473 Log.w(TAG, "Unsupported control.captureIntent value " + captureIntent 474 + "; default to PREVIEW"); 475 default: 476 captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW; 477 Log.w(TAG, "Unknown control.captureIntent value " + captureIntent 478 + "; default to PREVIEW"); 479 } 480 481 return captureIntent; 482 } 483 convertMeteringRegionsToLegacy( Rect activeArray, ParameterUtils.ZoomData zoomData, MeteringRectangle[] meteringRegions, int maxNumMeteringAreas, String regionName)484 private static List<Camera.Area> convertMeteringRegionsToLegacy( 485 Rect activeArray, ParameterUtils.ZoomData zoomData, 486 MeteringRectangle[] meteringRegions, int maxNumMeteringAreas, String regionName) { 487 if (meteringRegions == null || maxNumMeteringAreas <= 0) { 488 if (maxNumMeteringAreas > 0) { 489 return Arrays.asList(ParameterUtils.CAMERA_AREA_DEFAULT); 490 } else { 491 return null; 492 } 493 } 494 495 // Add all non-zero weight regions to the list 496 List<MeteringRectangle> meteringRectangleList = new ArrayList<>(); 497 for (MeteringRectangle rect : meteringRegions) { 498 if (rect.getMeteringWeight() != MeteringRectangle.METERING_WEIGHT_DONT_CARE) { 499 meteringRectangleList.add(rect); 500 } 501 } 502 503 if (meteringRectangleList.size() == 0) { 504 Log.w(TAG, "Only received metering rectangles with weight 0."); 505 return Arrays.asList(ParameterUtils.CAMERA_AREA_DEFAULT); 506 } 507 508 // Ignore any regions beyond our maximum supported count 509 int countMeteringAreas = 510 Math.min(maxNumMeteringAreas, meteringRectangleList.size()); 511 List<Camera.Area> meteringAreaList = new ArrayList<>(countMeteringAreas); 512 513 for (int i = 0; i < countMeteringAreas; ++i) { 514 MeteringRectangle rect = meteringRectangleList.get(i); 515 516 ParameterUtils.MeteringData meteringData = 517 ParameterUtils.convertMeteringRectangleToLegacy(activeArray, rect, zoomData); 518 meteringAreaList.add(meteringData.meteringArea); 519 } 520 521 if (maxNumMeteringAreas < meteringRectangleList.size()) { 522 Log.w(TAG, 523 "convertMeteringRegionsToLegacy - Too many requested " + regionName + 524 " regions, ignoring all beyond the first " + maxNumMeteringAreas); 525 } 526 527 if (DEBUG) { 528 Log.v(TAG, "convertMeteringRegionsToLegacy - " + regionName + " areas = " 529 + ParameterUtils.stringFromAreaList(meteringAreaList)); 530 } 531 532 return meteringAreaList; 533 } 534 mapAeAndFlashMode(CaptureRequest r, Parameters p)535 private static void mapAeAndFlashMode(CaptureRequest r, /*out*/Parameters p) { 536 int flashMode = ParamsUtils.getOrDefault(r, FLASH_MODE, FLASH_MODE_OFF); 537 int aeMode = ParamsUtils.getOrDefault(r, CONTROL_AE_MODE, CONTROL_AE_MODE_ON); 538 539 List<String> supportedFlashModes = p.getSupportedFlashModes(); 540 541 String flashModeSetting = null; 542 543 // Flash is OFF by default, on cameras that support flash 544 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_OFF)) { 545 flashModeSetting = Parameters.FLASH_MODE_OFF; 546 } 547 548 /* 549 * Map all of the control.aeMode* enums, but ignore AE_MODE_OFF since we never support it 550 */ 551 552 // Ignore flash.mode controls unless aeMode == ON 553 if (aeMode == CONTROL_AE_MODE_ON) { 554 if (flashMode == FLASH_MODE_TORCH) { 555 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_TORCH)) { 556 flashModeSetting = Parameters.FLASH_MODE_TORCH; 557 } else { 558 Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == TORCH;" + 559 "camera does not support it"); 560 } 561 } else if (flashMode == FLASH_MODE_SINGLE) { 562 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) { 563 flashModeSetting = Parameters.FLASH_MODE_ON; 564 } else { 565 Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == SINGLE;" + 566 "camera does not support it"); 567 } 568 } else { 569 // Use the default FLASH_MODE_OFF 570 } 571 } else if (aeMode == CONTROL_AE_MODE_ON_ALWAYS_FLASH) { 572 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) { 573 flashModeSetting = Parameters.FLASH_MODE_ON; 574 } else { 575 Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_ALWAYS_FLASH;" + 576 "camera does not support it"); 577 } 578 } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH) { 579 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_AUTO)) { 580 flashModeSetting = Parameters.FLASH_MODE_AUTO; 581 } else { 582 Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH;" + 583 "camera does not support it"); 584 } 585 } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) { 586 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_RED_EYE)) { 587 flashModeSetting = Parameters.FLASH_MODE_RED_EYE; 588 } else { 589 Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH_REDEYE;" 590 + "camera does not support it"); 591 } 592 } else { 593 // Default to aeMode == ON, flash = OFF 594 } 595 596 if (flashModeSetting != null) { 597 p.setFlashMode(flashModeSetting); 598 } 599 600 if (DEBUG) { 601 Log.v(TAG, 602 "mapAeAndFlashMode - set flash.mode (api1) to " + flashModeSetting 603 + ", requested (api2) " + flashMode 604 + ", supported (api1) " + ListUtils.listToString(supportedFlashModes)); 605 } 606 } 607 608 /** 609 * Returns null if the anti-banding mode enum is not supported. 610 */ convertAeAntiBandingModeToLegacy(int mode)611 private static String convertAeAntiBandingModeToLegacy(int mode) { 612 switch (mode) { 613 case CONTROL_AE_ANTIBANDING_MODE_OFF: { 614 return Parameters.ANTIBANDING_OFF; 615 } 616 case CONTROL_AE_ANTIBANDING_MODE_50HZ: { 617 return Parameters.ANTIBANDING_50HZ; 618 } 619 case CONTROL_AE_ANTIBANDING_MODE_60HZ: { 620 return Parameters.ANTIBANDING_60HZ; 621 } 622 case CONTROL_AE_ANTIBANDING_MODE_AUTO: { 623 return Parameters.ANTIBANDING_AUTO; 624 } 625 default: { 626 return null; 627 } 628 } 629 } 630 convertAeFpsRangeToLegacy(Range<Integer> fpsRange)631 private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) { 632 int[] legacyFps = new int[2]; 633 legacyFps[Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower() * 1000; 634 legacyFps[Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper() * 1000; 635 return legacyFps; 636 } 637 convertAwbModeToLegacy(int mode)638 private static String convertAwbModeToLegacy(int mode) { 639 switch (mode) { 640 case CONTROL_AWB_MODE_AUTO: 641 return Camera.Parameters.WHITE_BALANCE_AUTO; 642 case CONTROL_AWB_MODE_INCANDESCENT: 643 return Camera.Parameters.WHITE_BALANCE_INCANDESCENT; 644 case CONTROL_AWB_MODE_FLUORESCENT: 645 return Camera.Parameters.WHITE_BALANCE_FLUORESCENT; 646 case CONTROL_AWB_MODE_WARM_FLUORESCENT: 647 return Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT; 648 case CONTROL_AWB_MODE_DAYLIGHT: 649 return Camera.Parameters.WHITE_BALANCE_DAYLIGHT; 650 case CONTROL_AWB_MODE_CLOUDY_DAYLIGHT: 651 return Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT; 652 case CONTROL_AWB_MODE_TWILIGHT: 653 return Camera.Parameters.WHITE_BALANCE_TWILIGHT; 654 case CONTROL_AWB_MODE_SHADE: 655 return Parameters.WHITE_BALANCE_SHADE; 656 default: 657 Log.w(TAG, "convertAwbModeToLegacy - unrecognized control.awbMode" + mode); 658 return Camera.Parameters.WHITE_BALANCE_AUTO; 659 } 660 } 661 662 663 /** 664 * Return {@code null} if the value is not supported, otherwise return the retrieved key's 665 * value from the request (or the default value if it wasn't set). 666 * 667 * <p>If the fetched value in the request is equivalent to {@code allowedValue}, 668 * then omit the warning (e.g. turning off AF lock on a camera 669 * that always has the AF lock turned off is a silent no-op), but still return {@code null}.</p> 670 * 671 * <p>Logs a warning to logcat if the key is not supported by api1 camera device.</p. 672 */ getIfSupported( CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue, boolean isSupported, T allowedValue)673 private static <T> T getIfSupported( 674 CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue, boolean isSupported, 675 T allowedValue) { 676 T val = ParamsUtils.getOrDefault(r, key, defaultValue); 677 678 if (!isSupported) { 679 if (!Objects.equals(val, allowedValue)) { 680 Log.w(TAG, key.getName() + " is not supported; ignoring requested value " + val); 681 } 682 return null; 683 } 684 685 return val; 686 } 687 } 688