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