1 /* 2 * Copyright (C) 2016 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.devcamera; 17 18 import android.app.Activity; 19 import android.content.Context; 20 import android.graphics.ImageFormat; 21 import android.graphics.Rect; 22 import android.graphics.SurfaceTexture; 23 import android.hardware.camera2.CameraCharacteristics; 24 import android.hardware.camera2.CameraManager; 25 import android.hardware.camera2.CameraMetadata; 26 import android.hardware.camera2.CaptureRequest; 27 import android.hardware.camera2.CaptureResult; 28 import android.hardware.camera2.params.StreamConfigurationMap; 29 import android.os.Build; 30 import android.util.DisplayMetrics; 31 import android.util.Log; 32 import android.util.Range; 33 import android.util.Size; 34 import android.util.SizeF; 35 import android.view.SurfaceHolder; 36 import android.view.WindowManager; 37 38 public class CameraDeviceReport { 39 private static final String TAG = "DevCamera_INFO"; 40 41 // Note: we actually need the activity to get window information 42 public static void printReport(Activity activity, boolean firstCameraOnly) { 43 printDisplayInfo(activity); 44 printCameraSystemInfo(activity, firstCameraOnly); 45 } 46 47 /** 48 * Print out information about all cameras. 49 */ 50 private static void printCameraSystemInfo(Activity activity, boolean firstCameraOnly) { 51 CameraManager cameraMgr = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); // "camera" 52 String[] cameralist; 53 try { 54 cameralist = cameraMgr.getCameraIdList(); 55 Log.v(TAG, "Number of cameras:" + cameralist.length); 56 } catch (Exception e) { 57 Log.e(TAG, "Could not get camera ID list: "+e); 58 return; 59 } 60 for (String cameraId : cameralist) { 61 printCameraInfo(cameraMgr, cameraId); 62 if (firstCameraOnly) { 63 break; 64 } 65 } 66 } 67 68 /** 69 * Print out information about a specific camera. 70 */ 71 private static void printCameraInfo(CameraManager manager, String id) { 72 Log.v(TAG, "============= CAMERA " + id + " INFO ============="); 73 74 CameraCharacteristics p; 75 try { 76 p = manager.getCameraCharacteristics(id); 77 } catch (Exception e) { 78 Log.e(TAG, "Could not get getCameraCharacteristics"); 79 return; 80 } 81 // dumpsys media.camera 82 83 // Print out various CameraCharacteristics. 84 Rect size = p.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); 85 if (size != null) { 86 Log.v(TAG, "SENSOR_INFO_ACTIVE_ARRAY_SIZE: " 87 + size.width() + "x" + size.height()); 88 } else { 89 Log.v(TAG, "SENSOR_INFO_ACTIVE_ARRAY_SIZE: null"); 90 } 91 92 Size size2 = p.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE); 93 Log.v(TAG, "SENSOR_INFO_PIXEL_ARRAY_SIZE: " + size2.getWidth() + "x" + size2.getHeight()); 94 95 SizeF size3 = p.get(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE); 96 Log.v(TAG, "SENSOR_INFO_PHYSICAL_SIZE: " + size3.getWidth() + "x" + size3.getHeight()); 97 98 99 int sensorOrientation = p.get(CameraCharacteristics.SENSOR_ORIENTATION); 100 Log.v(TAG, "SENSOR_ORIENTATION: " + sensorOrientation); 101 102 Log.v(TAG, "SENSOR_INFO_TIMESTAMP_SOURCE: " + 103 getTimestampSourceName(p.get(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE))); 104 105 Log.v(TAG, "LENS_INFO_FOCUS_DISTANCE_CALIBRATION: " + 106 getFocusDistanceCalibrationName(p.get(CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION))); 107 108 int[] faceModes = p.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES); 109 Log.v(TAG, "STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES: "); 110 for (int i = 0; i < faceModes.length; i++) { 111 switch (faceModes[i]) { 112 case CameraCharacteristics.STATISTICS_FACE_DETECT_MODE_OFF: 113 Log.v(TAG, " STATISTICS_FACE_DETECT_MODE_OFF"); 114 break; 115 case CameraCharacteristics.STATISTICS_FACE_DETECT_MODE_SIMPLE: 116 Log.v(TAG, " STATISTICS_FACE_DETECT_MODE_SIMPLE"); 117 break; 118 case CameraCharacteristics.STATISTICS_FACE_DETECT_MODE_FULL: 119 Log.v(TAG, " STATISTICS_FACE_DETECT_MODE_FULL"); 120 break; 121 default: 122 Log.v(TAG, " STATISTICS_FACE_DETECT_MODE_? (unknown)"); 123 } 124 } 125 126 Log.v(TAG, "STATISTICS_INFO_MAX_FACE_COUNT: " + p.get(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT)); 127 128 Log.v(TAG, "REQUEST_PIPELINE_MAX_DEPTH: " 129 + p.get(CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH)); 130 131 Log.v(TAG, "REQUEST_MAX_NUM_OUTPUT_RAW: " 132 + p.get(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW)); 133 Log.v(TAG, "REQUEST_MAX_NUM_OUTPUT_PROC: " 134 + p.get(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC)); 135 Log.v(TAG, "REQUEST_MAX_NUM_OUTPUT_PROC_STALLING: " 136 + p.get(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING)); 137 138 Log.v(TAG, "EDGE_AVAILABLE_EDGE_MODES: " 139 + intsToString(p.get(CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES))); 140 141 Log.v(TAG, "NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES: " 142 + intsToString(p.get(CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES))); 143 144 Log.v(TAG, "REQUEST_MAX_NUM_OUTPUT_PROC_STALLING: " 145 + p.get(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING)); 146 147 148 // REQUEST_AVAILABLE_CAPABILITIES 149 boolean mHasReprocessing = false; 150 { 151 Log.v(TAG, "CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES:"); 152 for (int item : p.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)) { 153 Log.v(TAG, " " + item + " = " + getCapabilityName(item)); 154 if (item == 4 || item == 7) { 155 mHasReprocessing = true; 156 } 157 } 158 } 159 160 StreamConfigurationMap map = p.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 161 { 162 int[] formats = map.getOutputFormats(); 163 Log.v(TAG, "number of output formats: " + formats.length); 164 for (int i = 0; i < formats.length; i++) { 165 Log.v(TAG, "output sizes for format " + formats[i] + 166 " = ImageFormat." + getFormatName(formats[i]) + " = " + 167 ImageFormat.getBitsPerPixel(formats[i]) + " bits per pixel."); 168 Size[] sizes = map.getOutputSizes(formats[i]); 169 if (sizes != null) { 170 Log.v(TAG, " Size Stall duration Min frame duration"); 171 for (int j = 0; j < sizes.length; j++) { 172 Log.v(TAG, String.format(" %10s %7d ms %7d ms \n", 173 sizes[j].toString(), 174 map.getOutputStallDuration(formats[i], sizes[j]) / 1000000, 175 map.getOutputMinFrameDuration(formats[i], sizes[j]) / 1000000 176 )); 177 } 178 } 179 } 180 } 181 182 if (mHasReprocessing) { 183 int[] formats = map.getInputFormats(); 184 Log.v(TAG, "number of input formats: " + formats.length); 185 for (int i = 0; i < formats.length; i++) { 186 Size[] sizes = map.getInputSizes(formats[i]); 187 Log.v(TAG, "input sizes for format " + formats[i] + " = ImageFormat." 188 + getFormatName(formats[i]) + " are: " + sizesToString(sizes)); 189 } 190 } 191 192 { 193 Size[] sizes = map.getOutputSizes(SurfaceHolder.class); 194 Log.v(TAG, "output sizes for SurfaceHolder.class are: " + sizesToString(sizes)); 195 } 196 197 { 198 Size[] sizes = map.getOutputSizes(SurfaceTexture.class); 199 Log.v(TAG, "output sizes for SurfaceTexture.class are: " + sizesToString(sizes)); 200 } 201 202 // JPEG thumbnail sizes 203 { 204 Size[] sizes = p.get(CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES); 205 Log.v(TAG, "JPEG thumbnail sizes: " + sizesToString(sizes)); 206 } 207 208 // REQUEST HARDWARE LEVEL 209 { 210 int level = p.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); 211 Log.v(TAG, "CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL: " + getHardwareLevelName(level)); 212 } 213 214 215 // REQUEST CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES 216 { 217 Log.v(TAG, "CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES:"); 218 for (Range<Integer> item : p.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES)) { 219 Log.v(TAG, " " + item); 220 } 221 } 222 // SENSOR_INFO_EXPOSURE_TIME_RANGE 223 { 224 Range<Long> rr = p.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE); 225 Log.v(TAG, "CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE: " + rr); 226 } 227 228 229 // CAPTURE REQUEST KEYS 230 { 231 String keys = ""; 232 for (CaptureRequest.Key key : p.getAvailableCaptureRequestKeys()) { 233 keys += key.getName() + " "; 234 } 235 Log.v(TAG, "CameraCharacteristics.getAvailableCaptureRequestKeys() = " + keys); 236 } 237 238 // CAPTURE RESULT KEYS 239 { 240 String keys = ""; 241 for (CaptureResult.Key key : p.getAvailableCaptureResultKeys()) { 242 keys += key.getName() + " "; 243 } 244 Log.v(TAG, "CameraCharacteristics.getAvailableCaptureResultKeys() = " + keys); 245 } 246 247 } 248 249 public static String sizesToString(Size[] sizes) { 250 String result = ""; 251 if (sizes != null) { 252 for (int j = 0; j < sizes.length; j++) { 253 result += sizes[j].toString() + " "; 254 } 255 } 256 return result; 257 } 258 259 public static String intsToString(int[] modes) { 260 String result = ""; 261 if (modes != null) { 262 for (int j = 0; j < modes.length; j++) { 263 result += modes[j] + " "; 264 } 265 } 266 return result; 267 } 268 269 public static String getTimestampSourceName(Integer level) { 270 if (level == null) return "null"; 271 switch (level) { 272 case CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME: 273 return "SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME"; 274 case CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN: 275 return "SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN"; 276 } 277 return "Unknown"; 278 } 279 280 public static String getFocusDistanceCalibrationName(Integer level) { 281 if (level == null) return "null"; 282 switch (level) { 283 case CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE: 284 return "LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE"; 285 case CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED: 286 return "LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED"; 287 case CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED: 288 return "LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED"; 289 } 290 return "Unknown"; 291 } 292 293 public static String getCapabilityName(int format) { 294 switch (format) { 295 case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE: 296 return "REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE"; 297 case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR: 298 return "REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR"; 299 case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING: 300 return "REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING"; 301 case CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW: 302 return "REQUEST_AVAILABLE_CAPABILITIES_RAW"; 303 case 4: 304 return "REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING"; 305 case 5: 306 return "REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS"; 307 case 6: 308 return "REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE"; 309 case 7: 310 return "REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING"; 311 case 8: 312 return "REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT"; 313 } 314 return "Unknown"; 315 } 316 317 public static String getHardwareLevelName(int level) { 318 switch (level) { 319 case CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL: 320 return "INFO_SUPPORTED_HARDWARE_LEVEL_FULL"; 321 case CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED: 322 return "INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED"; 323 case CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY: 324 return "INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY"; 325 } 326 return "Unknown"; 327 } 328 329 330 public static String getFormatName(int format) { 331 switch (format) { 332 // Android M 333 //case ImageFormat.PRIVATE: 334 // return "PRIVATE"; 335 // Android L 336 case ImageFormat.JPEG: 337 return "JPEG"; 338 case ImageFormat.RGB_565: 339 return "RGB_565"; 340 case ImageFormat.NV16: 341 return "NV16"; 342 case ImageFormat.YUY2: 343 return "YUY2"; 344 case ImageFormat.YV12: 345 return "YV12"; 346 case ImageFormat.NV21: 347 return "NV21"; 348 case ImageFormat.YUV_420_888: 349 return "YUV_420_888"; 350 case ImageFormat.RAW_SENSOR: 351 return "RAW_SENSOR"; 352 case ImageFormat.RAW10: 353 return "RAW10"; 354 } 355 return "Unknown"; 356 } 357 358 359 /** 360 * Print out various information about the device display. 361 */ 362 private static void printDisplayInfo(Activity activity) { 363 Log.v(TAG, "============= DEVICE INFO ============="); 364 Log.v(TAG, "Build.DEVICE = " + Build.DEVICE); 365 Log.v(TAG, "Build.FINGERPRINT = " + Build.FINGERPRINT); 366 Log.v(TAG, "Build.BRAND = " + Build.BRAND); 367 Log.v(TAG, "Build.MODEL = " + Build.MODEL); 368 Log.v(TAG, "Build.PRODUCT = " + Build.PRODUCT); 369 Log.v(TAG, "Build.MANUFACTURER = " + Build.MANUFACTURER); 370 Log.v(TAG, "Build.VERSION.CODENAME = " + Build.VERSION.CODENAME); 371 Log.v(TAG, "Build.VERSION.SDK_INT = " + Build.VERSION.SDK_INT); 372 373 Log.v(TAG, "============= DEVICE DISPLAY INFO ============="); 374 WindowManager windowMgr = activity.getWindowManager(); 375 376 // Nexus 5 is 360dp * 567dp 377 // Each dp is 3 hardware pixels 378 Log.v(TAG, "screen width dp = " + activity.getResources().getConfiguration().screenWidthDp); 379 Log.v(TAG, "screen height dp = " + activity.getResources().getConfiguration().screenHeightDp); 380 381 DisplayMetrics metrics = new DisplayMetrics(); 382 // With chrome subtracted. 383 windowMgr.getDefaultDisplay().getMetrics(metrics); 384 Log.v(TAG, "screen width pixels = " + metrics.widthPixels); 385 Log.v(TAG, "screen height pixels = " + metrics.heightPixels); 386 // Native. 387 windowMgr.getDefaultDisplay().getRealMetrics(metrics); 388 Log.v(TAG, "real screen width pixels = " + metrics.widthPixels); 389 Log.v(TAG, "real screen height pixels = " + metrics.heightPixels); 390 391 Log.v(TAG, "refresh rate = " + windowMgr.getDefaultDisplay().getRefreshRate() + " Hz"); 392 } 393 394 395 396 } 397