Home | History | Annotate | Download | only in devcamera
      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