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          */
toApiCase(String enumCase)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          */
toEnumCase(String apiCase)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          */
stringify(FocusMode focus)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          */
focusModeFromString(String val)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          */
stringify(FlashMode flash)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          */
flashModeFromString(String val)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          */
stringify(SceneMode scene)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          */
sceneModeFromString(String val)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          */
stringify(WhiteBalance wb)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          */
whiteBalanceFromString(String val)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      */
CameraCapabilities(Stringifier stringifier)466     CameraCapabilities(Stringifier stringifier) {
467         mStringifier = stringifier;
468     }
469 
470     /**
471      * Copy constructor.
472      * @param src The source instance.
473      */
CameraCapabilities(CameraCapabilities src)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 
getHorizontalViewAngle()499     public float getHorizontalViewAngle() {
500         return mHorizontalViewAngle;
501     }
502 
getVerticalViewAngle()503     public float getVerticalViewAngle() {
504         return mVerticalViewAngle;
505     }
506 
507     /**
508      * @return the supported picture formats. See {@link android.graphics.ImageFormat}.
509      */
getSupportedPhotoFormats()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      */
getSupportedPreviewFormats()518     public Set<Integer> getSupportedPreviewFormats() {
519         return new TreeSet<Integer>(mSupportedPreviewFormats);
520     }
521 
522     /**
523      * Gets the supported picture sizes.
524      */
getSupportedPhotoSizes()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      */
getSupportedPreviewFpsRange()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      */
getSupportedPreviewSizes()542     public final List<Size> getSupportedPreviewSizes() {
543         return new ArrayList<Size>(mSupportedPreviewSizes);
544     }
545 
getPreferredPreviewSizeForVideo()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      */
getSupportedVideoSizes()554     public final List<Size> getSupportedVideoSizes() {
555         return new ArrayList<Size>(mSupportedVideoSizes);
556     }
557 
558     /**
559      * @return The supported scene modes.
560      */
getSupportedSceneModes()561     public final Set<SceneMode> getSupportedSceneModes() {
562         return new HashSet<SceneMode>(mSupportedSceneModes);
563     }
564 
565     /**
566      * @return Whether the scene mode is supported.
567      */
supports(SceneMode scene)568     public final boolean supports(SceneMode scene) {
569         return (scene != null && mSupportedSceneModes.contains(scene));
570     }
571 
supports(final CameraSettings settings)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      */
getSupportedFlashModes()584     public final Set<FlashMode> getSupportedFlashModes() {
585         return new HashSet<FlashMode>(mSupportedFlashModes);
586     }
587 
588     /**
589      * @return Whether the flash mode is supported.
590      */
supports(FlashMode flash)591     public final boolean supports(FlashMode flash) {
592         return (flash != null && mSupportedFlashModes.contains(flash));
593     }
594 
595     /**
596      * @return The supported focus modes.
597      */
getSupportedFocusModes()598     public final Set<FocusMode> getSupportedFocusModes() {
599         return new HashSet<FocusMode>(mSupportedFocusModes);
600     }
601 
602     /**
603      * @return Whether the focus mode is supported.
604      */
supports(FocusMode focus)605     public final boolean supports(FocusMode focus) {
606         return (focus != null && mSupportedFocusModes.contains(focus));
607     }
608 
609     /**
610      * @return The supported white balanceas.
611      */
getSupportedWhiteBalance()612     public final Set<WhiteBalance> getSupportedWhiteBalance() {
613         return new HashSet<WhiteBalance>(mSupportedWhiteBalances);
614     }
615 
616     /**
617      * @return Whether the white balance is supported.
618      */
supports(WhiteBalance wb)619     public boolean supports(WhiteBalance wb) {
620         return (wb != null && mSupportedWhiteBalances.contains(wb));
621     }
622 
getSupportedFeature()623     public final Set<Feature> getSupportedFeature() {
624         return new HashSet<Feature>(mSupportedFeatures);
625     }
626 
supports(Feature ft)627     public boolean supports(Feature ft) {
628         return (ft != null && mSupportedFeatures.contains(ft));
629     }
630 
631     /**
632      * @return The maximal supported zoom ratio.
633      */
getMaxZoomRatio()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      */
getMinExposureCompensation()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      */
getMaxExposureCompensation()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      */
getExposureCompensationStep()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      */
getMaxNumOfFacesSupported()668     public final int getMaxNumOfFacesSupported() {
669         return mMaxNumOfFacesSupported;
670     }
671 
672     /**
673      * @return The stringifier used by this instance.
674      */
getStringifier()675     public Stringifier getStringifier() {
676         return mStringifier;
677     }
678 
zoomCheck(final CameraSettings settings)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 
exposureCheck(final CameraSettings settings)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 
focusCheck(final CameraSettings settings)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 
flashCheck(final CameraSettings settings)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 
photoSizeCheck(final CameraSettings settings)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 
previewSizeCheck(final CameraSettings settings)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 
videoStabilizationCheck(final CameraSettings settings)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