Home | History | Annotate | Download | only in portability
      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 com.android.ex.camera2.portability;
     18 
     19 import com.android.ex.camera2.portability.debug.Log;
     20 
     21 import java.util.ArrayList;
     22 import java.util.EnumSet;
     23 import java.util.HashSet;
     24 import java.util.List;
     25 import java.util.Locale;
     26 import java.util.Set;
     27 import java.util.TreeSet;
     28 
     29 /**
     30  * This class holds all the static information of a camera's capabilities.
     31  * <p>
     32  * The design of this class is thread-safe and can be passed around regardless
     33  * of which thread using it.
     34  * </p>
     35  */
     36 public class CameraCapabilities {
     37 
     38     private static Log.Tag TAG = new Log.Tag("CamCapabs");
     39 
     40     /** Zoom ratio used for seeing sensor's full field of view. */
     41     protected static final float ZOOM_RATIO_UNZOOMED = 1.0f;
     42 
     43     /* All internal states are declared final and should be thread-safe. */
     44 
     45     protected final ArrayList<int[]> mSupportedPreviewFpsRange = new ArrayList<int[]>();
     46     protected final ArrayList<Size> mSupportedPreviewSizes = new ArrayList<Size>();
     47     protected final TreeSet<Integer> mSupportedPreviewFormats = new TreeSet<Integer>();
     48     protected final ArrayList<Size> mSupportedVideoSizes = new ArrayList<Size>();
     49     protected final ArrayList<Size> mSupportedPhotoSizes = new ArrayList<Size>();
     50     protected final TreeSet<Integer> mSupportedPhotoFormats = new TreeSet<Integer>();
     51     protected final EnumSet<SceneMode> mSupportedSceneModes = EnumSet.noneOf(SceneMode.class);
     52     protected final EnumSet<FlashMode> mSupportedFlashModes = EnumSet.noneOf(FlashMode.class);
     53     protected final EnumSet<FocusMode> mSupportedFocusModes = EnumSet.noneOf(FocusMode.class);
     54     protected final EnumSet<WhiteBalance> mSupportedWhiteBalances =
     55             EnumSet.noneOf(WhiteBalance.class);
     56     protected final EnumSet<Feature> mSupportedFeatures = EnumSet.noneOf(Feature.class);
     57     protected Size mPreferredPreviewSizeForVideo;
     58     protected int mMinExposureCompensation;
     59     protected int mMaxExposureCompensation;
     60     protected float mExposureCompensationStep;
     61     protected int mMaxNumOfFacesSupported;
     62     protected int mMaxNumOfFocusAreas;
     63     protected int mMaxNumOfMeteringArea;
     64     protected float mMaxZoomRatio;
     65     protected float mHorizontalViewAngle;
     66     protected float mVerticalViewAngle;
     67     private final Stringifier mStringifier;
     68 
     69     /**
     70      * Focus modes.
     71      */
     72     public enum FocusMode {
     73         /**
     74          * Continuous auto focus mode intended for taking pictures.
     75          * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_AUTO}.
     76          */
     77         AUTO,
     78         /**
     79          * Continuous auto focus mode intended for taking pictures.
     80          * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_CONTINUOUS_PICTURE}.
     81          */
     82         CONTINUOUS_PICTURE,
     83         /**
     84          * Continuous auto focus mode intended for video recording.
     85          * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_CONTINUOUS_VIDEO}.
     86          */
     87         CONTINUOUS_VIDEO,
     88         /**
     89          * Extended depth of field (EDOF).
     90          * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_EDOF}.
     91          */
     92         EXTENDED_DOF,
     93         /**
     94          * Focus is fixed.
     95          * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_FIXED}.
     96          */
     97         FIXED,
     98         /**
     99          * Focus is set at infinity.
    100          * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_INFINITY}.
    101          */
    102         // TODO: Unsupported on API 2
    103         INFINITY,
    104         /**
    105          * Macro (close-up) focus mode.
    106          * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_MACRO}.
    107          */
    108         MACRO,
    109     }
    110 
    111     /**
    112      * Flash modes.
    113      */
    114     public enum FlashMode {
    115         /**
    116          * No flash.
    117          */
    118         NO_FLASH,
    119         /**
    120          * Flash will be fired automatically when required.
    121          * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}.
    122          */
    123         AUTO,
    124         /**
    125          * Flash will not be fired.
    126          * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}.
    127          */
    128         OFF,
    129         /**
    130          * Flash will always be fired during snapshot.
    131          * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_ON}.
    132          */
    133         ON,
    134         /**
    135          * Constant emission of light during preview, auto-focus and snapshot.
    136          * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_TORCH}.
    137          */
    138         TORCH,
    139         /**
    140          * Flash will be fired in red-eye reduction mode.
    141          * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_RED_EYE}.
    142          */
    143         RED_EYE,
    144     }
    145 
    146     /**
    147      * Scene modes.
    148      */
    149     public enum SceneMode {
    150         /**
    151          * No supported scene mode.
    152          */
    153         NO_SCENE_MODE,
    154         /**
    155          * Scene mode is off.
    156          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_AUTO}.
    157          */
    158         AUTO,
    159         /**
    160          * Take photos of fast moving objects.
    161          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_ACTION}.
    162          */
    163         ACTION,
    164         /**
    165          * Applications are looking for a barcode.
    166          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_BARCODE}.
    167          */
    168         BARCODE,
    169         /**
    170          * Take pictures on the beach.
    171          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_BEACH}.
    172          */
    173         BEACH,
    174         /**
    175          * Capture the naturally warm color of scenes lit by candles.
    176          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_CANDLELIGHT}.
    177          */
    178         CANDLELIGHT,
    179         /**
    180          * For shooting firework displays.
    181          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_FIREWORKS}.
    182          */
    183         FIREWORKS,
    184         /**
    185          * Capture a scene using high dynamic range imaging techniques.
    186          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_HDR}.
    187          */
    188         // Note: Supported as a vendor tag on the Camera2 API for some LEGACY devices.
    189         HDR,
    190         /**
    191          * Take pictures on distant objects.
    192          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_LANDSCAPE}.
    193          */
    194         LANDSCAPE,
    195         /**
    196          * Take photos at night.
    197          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_NIGHT}.
    198          */
    199         NIGHT,
    200         /**
    201          * Take people pictures at night.
    202          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_NIGHT_PORTRAIT}.
    203          */
    204         // TODO: Unsupported on API 2
    205         NIGHT_PORTRAIT,
    206         /**
    207          * Take indoor low-light shot.
    208          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_PARTY}.
    209          */
    210         PARTY,
    211         /**
    212          * Take people pictures.
    213          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_PORTRAIT}.
    214          */
    215         PORTRAIT,
    216         /**
    217          * Take pictures on the snow.
    218          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_SNOW}.
    219          */
    220         SNOW,
    221         /**
    222          * Take photos of fast moving objects.
    223          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_SPORTS}.
    224          */
    225         SPORTS,
    226         /**
    227          * Avoid blurry pictures (for example, due to hand shake).
    228          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_STEADYPHOTO}.
    229          */
    230         STEADYPHOTO,
    231         /**
    232          * Take sunset photos.
    233          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_SUNSET}.
    234          */
    235         SUNSET,
    236         /**
    237          * Take photos in a theater.
    238          * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_THEATRE}.
    239          */
    240         THEATRE,
    241     }
    242 
    243     /**
    244      * White blances.
    245      */
    246     public enum WhiteBalance {
    247         /**
    248          * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_AUTO}.
    249          */
    250         AUTO,
    251         /**
    252          * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_CLOUDY_DAYLIGHT}.
    253          */
    254         CLOUDY_DAYLIGHT,
    255         /**
    256          * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_DAYLIGHT}.
    257          */
    258         DAYLIGHT,
    259         /**
    260          * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_FLUORESCENT}.
    261          */
    262         FLUORESCENT,
    263         /**
    264          * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_INCANDESCENT}.
    265          */
    266         INCANDESCENT,
    267         /**
    268          * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_SHADE}.
    269          */
    270         SHADE,
    271         /**
    272          * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_TWILIGHT}.
    273          */
    274         TWILIGHT,
    275         /**
    276          * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_WARM_FLUORESCENT}.
    277          */
    278         WARM_FLUORESCENT,
    279     }
    280 
    281     /**
    282      * Features.
    283      */
    284     public enum Feature {
    285         /**
    286          * Support zoom-related methods.
    287          */
    288         ZOOM,
    289         /**
    290          * Support for photo capturing during video recording.
    291          */
    292         VIDEO_SNAPSHOT,
    293         /**
    294          * Support for focus area settings.
    295          */
    296         FOCUS_AREA,
    297         /**
    298          * Support for metering area settings.
    299          */
    300         METERING_AREA,
    301         /**
    302          * Support for automatic exposure lock.
    303          */
    304         AUTO_EXPOSURE_LOCK,
    305         /**
    306          * Support for automatic white balance lock.
    307          */
    308         AUTO_WHITE_BALANCE_LOCK,
    309         /**
    310          * Support for video stabilization.
    311          */
    312         VIDEO_STABILIZATION,
    313     }
    314 
    315     /**
    316      * A interface stringifier to convert abstract representations to API
    317      * related string representation.
    318      */
    319     public static class Stringifier {
    320         /**
    321          * Converts the string to hyphen-delimited lowercase for compatibility with multiple APIs.
    322          *
    323          * @param enumCase The name of an enum constant.
    324          * @return The converted string.
    325          */
    326         private static String toApiCase(String enumCase) {
    327             return enumCase.toLowerCase(Locale.US).replaceAll("_", "-");
    328         }
    329 
    330         /**
    331          * Converts the string to underscore-delimited uppercase to match the enum constant names.
    332          *
    333          * @param apiCase An API-related string representation.
    334          * @return The converted string.
    335          */
    336         private static String toEnumCase(String apiCase) {
    337             return apiCase.toUpperCase(Locale.US).replaceAll("-", "_");
    338         }
    339 
    340         /**
    341          * Converts the focus mode to API-related string representation.
    342          *
    343          * @param focus The focus mode to convert.
    344          * @return The string used by the camera framework API to represent the
    345          *         focus mode.
    346          */
    347         public String stringify(FocusMode focus) {
    348             return toApiCase(focus.name());
    349         }
    350 
    351         /**
    352          * Converts the API-related string representation of the focus mode to the
    353          * abstract representation.
    354          *
    355          * @param val The string representation.
    356          * @return The focus mode represented by the input string, or the focus
    357          *         mode with the lowest ordinal if it cannot be converted.
    358          */
    359         public FocusMode focusModeFromString(String val) {
    360             if (val == null) {
    361                 return FocusMode.values()[0];
    362             }
    363             try {
    364                 return FocusMode.valueOf(toEnumCase(val));
    365             } catch (IllegalArgumentException ex) {
    366                 return FocusMode.values()[0];
    367             }
    368         }
    369 
    370         /**
    371          * Converts the flash mode to API-related string representation.
    372          *
    373          * @param flash The focus mode to convert.
    374          * @return The string used by the camera framework API to represent the
    375          *         flash mode.
    376          */
    377         public String stringify(FlashMode flash) {
    378             return toApiCase(flash.name());
    379         }
    380 
    381         /**
    382          * Converts the API-related string representation of the flash mode to the
    383          * abstract representation.
    384          *
    385          * @param val The string representation.
    386          * @return The flash mode represented by the input string, or the flash
    387          *         mode with the lowest ordinal if it cannot be converted.
    388          */
    389         public FlashMode flashModeFromString(String val) {
    390             if (val == null) {
    391                 return FlashMode.values()[0];
    392             }
    393             try {
    394                 return FlashMode.valueOf(toEnumCase(val));
    395             } catch (IllegalArgumentException ex) {
    396                 return FlashMode.values()[0];
    397             }
    398         }
    399 
    400         /**
    401          * Converts the scene mode to API-related string representation.
    402          *
    403          * @param scene The focus mode to convert.
    404          * @return The string used by the camera framework API to represent the
    405          *         scene mode.
    406          */
    407         public String stringify(SceneMode scene) {
    408             return toApiCase(scene.name());
    409         }
    410 
    411         /**
    412          * Converts the API-related string representation of the scene mode to the
    413          * abstract representation.
    414          *
    415          * @param val The string representation.
    416          * @return The scene mode represented by the input string, or the scene
    417          *         mode with the lowest ordinal if it cannot be converted.
    418          */
    419         public SceneMode sceneModeFromString(String val) {
    420             if (val == null) {
    421                 return SceneMode.values()[0];
    422             }
    423             try {
    424                 return SceneMode.valueOf(toEnumCase(val));
    425             } catch (IllegalArgumentException ex) {
    426                 return SceneMode.values()[0];
    427             }
    428         }
    429 
    430         /**
    431          * Converts the white balance to API-related string representation.
    432          *
    433          * @param wb The focus mode to convert.
    434          * @return The string used by the camera framework API to represent the
    435          * white balance.
    436          */
    437         public String stringify(WhiteBalance wb) {
    438             return toApiCase(wb.name());
    439         }
    440 
    441         /**
    442          * Converts the API-related string representation of the white balance to
    443          * the abstract representation.
    444          *
    445          * @param val The string representation.
    446          * @return The white balance represented by the input string, or the
    447          *         white balance with the lowest ordinal if it cannot be
    448          *         converted.
    449          */
    450         public WhiteBalance whiteBalanceFromString(String val) {
    451             if (val == null) {
    452                 return WhiteBalance.values()[0];
    453             }
    454             try {
    455                 return WhiteBalance.valueOf(toEnumCase(val));
    456             } catch (IllegalArgumentException ex) {
    457                 return WhiteBalance.values()[0];
    458             }
    459         }
    460     }
    461 
    462     /**
    463      * Constructor.
    464      * @param stringifier The API-specific stringifier for this instance.
    465      */
    466     CameraCapabilities(Stringifier stringifier) {
    467         mStringifier = stringifier;
    468     }
    469 
    470     /**
    471      * Copy constructor.
    472      * @param src The source instance.
    473      */
    474     public CameraCapabilities(CameraCapabilities src) {
    475         mSupportedPreviewFpsRange.addAll(src.mSupportedPreviewFpsRange);
    476         mSupportedPreviewSizes.addAll(src.mSupportedPreviewSizes);
    477         mSupportedPreviewFormats.addAll(src.mSupportedPreviewFormats);
    478         mSupportedVideoSizes.addAll(src.mSupportedVideoSizes);
    479         mSupportedPhotoSizes.addAll(src.mSupportedPhotoSizes);
    480         mSupportedPhotoFormats.addAll(src.mSupportedPhotoFormats);
    481         mSupportedSceneModes.addAll(src.mSupportedSceneModes);
    482         mSupportedFlashModes.addAll(src.mSupportedFlashModes);
    483         mSupportedFocusModes.addAll(src.mSupportedFocusModes);
    484         mSupportedWhiteBalances.addAll(src.mSupportedWhiteBalances);
    485         mSupportedFeatures.addAll(src.mSupportedFeatures);
    486         mPreferredPreviewSizeForVideo = src.mPreferredPreviewSizeForVideo;
    487         mMaxExposureCompensation = src.mMaxExposureCompensation;
    488         mMinExposureCompensation = src.mMinExposureCompensation;
    489         mExposureCompensationStep = src.mExposureCompensationStep;
    490         mMaxNumOfFacesSupported = src.mMaxNumOfFacesSupported;
    491         mMaxNumOfFocusAreas = src.mMaxNumOfFocusAreas;
    492         mMaxNumOfMeteringArea = src.mMaxNumOfMeteringArea;
    493         mMaxZoomRatio = src.mMaxZoomRatio;
    494         mHorizontalViewAngle = src.mHorizontalViewAngle;
    495         mVerticalViewAngle = src.mVerticalViewAngle;
    496         mStringifier = src.mStringifier;
    497     }
    498 
    499     public float getHorizontalViewAngle() {
    500         return mHorizontalViewAngle;
    501     }
    502 
    503     public float getVerticalViewAngle() {
    504         return mVerticalViewAngle;
    505     }
    506 
    507     /**
    508      * @return the supported picture formats. See {@link android.graphics.ImageFormat}.
    509      */
    510     public Set<Integer> getSupportedPhotoFormats() {
    511         return new TreeSet<Integer>(mSupportedPhotoFormats);
    512     }
    513 
    514     /**
    515      * Gets the supported preview formats.
    516      * @return The supported preview {@link android.graphics.ImageFormat}s.
    517      */
    518     public Set<Integer> getSupportedPreviewFormats() {
    519         return new TreeSet<Integer>(mSupportedPreviewFormats);
    520     }
    521 
    522     /**
    523      * Gets the supported picture sizes.
    524      */
    525     public List<Size> getSupportedPhotoSizes() {
    526         return new ArrayList<Size>(mSupportedPhotoSizes);
    527     }
    528 
    529     /**
    530      * @return The supported preview fps (frame-per-second) ranges. The returned
    531      * list is sorted by maximum fps then minimum fps in a descending order.
    532      * The values are multiplied by 1000.
    533      */
    534     public final List<int[]> getSupportedPreviewFpsRange() {
    535         return new ArrayList<int[]>(mSupportedPreviewFpsRange);
    536     }
    537 
    538     /**
    539      * @return The supported preview sizes. The list is sorted by width then
    540      * height in a descending order.
    541      */
    542     public final List<Size> getSupportedPreviewSizes() {
    543         return new ArrayList<Size>(mSupportedPreviewSizes);
    544     }
    545 
    546     public final Size getPreferredPreviewSizeForVideo() {
    547         return new Size(mPreferredPreviewSizeForVideo);
    548     }
    549 
    550     /**
    551      * @return The supported video frame sizes that can be used by MediaRecorder.
    552      *         The list is sorted by width then height in a descending order.
    553      */
    554     public final List<Size> getSupportedVideoSizes() {
    555         return new ArrayList<Size>(mSupportedVideoSizes);
    556     }
    557 
    558     /**
    559      * @return The supported scene modes.
    560      */
    561     public final Set<SceneMode> getSupportedSceneModes() {
    562         return new HashSet<SceneMode>(mSupportedSceneModes);
    563     }
    564 
    565     /**
    566      * @return Whether the scene mode is supported.
    567      */
    568     public final boolean supports(SceneMode scene) {
    569         return (scene != null && mSupportedSceneModes.contains(scene));
    570     }
    571 
    572     public boolean supports(final CameraSettings settings) {
    573         if (zoomCheck(settings) && exposureCheck(settings) && focusCheck(settings) &&
    574                 flashCheck(settings) && photoSizeCheck(settings) && previewSizeCheck(settings) &&
    575                 videoStabilizationCheck(settings)) {
    576             return true;
    577         }
    578         return false;
    579     }
    580 
    581     /**
    582      * @return The supported flash modes.
    583      */
    584     public final Set<FlashMode> getSupportedFlashModes() {
    585         return new HashSet<FlashMode>(mSupportedFlashModes);
    586     }
    587 
    588     /**
    589      * @return Whether the flash mode is supported.
    590      */
    591     public final boolean supports(FlashMode flash) {
    592         return (flash != null && mSupportedFlashModes.contains(flash));
    593     }
    594 
    595     /**
    596      * @return The supported focus modes.
    597      */
    598     public final Set<FocusMode> getSupportedFocusModes() {
    599         return new HashSet<FocusMode>(mSupportedFocusModes);
    600     }
    601 
    602     /**
    603      * @return Whether the focus mode is supported.
    604      */
    605     public final boolean supports(FocusMode focus) {
    606         return (focus != null && mSupportedFocusModes.contains(focus));
    607     }
    608 
    609     /**
    610      * @return The supported white balanceas.
    611      */
    612     public final Set<WhiteBalance> getSupportedWhiteBalance() {
    613         return new HashSet<WhiteBalance>(mSupportedWhiteBalances);
    614     }
    615 
    616     /**
    617      * @return Whether the white balance is supported.
    618      */
    619     public boolean supports(WhiteBalance wb) {
    620         return (wb != null && mSupportedWhiteBalances.contains(wb));
    621     }
    622 
    623     public final Set<Feature> getSupportedFeature() {
    624         return new HashSet<Feature>(mSupportedFeatures);
    625     }
    626 
    627     public boolean supports(Feature ft) {
    628         return (ft != null && mSupportedFeatures.contains(ft));
    629     }
    630 
    631     /**
    632      * @return The maximal supported zoom ratio.
    633      */
    634     public float getMaxZoomRatio() {
    635         return mMaxZoomRatio;
    636     }
    637 
    638     /**
    639      * @return The min exposure compensation index. The EV is the compensation
    640      * index multiplied by the step value. If unsupported, both this method and
    641      * {@link #getMaxExposureCompensation()} return 0.
    642      */
    643     public final int getMinExposureCompensation() {
    644         return mMinExposureCompensation;
    645     }
    646 
    647     /**
    648      * @return The max exposure compensation index. The EV is the compensation
    649      * index multiplied by the step value. If unsupported, both this method and
    650      * {@link #getMinExposureCompensation()} return 0.
    651      */
    652     public final int getMaxExposureCompensation() {
    653         return mMaxExposureCompensation;
    654     }
    655 
    656     /**
    657      * @return The exposure compensation step. The EV is the compensation index
    658      * multiplied by the step value.
    659      */
    660     public final float getExposureCompensationStep() {
    661         return mExposureCompensationStep;
    662     }
    663 
    664     /**
    665      * @return The max number of faces supported by the face detection. 0 if
    666      * unsupported.
    667      */
    668     public final int getMaxNumOfFacesSupported() {
    669         return mMaxNumOfFacesSupported;
    670     }
    671 
    672     /**
    673      * @return The stringifier used by this instance.
    674      */
    675     public Stringifier getStringifier() {
    676         return mStringifier;
    677     }
    678 
    679     private boolean zoomCheck(final CameraSettings settings) {
    680         final float ratio = settings.getCurrentZoomRatio();
    681         if (!supports(Feature.ZOOM)) {
    682             if (ratio != ZOOM_RATIO_UNZOOMED) {
    683                 Log.v(TAG, "Zoom is not supported");
    684                 return false;
    685             }
    686         } else {
    687             if (settings.getCurrentZoomRatio() > getMaxZoomRatio()) {
    688                 Log.v(TAG, "Zoom ratio is not supported: ratio = " +
    689                         settings.getCurrentZoomRatio());
    690                 return false;
    691             }
    692         }
    693         return true;
    694     }
    695 
    696     private boolean exposureCheck(final CameraSettings settings) {
    697         final int index = settings.getExposureCompensationIndex();
    698         if (index > getMaxExposureCompensation() || index < getMinExposureCompensation()) {
    699             Log.v(TAG, "Exposure compensation index is not supported. Min = " +
    700                     getMinExposureCompensation() + ", max = " + getMaxExposureCompensation() + "," +
    701                     " setting = " + index);
    702             return false;
    703         }
    704         return true;
    705     }
    706 
    707     private boolean focusCheck(final CameraSettings settings) {
    708         FocusMode focusMode = settings.getCurrentFocusMode();
    709         if (!supports(focusMode)) {
    710             if (supports(FocusMode.FIXED)) {
    711                 // Workaround for devices whose templates define defaults they don't really support
    712                 // TODO: Remove workaround (b/17177436)
    713                 Log.w(TAG, "Focus mode not supported... trying FIXED");
    714                 settings.setFocusMode(FocusMode.FIXED);
    715             } else {
    716                 Log.v(TAG, "Focus mode not supported:" +
    717                         (focusMode != null ? focusMode.name() : "null"));
    718                 return false;
    719             }
    720         }
    721         return true;
    722     }
    723 
    724     private boolean flashCheck(final CameraSettings settings) {
    725         FlashMode flashMode = settings.getCurrentFlashMode();
    726         if (!supports(flashMode)) {
    727             Log.v(TAG,
    728                     "Flash mode not supported:" + (flashMode != null ? flashMode.name() : "null"));
    729             return false;
    730         }
    731         return true;
    732     }
    733 
    734     private boolean photoSizeCheck(final CameraSettings settings) {
    735         Size photoSize = settings.getCurrentPhotoSize();
    736         if (mSupportedPhotoSizes.contains(photoSize)) {
    737             return true;
    738         }
    739         Log.v(TAG, "Unsupported photo size:" + photoSize);
    740         return false;
    741     }
    742 
    743     private boolean previewSizeCheck(final CameraSettings settings) {
    744         final Size previewSize = settings.getCurrentPreviewSize();
    745         if (mSupportedPreviewSizes.contains(previewSize)) {
    746             return true;
    747         }
    748         Log.v(TAG, "Unsupported preview size:" + previewSize);
    749         return false;
    750     }
    751 
    752     private boolean videoStabilizationCheck(final CameraSettings settings) {
    753         if (!settings.isVideoStabilizationEnabled() || supports(Feature.VIDEO_STABILIZATION)) {
    754             return true;
    755         }
    756         Log.v(TAG, "Video stabilization is not supported");
    757         return false;
    758     }
    759 }
    760