CameraCapabilities.java revision f2b5a976bb1c30f83682a996ce9289a973c88784
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        mMaxZoomIndex = src.mMaxZoomIndex;
492        mZoomRatioList.addAll(src.mZoomRatioList);
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    // We'll replace these old style methods with new ones.
639    @Deprecated
640    public int getMaxZoomIndex() {
641        return mMaxZoomIndex;
642    }
643
644    @Deprecated
645    public List<Integer> getZoomRatioList() {
646        return new ArrayList<Integer>(mZoomRatioList);
647    }
648
649    /**
650     * @return The min exposure compensation index. The EV is the compensation
651     * index multiplied by the step value. If unsupported, both this method and
652     * {@link #getMaxExposureCompensation()} return 0.
653     */
654    public final int getMinExposureCompensation() {
655        return mMinExposureCompensation;
656    }
657
658    /**
659     * @return The max exposure compensation index. The EV is the compensation
660     * index multiplied by the step value. If unsupported, both this method and
661     * {@link #getMinExposureCompensation()} return 0.
662     */
663    public final int getMaxExposureCompensation() {
664        return mMaxExposureCompensation;
665    }
666
667    /**
668     * @return The exposure compensation step. The EV is the compensation index
669     * multiplied by the step value.
670     */
671    public final float getExposureCompensationStep() {
672        return mExposureCompensationStep;
673    }
674
675    /**
676     * @return The max number of faces supported by the face detection. 0 if
677     * unsupported.
678     */
679    public final int getMaxNumOfFacesSupported() {
680        return mMaxNumOfFacesSupported;
681    }
682
683    /**
684     * @return The stringifier used by this instance.
685     */
686    public Stringifier getStringifier() {
687        return mStringifier;
688    }
689
690    private boolean zoomCheck(final CameraSettings settings) {
691        final float ratio = settings.getCurrentZoomRatio();
692        final int index = settings.getCurrentZoomIndex();
693        if (!supports(Feature.ZOOM)) {
694            if (ratio != 1.0f || index != 0) {
695                Log.v(TAG, "Zoom is not supported");
696                return false;
697            }
698        } else {
699            if (settings.getCurrentZoomRatio() > getMaxZoomRatio() ||
700                    index > getMaxZoomIndex()) {
701                Log.v(TAG, "Zoom ratio is not supported: ratio = " +
702                        settings.getCurrentZoomRatio() + ", index = " + index);
703                return false;
704            }
705        }
706        return true;
707    }
708
709    private boolean exposureCheck(final CameraSettings settings) {
710        final int index = settings.getExposureCompensationIndex();
711        if (index > getMaxExposureCompensation() || index < getMinExposureCompensation()) {
712            Log.v(TAG, "Exposure compensation index is not supported. Min = " +
713                    getMinExposureCompensation() + ", max = " + getMaxExposureCompensation() + "," +
714                    " setting = " + index);
715            return false;
716        }
717        return true;
718    }
719
720    private boolean focusCheck(final CameraSettings settings) {
721        FocusMode focusMode = settings.getCurrentFocusMode();
722        if (!supports(focusMode)) {
723            if (supports(FocusMode.FIXED)) {
724                // Workaround for devices whose templates define defaults they don't really support
725                // TODO: Remove workaround (b/17177436)
726                Log.w(TAG, "Focus mode not supported... trying FIXED");
727                settings.setFocusMode(FocusMode.FIXED);
728            } else {
729                Log.v(TAG, "Focus mode not supported:" +
730                        (focusMode != null ? focusMode.name() : "null"));
731                return false;
732            }
733        }
734        return true;
735    }
736
737    private boolean flashCheck(final CameraSettings settings) {
738        FlashMode flashMode = settings.getCurrentFlashMode();
739        if (!supports(flashMode)) {
740            Log.v(TAG,
741                    "Flash mode not supported:" + (flashMode != null ? flashMode.name() : "null"));
742            return false;
743        }
744        return true;
745    }
746
747    private boolean photoSizeCheck(final CameraSettings settings) {
748        Size photoSize = settings.getCurrentPhotoSize();
749        if (mSupportedPhotoSizes.contains(photoSize)) {
750            return true;
751        }
752        Log.v(TAG, "Unsupported photo size:" + photoSize);
753        return false;
754    }
755
756    private boolean previewSizeCheck(final CameraSettings settings) {
757        final Size previewSize = settings.getCurrentPreviewSize();
758        if (mSupportedPreviewSizes.contains(previewSize)) {
759            return true;
760        }
761        Log.v(TAG, "Unsupported preview size:" + previewSize);
762        return false;
763    }
764
765    private boolean videoStabilizationCheck(final CameraSettings settings) {
766        if (!settings.isVideoStabilizationEnabled() || supports(Feature.VIDEO_STABILIZATION)) {
767            return true;
768        }
769        Log.v(TAG, "Video stabilization is not supported");
770        return false;
771    }
772}
773