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