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