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