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