1 /* 2 * Copyright (C) 2015 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 package com.android.cts.deviceinfo; 17 18 import android.content.Context; 19 import android.graphics.ColorSpace; 20 import android.graphics.ImageFormat; 21 import android.graphics.Rect; 22 import android.hardware.camera2.CameraAccessException; 23 import android.hardware.camera2.CameraCharacteristics; 24 import android.hardware.camera2.CameraManager; 25 import android.hardware.camera2.params.BlackLevelPattern; 26 import android.hardware.camera2.params.ColorSpaceProfiles; 27 import android.hardware.camera2.params.ColorSpaceTransform; 28 import android.hardware.camera2.params.DynamicRangeProfiles; 29 import android.hardware.camera2.params.MultiResolutionStreamConfigurationMap; 30 import android.hardware.camera2.params.MultiResolutionStreamInfo; 31 import android.hardware.camera2.params.StreamConfigurationMap; 32 import android.media.CamcorderProfile; 33 import android.util.Log; 34 import android.util.Range; 35 import android.util.Rational; 36 import android.util.Size; 37 import android.util.SizeF; 38 39 import com.android.compatibility.common.deviceinfo.DeviceInfo; 40 import com.android.compatibility.common.util.DeviceInfoStore; 41 42 import java.lang.reflect.Array; 43 import java.lang.reflect.Field; 44 import java.lang.reflect.GenericArrayType; 45 import java.lang.reflect.Modifier; 46 import java.lang.reflect.ParameterizedType; 47 import java.lang.reflect.Type; 48 import java.util.ArrayList; 49 import java.util.Collection; 50 import java.util.HashMap; 51 import java.util.HashSet; 52 import java.util.List; 53 import java.util.Set; 54 55 /** 56 * Camera information collector. 57 */ 58 public final class CameraDeviceInfo extends DeviceInfo { 59 private static final String TAG = "CameraDeviceInfo"; 60 61 private final static class CameraCharacteristicsStorer { 62 private CameraManager mCameraManager; 63 private DeviceInfoStore mStore; 64 CameraCharacteristicsStorer(CameraManager cameraManager, DeviceInfoStore store)65 public CameraCharacteristicsStorer(CameraManager cameraManager, DeviceInfoStore store) { 66 if (cameraManager == null || store == null) { 67 throw new IllegalArgumentException("can not create an CameraMetadataGetter object" 68 + " with null CameraManager or null DeviceInfoStore"); 69 } 70 71 mCameraManager = cameraManager; 72 mStore = store; 73 } 74 storeCameraInfo(String cameraId)75 public void storeCameraInfo(String cameraId) throws Exception { 76 try { 77 CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(cameraId); 78 mStore.startGroup(); // per camera chars 79 mStore.addResult("cameraId", cameraId); 80 storeCameraChars(chars); 81 mStore.endGroup(); // per camera chars 82 } catch (CameraAccessException e) { 83 Log.e(TAG, 84 "Unable to get camera camera static info, skip this camera, error: " 85 + e.getMessage()); 86 } 87 return; 88 } 89 storePhysicalCameraInfo(String cameraId, List<String> logicalCameras)90 public void storePhysicalCameraInfo(String cameraId, List<String> logicalCameras) 91 throws Exception { 92 try { 93 CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(cameraId); 94 mStore.startGroup(); // per camera chars 95 mStore.addResult("cameraId", cameraId); 96 mStore.addListResult("parentLogicalCameraIds", logicalCameras); 97 storeCameraChars(chars); 98 mStore.endGroup(); // per camera chars 99 } catch (CameraAccessException e) { 100 Log.e(TAG, 101 "Unable to get camera camera static info, skip this camera, error: " 102 + e.getMessage()); 103 } 104 return; 105 } 106 storeRational( Rational rat, String protoName)107 private void storeRational( 108 Rational rat, String protoName) throws Exception { 109 if (protoName == null) { 110 mStore.startGroup(); 111 } else { 112 mStore.startGroup(protoName); 113 } 114 mStore.addResult("numerator", rat.getNumerator()); 115 mStore.addResult("denominator", rat.getDenominator()); 116 mStore.endGroup(); 117 } 118 storeSize( Size size, String protoName)119 private void storeSize( 120 Size size, String protoName) throws Exception { 121 if (protoName == null) { 122 mStore.startGroup(); 123 } else { 124 mStore.startGroup(protoName); 125 } 126 mStore.addResult("width", size.getWidth()); 127 mStore.addResult("height", size.getHeight()); 128 mStore.endGroup(); 129 } 130 storeSizeF( SizeF size, String protoName)131 private void storeSizeF( 132 SizeF size, String protoName) throws Exception { 133 if (protoName == null) { 134 mStore.startGroup(); 135 } else { 136 mStore.startGroup(protoName); 137 } 138 mStore.addResult("width", size.getWidth()); 139 mStore.addResult("height", size.getHeight()); 140 mStore.endGroup(); 141 } 142 storeRect( Rect rect, String protoName)143 private void storeRect( 144 Rect rect, String protoName) throws Exception { 145 if (protoName == null) { 146 mStore.startGroup(); 147 } else { 148 mStore.startGroup(protoName); 149 } 150 mStore.addResult("left", rect.left); 151 mStore.addResult("right", rect.right); 152 mStore.addResult("top", rect.top); 153 mStore.addResult("bottom", rect.bottom); 154 mStore.endGroup(); 155 } 156 storeStreamConfigurationMap( StreamConfigurationMap map, String protoName)157 private void storeStreamConfigurationMap( 158 StreamConfigurationMap map, String protoName) throws Exception { 159 if (protoName == null) { 160 mStore.startGroup(); 161 } else { 162 mStore.startGroup(protoName); 163 } 164 165 int fmts[] = map.getOutputFormats(); 166 if (fmts != null) { 167 mStore.startArray("availableStreamConfigurations"); 168 for (int fi = 0; fi < Array.getLength(fmts); fi++) { 169 Size sizes[] = map.getOutputSizes(fmts[fi]); 170 if (sizes != null) { 171 for (int si = 0; si < Array.getLength(sizes); si++) { 172 mStore.startGroup(); 173 mStore.addResult("format", fmts[fi]); 174 mStore.addResult("width", sizes[si].getWidth()); 175 mStore.addResult("height", sizes[si].getHeight()); 176 mStore.addResult("input", false); 177 mStore.addResult("minFrameDuration", 178 map.getOutputMinFrameDuration(fmts[fi], sizes[si])); 179 mStore.endGroup(); 180 } 181 } 182 } 183 mStore.endArray(); 184 } 185 186 Size[] highSpeedVideoSizes = map.getHighSpeedVideoSizes(); 187 if (highSpeedVideoSizes != null && highSpeedVideoSizes.length > 0) { 188 mStore.startArray("availableHighSpeedVideoConfigurations"); 189 for (int i = 0; i < highSpeedVideoSizes.length; i++) { 190 Range<Integer>[] fpsRanges = map.getHighSpeedVideoFpsRangesFor( 191 highSpeedVideoSizes[i]); 192 if (fpsRanges != null && fpsRanges.length > 0) { 193 for (int j = 0; j < fpsRanges.length; j++) { 194 mStore.startGroup(); 195 mStore.addResult("width", highSpeedVideoSizes[i].getWidth()); 196 mStore.addResult("height", highSpeedVideoSizes[i].getHeight()); 197 mStore.addResult("minFps", fpsRanges[j].getLower()); 198 mStore.addResult("maxFps", fpsRanges[j].getUpper()); 199 mStore.endGroup(); 200 } 201 } 202 } 203 mStore.endArray(); 204 } 205 206 int inputFmts[] = map.getInputFormats(); 207 if (inputFmts != null && inputFmts.length > 0) { 208 mStore.startArray("availableInputConfigurations"); 209 for (int i = 0 ; i < inputFmts.length; i++) { 210 Size[] inputSizes = map.getInputSizes(inputFmts[i]); 211 if (inputSizes != null && inputSizes.length > 0) { 212 for (int j = 0; j < inputSizes.length; j++) { 213 mStore.startGroup(); 214 mStore.addResult("inputFormat", inputFmts[i]); 215 mStore.addResult("inputWidth", inputSizes[j].getWidth()); 216 mStore.addResult("inputHeight", inputSizes[j].getHeight()); 217 mStore.endGroup(); 218 } 219 } 220 } 221 mStore.endArray(); 222 223 mStore.startArray("availableInputOutputFormatsMap"); 224 for (int i = 0 ; i < inputFmts.length; i++) { 225 int[] outputFmts = map.getValidOutputFormatsForInput(inputFmts[i]); 226 if (outputFmts != null && outputFmts.length > 0) { 227 for (int j = 0; j < outputFmts.length; j++) { 228 mStore.startGroup(); 229 mStore.addResult("inputFormat", inputFmts[i]); 230 mStore.addResult("outputFormat", outputFmts[j]); 231 mStore.endGroup(); 232 } 233 } 234 } 235 mStore.endArray(); 236 } 237 238 mStore.endGroup(); 239 } 240 storeRangeFloat( Range<Float> range, String protoName)241 private void storeRangeFloat( 242 Range<Float> range, String protoName) throws Exception { 243 if (protoName == null) { 244 mStore.startGroup(); 245 } else { 246 mStore.startGroup(protoName); 247 } 248 mStore.addResult("lower", range.getLower()); 249 mStore.addResult("upper", range.getUpper()); 250 mStore.endGroup(); 251 } 252 storeRangeInt( Range<Integer> range, String protoName)253 private void storeRangeInt( 254 Range<Integer> range, String protoName) throws Exception { 255 if (protoName == null) { 256 mStore.startGroup(); 257 } else { 258 mStore.startGroup(protoName); 259 } 260 mStore.addResult("lower", range.getLower()); 261 mStore.addResult("upper", range.getUpper()); 262 mStore.endGroup(); 263 } 264 storeRangeLong( Range<Long> range, String protoName)265 private void storeRangeLong( 266 Range<Long> range, String protoName) throws Exception { 267 if (protoName == null) { 268 mStore.startGroup(); 269 } else { 270 mStore.startGroup(protoName); 271 } 272 mStore.addResult("lower", range.getLower()); 273 mStore.addResult("upper", range.getUpper()); 274 mStore.endGroup(); 275 } 276 storeColorSpaceProfiles( ColorSpaceProfiles profiles, String protoName)277 private void storeColorSpaceProfiles( 278 ColorSpaceProfiles profiles, String protoName) throws Exception { 279 if (protoName == null) { 280 mStore.startGroup(); 281 } else { 282 mStore.startGroup(protoName); 283 } 284 285 mStore.startArray("color_space_profiles"); 286 Set<ColorSpace.Named> supportedColorSpaces = profiles.getSupportedColorSpaces( 287 ImageFormat.UNKNOWN); 288 for (ColorSpace.Named colorSpace : supportedColorSpaces) { 289 mStore.startGroup(); 290 Set<Integer> supportedImageFormats = 291 profiles.getSupportedImageFormatsForColorSpace(colorSpace); 292 mStore.addResult("color_space", colorSpace.ordinal()); 293 mStore.startArray("image_formats"); 294 for (int imageFormat : supportedImageFormats) { 295 mStore.startGroup(); 296 Set<Long> supportedDynamicRangeProfiles = 297 profiles.getSupportedDynamicRangeProfiles(colorSpace, imageFormat); 298 mStore.addResult("image_format", imageFormat); 299 mStore.addArrayResult("dynamic_range_profiles", 300 supportedDynamicRangeProfiles.stream().mapToLong( 301 Long::longValue).toArray()); 302 mStore.endGroup(); 303 } 304 mStore.endArray(); 305 mStore.endGroup(); 306 } 307 mStore.endArray(); 308 mStore.endGroup(); 309 } 310 storeColorSpaceTransform( ColorSpaceTransform xform, String protoName)311 private void storeColorSpaceTransform( 312 ColorSpaceTransform xform, String protoName) throws Exception { 313 if (protoName == null) { 314 mStore.startGroup(); 315 } else { 316 mStore.startGroup(protoName); 317 } 318 319 mStore.startArray("elements"); 320 for (int row = 0; row < 3; row++) { 321 for (int col = 0; col < 3; col++) { 322 storeRational((Rational) xform.getElement(col, row), null); 323 } 324 } 325 mStore.endArray(); 326 mStore.endGroup(); 327 } 328 storeDynamicRangeProfiles( DynamicRangeProfiles profiles, String protoName)329 private void storeDynamicRangeProfiles( 330 DynamicRangeProfiles profiles, String protoName) throws Exception { 331 if (protoName == null) { 332 mStore.startGroup(); 333 } else { 334 mStore.startGroup(protoName); 335 } 336 mStore.addArrayResult("dynamic_range_profiles", 337 profiles.getSupportedProfiles().stream().mapToLong(Long::longValue).toArray()); 338 mStore.endGroup(); 339 } 340 storeBlackLevelPattern( BlackLevelPattern pat, String protoName)341 private void storeBlackLevelPattern( 342 BlackLevelPattern pat, String protoName) throws Exception { 343 if (protoName == null) { 344 mStore.startGroup(); 345 } else { 346 mStore.startGroup(protoName); 347 } 348 int patVals[] = new int[4]; 349 pat.copyTo(patVals, 0); 350 mStore.addArrayResult("black_level_pattern", patVals); 351 mStore.endGroup(); 352 } 353 storeMultiResStreamConfigurationMap( MultiResolutionStreamConfigurationMap map, String protoName)354 private void storeMultiResStreamConfigurationMap( 355 MultiResolutionStreamConfigurationMap map, String protoName) throws Exception { 356 if (protoName == null) { 357 mStore.startGroup(); 358 } else { 359 mStore.startGroup(protoName); 360 } 361 362 mStore.startArray("availableMultiResolutionConfigurations"); 363 int[] fmts = map.getOutputFormats(); 364 if (fmts != null) { 365 for (int fi = 0; fi < Array.getLength(fmts); fi++) { 366 Collection<MultiResolutionStreamInfo> streamInfo = map.getOutputInfo(fmts[fi]); 367 if (streamInfo != null) { 368 for (MultiResolutionStreamInfo oneStream : streamInfo) { 369 mStore.startGroup(); 370 mStore.addResult("format", fmts[fi]); 371 mStore.addResult("width", oneStream.getWidth()); 372 mStore.addResult("height", oneStream.getHeight()); 373 mStore.addResult("cameraId", oneStream.getPhysicalCameraId()); 374 mStore.addResult("input", false); 375 mStore.endGroup(); 376 } 377 } 378 } 379 } 380 381 int[] inputFmts = map.getInputFormats(); 382 if (inputFmts != null) { 383 for (int fi = 0; fi < Array.getLength(inputFmts); fi++) { 384 Collection<MultiResolutionStreamInfo> streamInfo = 385 map.getInputInfo(inputFmts[fi]); 386 if (streamInfo != null) { 387 for (MultiResolutionStreamInfo oneStream : streamInfo) { 388 mStore.startGroup(); 389 mStore.addResult("format", inputFmts[fi]); 390 mStore.addResult("width", oneStream.getWidth()); 391 mStore.addResult("height", oneStream.getHeight()); 392 mStore.addResult("cameraId", oneStream.getPhysicalCameraId()); 393 mStore.addResult("input", true); 394 mStore.endGroup(); 395 } 396 } 397 } 398 } 399 mStore.endArray(); 400 mStore.endGroup(); 401 } 402 getKeyName(Object keyObj)403 private static String getKeyName(Object keyObj) { 404 return ((CameraCharacteristics.Key) keyObj).getName(); 405 } 406 getKeyValue(CameraCharacteristics chars, Object keyObj)407 private static Object getKeyValue(CameraCharacteristics chars, Object keyObj) { 408 return chars.get((CameraCharacteristics.Key) keyObj); 409 } 410 storeEntry(Type keyType, Object keyObj, CameraCharacteristics chars)411 private void storeEntry(Type keyType, Object keyObj, 412 CameraCharacteristics chars) throws Exception { 413 String keyName = getKeyName(keyObj); 414 String protoName = keyName.replace('.', '_'); 415 Object keyValue = getKeyValue(chars, keyObj); 416 if (keyValue == null) { 417 return; 418 } 419 420 if (keyType == int.class || keyType == Integer.class) { 421 mStore.addResult(protoName, (int) keyValue); 422 return; 423 } else if (keyType == float.class || keyType == Float.class) { 424 mStore.addResult(protoName, (float) keyValue); 425 return; 426 } else if (keyType == long.class || keyType == Long.class) { 427 mStore.addResult(protoName, (long) keyValue); 428 return; 429 } else if (keyType == double.class || keyType == Double.class) { 430 mStore.addResult(protoName, (double) keyValue); 431 return; 432 } else if (keyType == boolean.class || keyType == Boolean.class) { 433 mStore.addResult(protoName, (boolean) keyValue); 434 return; 435 } else if (keyType == byte.class || keyType == Byte.class) { 436 // Infostore does not support byte, convert to int32 and save 437 int intValue = (int) ((byte) keyValue); 438 mStore.addResult(protoName, intValue); 439 return; 440 } else if (keyType == Rational.class) { 441 storeRational((Rational) keyValue, protoName); 442 return; 443 } else if (keyType == Size.class) { 444 storeSize((Size) keyValue, protoName); 445 return; 446 } else if (keyType == SizeF.class) { 447 storeSizeF((SizeF) keyValue, protoName); 448 return; 449 } else if (keyType == Rect.class) { 450 storeRect((Rect) keyValue, protoName); 451 return; 452 } else if (keyType == StreamConfigurationMap.class) { 453 storeStreamConfigurationMap( 454 (StreamConfigurationMap) keyValue, protoName); 455 return; 456 } else if (keyType instanceof ParameterizedType && 457 ((ParameterizedType) keyType).getRawType() == Range.class && 458 ((ParameterizedType) keyType).getActualTypeArguments()[0] == Float.class) { 459 storeRangeFloat((Range<Float>) keyValue, protoName); 460 return; 461 } else if (keyType instanceof ParameterizedType && 462 ((ParameterizedType) keyType).getRawType() == Range.class && 463 ((ParameterizedType) keyType).getActualTypeArguments()[0] == Integer.class) { 464 storeRangeInt((Range<Integer>) keyValue, protoName); 465 return; 466 } else if (keyType instanceof ParameterizedType && 467 ((ParameterizedType) keyType).getRawType() == Range.class && 468 ((ParameterizedType) keyType).getActualTypeArguments()[0] == Long.class) { 469 storeRangeLong((Range<Long>) keyValue, protoName); 470 return; 471 } else if (keyType == ColorSpaceTransform.class) { 472 storeColorSpaceTransform((ColorSpaceTransform) keyValue, protoName); 473 return; 474 } else if (keyType == BlackLevelPattern.class) { 475 storeBlackLevelPattern((BlackLevelPattern) keyValue, protoName); 476 return; 477 } else if (keyType == MultiResolutionStreamConfigurationMap.class) { 478 storeMultiResStreamConfigurationMap( 479 (MultiResolutionStreamConfigurationMap) keyValue, protoName); 480 } else if (keyType == DynamicRangeProfiles.class) { 481 storeDynamicRangeProfiles((DynamicRangeProfiles) keyValue, protoName); 482 } else if (keyType == ColorSpaceProfiles.class) { 483 storeColorSpaceProfiles((ColorSpaceProfiles) keyValue, protoName); 484 } else { 485 Log.w(TAG, "Storing unsupported key type: " + keyType + 486 " for keyName: " + keyName); 487 return; 488 } 489 } 490 storeArrayEntry(Type keyType, Object keyObj, CameraCharacteristics chars)491 private void storeArrayEntry(Type keyType, Object keyObj, 492 CameraCharacteristics chars) throws Exception { 493 String keyName = getKeyName(keyObj); 494 String protoName = keyName.replace('.', '_'); 495 Object keyValue = getKeyValue(chars, keyObj); 496 if (keyValue == null) { 497 return; 498 } 499 500 int arrayLen = Array.getLength(keyValue); 501 if (arrayLen == 0) { 502 return; 503 } 504 Type elmtType = ((GenericArrayType) keyType).getGenericComponentType(); 505 506 if (elmtType == int.class) { 507 mStore.addArrayResult(protoName, (int[]) keyValue); 508 return; 509 } else if (elmtType == float.class) { 510 mStore.addArrayResult(protoName, (float[]) keyValue); 511 return; 512 } else if (elmtType == long.class) { 513 mStore.addArrayResult(protoName, (long[]) keyValue); 514 return; 515 } else if (elmtType == double.class) { 516 mStore.addArrayResult(protoName, (double[]) keyValue); 517 return; 518 } else if (elmtType == boolean.class) { 519 mStore.addArrayResult(protoName, (boolean[]) keyValue); 520 return; 521 } else if (elmtType == byte.class) { 522 // Infostore does not support byte, convert to int32 and save 523 int[] intValues = new int[arrayLen]; 524 for (int i = 0; i < arrayLen; i++) { 525 intValues[i] = (int) ((byte) Array.get(keyValue, i)); 526 } 527 mStore.addArrayResult(protoName, intValues); 528 return; 529 } else if (elmtType == Rational.class) { 530 mStore.startArray(protoName); 531 for (int i = 0; i < arrayLen; i++) { 532 storeRational((Rational) Array.get(keyValue, i), null); 533 } 534 mStore.endArray(); 535 return; 536 } else if (elmtType == Size.class) { 537 mStore.startArray(protoName); 538 for (int i = 0; i < arrayLen; i++) { 539 storeSize((Size) Array.get(keyValue, i), null); 540 } 541 mStore.endArray(); 542 return; 543 } else if (elmtType == Rect.class) { 544 mStore.startArray(protoName); 545 for (int i = 0; i < arrayLen; i++) { 546 storeRect((Rect) Array.get(keyValue, i), null); 547 } 548 mStore.endArray(); 549 return; 550 } else if (elmtType instanceof ParameterizedType && 551 ((ParameterizedType) elmtType).getRawType() == Range.class && 552 ((ParameterizedType) elmtType).getActualTypeArguments()[0] == Integer.class) { 553 mStore.startArray(protoName); 554 for (int i = 0; i < arrayLen; i++) { 555 storeRangeInt((Range<Integer>) Array.get(keyValue, i), null); 556 } 557 mStore.endArray(); 558 return; 559 } else if (elmtType == BlackLevelPattern.class) { 560 mStore.startArray(protoName); 561 for (int i = 0; i < arrayLen; i++) { 562 storeBlackLevelPattern((BlackLevelPattern) Array.get(keyValue, i), null); 563 } 564 mStore.endArray(); 565 return; 566 } else { 567 Log.w(TAG, "Storing unsupported array type: " + elmtType + 568 " for keyName: " + keyName); 569 return; 570 } 571 } 572 storeCameraChars( CameraCharacteristics chars)573 private void storeCameraChars( 574 CameraCharacteristics chars) throws Exception { 575 HashSet<String> charsKeyNames = getAllCharacteristicsKeyNames(); 576 Field[] allFields = chars.getClass().getDeclaredFields(); 577 for (Field field : allFields) { 578 if (Modifier.isPublic(field.getModifiers()) && 579 Modifier.isStatic(field.getModifiers()) && 580 field.getType() == CameraCharacteristics.Key.class && 581 field.getGenericType() instanceof ParameterizedType) { 582 ParameterizedType paramType = (ParameterizedType) field.getGenericType(); 583 Type[] argTypes = paramType.getActualTypeArguments(); 584 if (argTypes.length > 0) { 585 try { 586 Type keyType = argTypes[0]; 587 Object keyObj = field.get(chars); 588 String keyName = getKeyName(keyObj); 589 if (charsKeyNames.contains(keyName)) { 590 if (keyType instanceof GenericArrayType) { 591 storeArrayEntry(keyType, keyObj, chars); 592 } else { 593 storeEntry(keyType, keyObj, chars); 594 } 595 } 596 } catch (IllegalAccessException e) { 597 throw new IllegalStateException( 598 "Access error for field: " + field + ": ", e); 599 } 600 } 601 } 602 } 603 } 604 } 605 606 607 @Override collectDeviceInfo(DeviceInfoStore store)608 protected void collectDeviceInfo(DeviceInfoStore store) throws Exception { 609 store.addResult("profile_480p", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)); 610 store.addResult("profile_720p", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)); 611 store.addResult("profile_1080p", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)); 612 store.addResult("profile_cif", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_CIF)); 613 store.addResult("profile_qcif", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QCIF)); 614 store.addResult("profile_qvga", CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QVGA)); 615 616 CameraManager cameraManager = (CameraManager) 617 getContext().getSystemService(Context.CAMERA_SERVICE); 618 try { 619 String[] cameraIdList = cameraManager.getCameraIdList(); 620 HashMap<String, ArrayList<String>> physicalLogicalIdMap = 621 new HashMap<String, ArrayList<String>>(); 622 store.addResult("num_of_camera", cameraIdList.length); 623 if (cameraIdList.length > 0) { 624 CameraCharacteristicsStorer charsStorer = 625 new CameraCharacteristicsStorer(cameraManager, store); 626 store.startArray("per_camera_info"); 627 for (int i = 0; i < cameraIdList.length; i++) { 628 charsStorer.storeCameraInfo(cameraIdList[i]); 629 630 // Get the physical camera ids 631 CameraCharacteristics ch = cameraManager.getCameraCharacteristics( 632 cameraIdList[i]); 633 for (String physicalId : ch.getPhysicalCameraIds()) { 634 if (physicalLogicalIdMap.get(physicalId) == null) { 635 physicalLogicalIdMap.put(physicalId, new ArrayList<String>()); 636 } 637 physicalLogicalIdMap.get(physicalId).add(cameraIdList[i]); 638 } 639 } 640 store.endArray(); // per_camera_info 641 642 // Store characteristics for hidden physical camera ids 643 for (int i = 0; i < cameraIdList.length; ++i) { 644 physicalLogicalIdMap.remove(cameraIdList[i]); 645 } 646 if (physicalLogicalIdMap.size() > 0) { 647 store.addResult("num_of_hidden_physical_camera", physicalLogicalIdMap.size()); 648 store.startArray("per_hidden_physical_camera_info"); 649 for (String physicalId : physicalLogicalIdMap.keySet()) { 650 charsStorer.storePhysicalCameraInfo(physicalId, 651 physicalLogicalIdMap.get(physicalId)); 652 } 653 store.endArray(); // per_hidden_physical_camera_info 654 } 655 } 656 } catch (CameraAccessException e) { 657 Log.e(TAG, 658 "Unable to get camera camera ID list, error: " 659 + e.getMessage()); 660 } 661 } 662 663 /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ 664 * The key entries below this point are generated from metadata 665 * definitions in /system/media/camera/docs. Do not modify by hand or 666 * modify the comment blocks at the start or end. 667 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/ 668 getAllCharacteristicsKeyNames()669 private static HashSet<String> getAllCharacteristicsKeyNames() { 670 HashSet<String> charsKeyNames = new HashSet<String>(); 671 charsKeyNames.add(CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES.getName()); 672 charsKeyNames.add(CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES.getName()); 673 charsKeyNames.add(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES.getName()); 674 charsKeyNames.add(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES.getName()); 675 charsKeyNames.add(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE.getName()); 676 charsKeyNames.add(CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP.getName()); 677 charsKeyNames.add(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES.getName()); 678 charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS.getName()); 679 charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES.getName()); 680 charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES.getName()); 681 charsKeyNames.add(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES.getName()); 682 charsKeyNames.add(CameraCharacteristics.CONTROL_MAX_REGIONS_AE.getName()); 683 charsKeyNames.add(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB.getName()); 684 charsKeyNames.add(CameraCharacteristics.CONTROL_MAX_REGIONS_AF.getName()); 685 charsKeyNames.add(CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE.getName()); 686 charsKeyNames.add(CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE.getName()); 687 charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_MODES.getName()); 688 charsKeyNames.add(CameraCharacteristics.CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE.getName()); 689 charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_CAPABILITIES.getName()); 690 charsKeyNames.add(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE.getName()); 691 charsKeyNames.add(CameraCharacteristics.CONTROL_AVAILABLE_SETTINGS_OVERRIDES.getName()); 692 charsKeyNames.add(CameraCharacteristics.CONTROL_AUTOFRAMING_AVAILABLE.getName()); 693 charsKeyNames.add(CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES.getName()); 694 charsKeyNames.add(CameraCharacteristics.FLASH_INFO_AVAILABLE.getName()); 695 charsKeyNames.add(CameraCharacteristics.FLASH_INFO_STRENGTH_MAXIMUM_LEVEL.getName()); 696 charsKeyNames.add(CameraCharacteristics.FLASH_INFO_STRENGTH_DEFAULT_LEVEL.getName()); 697 charsKeyNames.add(CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES.getName()); 698 charsKeyNames.add(CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES.getName()); 699 charsKeyNames.add(CameraCharacteristics.LENS_FACING.getName()); 700 charsKeyNames.add(CameraCharacteristics.LENS_POSE_REFERENCE.getName()); 701 charsKeyNames.add(CameraCharacteristics.LENS_DISTORTION_MAXIMUM_RESOLUTION.getName()); 702 charsKeyNames.add(CameraCharacteristics.LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION.getName()); 703 charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES.getName()); 704 charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_FILTER_DENSITIES.getName()); 705 charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS.getName()); 706 charsKeyNames.add(CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION.getName()); 707 charsKeyNames.add(CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE.getName()); 708 charsKeyNames.add(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE.getName()); 709 charsKeyNames.add(CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION.getName()); 710 charsKeyNames.add(CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES.getName()); 711 charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW.getName()); 712 charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC.getName()); 713 charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING.getName()); 714 charsKeyNames.add(CameraCharacteristics.REQUEST_MAX_NUM_INPUT_STREAMS.getName()); 715 charsKeyNames.add(CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH.getName()); 716 charsKeyNames.add(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT.getName()); 717 charsKeyNames.add(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES.getName()); 718 charsKeyNames.add(CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES.getName()); 719 charsKeyNames.add(CameraCharacteristics.REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE.getName()); 720 charsKeyNames.add(CameraCharacteristics.REQUEST_AVAILABLE_COLOR_SPACE_PROFILES.getName()); 721 charsKeyNames.add(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM.getName()); 722 charsKeyNames.add(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP.getName()); 723 charsKeyNames.add(CameraCharacteristics.SCALER_CROPPING_TYPE.getName()); 724 charsKeyNames.add(CameraCharacteristics.SCALER_MANDATORY_STREAM_COMBINATIONS.getName()); 725 charsKeyNames.add(CameraCharacteristics.SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS.getName()); 726 charsKeyNames.add(CameraCharacteristics.SCALER_AVAILABLE_ROTATE_AND_CROP_MODES.getName()); 727 charsKeyNames.add(CameraCharacteristics.SCALER_DEFAULT_SECURE_IMAGE_SIZE.getName()); 728 charsKeyNames.add(CameraCharacteristics.SCALER_MULTI_RESOLUTION_STREAM_CONFIGURATION_MAP.getName()); 729 charsKeyNames.add(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION.getName()); 730 charsKeyNames.add(CameraCharacteristics.SCALER_MANDATORY_MAXIMUM_RESOLUTION_STREAM_COMBINATIONS.getName()); 731 charsKeyNames.add(CameraCharacteristics.SCALER_MANDATORY_TEN_BIT_OUTPUT_STREAM_COMBINATIONS.getName()); 732 charsKeyNames.add(CameraCharacteristics.SCALER_MANDATORY_PREVIEW_STABILIZATION_OUTPUT_STREAM_COMBINATIONS.getName()); 733 charsKeyNames.add(CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES.getName()); 734 charsKeyNames.add(CameraCharacteristics.SCALER_MANDATORY_USE_CASE_STREAM_COMBINATIONS.getName()); 735 charsKeyNames.add(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1.getName()); 736 charsKeyNames.add(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2.getName()); 737 charsKeyNames.add(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1.getName()); 738 charsKeyNames.add(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2.getName()); 739 charsKeyNames.add(CameraCharacteristics.SENSOR_COLOR_TRANSFORM1.getName()); 740 charsKeyNames.add(CameraCharacteristics.SENSOR_COLOR_TRANSFORM2.getName()); 741 charsKeyNames.add(CameraCharacteristics.SENSOR_FORWARD_MATRIX1.getName()); 742 charsKeyNames.add(CameraCharacteristics.SENSOR_FORWARD_MATRIX2.getName()); 743 charsKeyNames.add(CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN.getName()); 744 charsKeyNames.add(CameraCharacteristics.SENSOR_MAX_ANALOG_SENSITIVITY.getName()); 745 charsKeyNames.add(CameraCharacteristics.SENSOR_ORIENTATION.getName()); 746 charsKeyNames.add(CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES.getName()); 747 charsKeyNames.add(CameraCharacteristics.SENSOR_OPTICAL_BLACK_REGIONS.getName()); 748 charsKeyNames.add(CameraCharacteristics.SENSOR_READOUT_TIMESTAMP.getName()); 749 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE.getName()); 750 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE.getName()); 751 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT.getName()); 752 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE.getName()); 753 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION.getName()); 754 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE.getName()); 755 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE.getName()); 756 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL.getName()); 757 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE.getName()); 758 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_LENS_SHADING_APPLIED.getName()); 759 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE.getName()); 760 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION.getName()); 761 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION.getName()); 762 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION.getName()); 763 charsKeyNames.add(CameraCharacteristics.SENSOR_INFO_BINNING_FACTOR.getName()); 764 charsKeyNames.add(CameraCharacteristics.SHADING_AVAILABLE_MODES.getName()); 765 charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES.getName()); 766 charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT.getName()); 767 charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES.getName()); 768 charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES.getName()); 769 charsKeyNames.add(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES.getName()); 770 charsKeyNames.add(CameraCharacteristics.TONEMAP_MAX_CURVE_POINTS.getName()); 771 charsKeyNames.add(CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES.getName()); 772 charsKeyNames.add(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL.getName()); 773 charsKeyNames.add(CameraCharacteristics.INFO_VERSION.getName()); 774 charsKeyNames.add(CameraCharacteristics.INFO_DEVICE_STATE_SENSOR_ORIENTATION_MAP.getName()); 775 charsKeyNames.add(CameraCharacteristics.SYNC_MAX_LATENCY.getName()); 776 charsKeyNames.add(CameraCharacteristics.REPROCESS_MAX_CAPTURE_STALL.getName()); 777 charsKeyNames.add(CameraCharacteristics.DEPTH_DEPTH_IS_EXCLUSIVE.getName()); 778 charsKeyNames.add(CameraCharacteristics.LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE.getName()); 779 charsKeyNames.add(CameraCharacteristics.DISTORTION_CORRECTION_AVAILABLE_MODES.getName()); 780 charsKeyNames.add(CameraCharacteristics.AUTOMOTIVE_LOCATION.getName()); 781 charsKeyNames.add(CameraCharacteristics.AUTOMOTIVE_LENS_FACING.getName()); 782 783 return charsKeyNames; 784 } 785 786 /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ 787 * End generated code 788 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/ 789 } 790