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 android.hardware.Camera;
20 
21 import com.android.ex.camera2.portability.debug.Log;
22 
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.List;
26 
27 /**
28  * The subclass of {@link CameraCapabilities} for Android Camera 1 API.
29  */
30 class AndroidCameraCapabilities extends CameraCapabilities {
31 
32     private static Log.Tag TAG = new Log.Tag("AndCamCapabs");
33 
34     /** Conversion from ratios to percentages. */
35     public static final float ZOOM_MULTIPLIER = 100f;
36 
37     private FpsComparator mFpsComparator = new FpsComparator();
38     private SizeComparator mSizeComparator = new SizeComparator();
39 
AndroidCameraCapabilities(Camera.Parameters p)40     AndroidCameraCapabilities(Camera.Parameters p) {
41         super(new Stringifier());
42         mMaxExposureCompensation = p.getMaxExposureCompensation();
43         mMinExposureCompensation = p.getMinExposureCompensation();
44         mExposureCompensationStep = p.getExposureCompensationStep();
45         mMaxNumOfFacesSupported = p.getMaxNumDetectedFaces();
46         mMaxNumOfMeteringArea = p.getMaxNumMeteringAreas();
47         mPreferredPreviewSizeForVideo = new Size(p.getPreferredPreviewSizeForVideo());
48         mSupportedPreviewFormats.addAll(p.getSupportedPreviewFormats());
49         mSupportedPhotoFormats.addAll(p.getSupportedPictureFormats());
50         mHorizontalViewAngle = p.getHorizontalViewAngle();
51         mVerticalViewAngle = p.getVerticalViewAngle();
52         buildPreviewFpsRange(p);
53         buildPreviewSizes(p);
54         buildVideoSizes(p);
55         buildPictureSizes(p);
56         buildSceneModes(p);
57         buildFlashModes(p);
58         buildFocusModes(p);
59         buildWhiteBalances(p);
60 
61         if (p.isZoomSupported()) {
62             mMaxZoomRatio = p.getZoomRatios().get(p.getMaxZoom()) / ZOOM_MULTIPLIER;
63             mSupportedFeatures.add(Feature.ZOOM);
64         }
65         if (p.isVideoSnapshotSupported()) {
66             mSupportedFeatures.add(Feature.VIDEO_SNAPSHOT);
67         }
68         if (p.isAutoExposureLockSupported()) {
69             mSupportedFeatures.add(Feature.AUTO_EXPOSURE_LOCK);
70         }
71         if (p.isAutoWhiteBalanceLockSupported()) {
72             mSupportedFeatures.add(Feature.AUTO_WHITE_BALANCE_LOCK);
73         }
74         if (supports(FocusMode.AUTO)) {
75             mMaxNumOfFocusAreas = p.getMaxNumFocusAreas();
76             if (mMaxNumOfFocusAreas > 0) {
77                 mSupportedFeatures.add(Feature.FOCUS_AREA);
78             }
79         }
80         if (mMaxNumOfMeteringArea > 0) {
81             mSupportedFeatures.add(Feature.METERING_AREA);
82         }
83     }
84 
AndroidCameraCapabilities(AndroidCameraCapabilities src)85     AndroidCameraCapabilities(AndroidCameraCapabilities src) {
86         super(src);
87     }
88 
buildPreviewFpsRange(Camera.Parameters p)89     private void buildPreviewFpsRange(Camera.Parameters p) {
90         List<int[]> supportedPreviewFpsRange = p.getSupportedPreviewFpsRange();
91         if (supportedPreviewFpsRange != null) {
92             mSupportedPreviewFpsRange.addAll(supportedPreviewFpsRange);
93         }
94         Collections.sort(mSupportedPreviewFpsRange, mFpsComparator);
95     }
96 
buildPreviewSizes(Camera.Parameters p)97     private void buildPreviewSizes(Camera.Parameters p) {
98         List<Camera.Size> supportedPreviewSizes = p.getSupportedPreviewSizes();
99         if (supportedPreviewSizes != null) {
100             for (Camera.Size s : supportedPreviewSizes) {
101                 mSupportedPreviewSizes.add(new Size(s.width, s.height));
102             }
103         }
104         Collections.sort(mSupportedPreviewSizes, mSizeComparator);
105     }
106 
buildVideoSizes(Camera.Parameters p)107     private void buildVideoSizes(Camera.Parameters p) {
108         List<Camera.Size> supportedVideoSizes = p.getSupportedVideoSizes();
109         if (supportedVideoSizes != null) {
110             for (Camera.Size s : supportedVideoSizes) {
111                 mSupportedVideoSizes.add(new Size(s.width, s.height));
112             }
113         }
114         Collections.sort(mSupportedVideoSizes, mSizeComparator);
115     }
116 
buildPictureSizes(Camera.Parameters p)117     private void buildPictureSizes(Camera.Parameters p) {
118         List<Camera.Size> supportedPictureSizes = p.getSupportedPictureSizes();
119         if (supportedPictureSizes != null) {
120             for (Camera.Size s : supportedPictureSizes) {
121                 mSupportedPhotoSizes.add(new Size(s.width, s.height));
122             }
123         }
124         Collections.sort(mSupportedPhotoSizes, mSizeComparator);
125 
126     }
127 
buildSceneModes(Camera.Parameters p)128     private void buildSceneModes(Camera.Parameters p) {
129         List<String> supportedSceneModes = p.getSupportedSceneModes();
130         if (supportedSceneModes != null) {
131             for (String scene : supportedSceneModes) {
132                 if (Camera.Parameters.SCENE_MODE_AUTO.equals(scene)) {
133                     mSupportedSceneModes.add(SceneMode.AUTO);
134                 } else if (Camera.Parameters.SCENE_MODE_ACTION.equals(scene)) {
135                     mSupportedSceneModes.add(SceneMode.ACTION);
136                 } else if (Camera.Parameters.SCENE_MODE_BARCODE.equals(scene)) {
137                     mSupportedSceneModes.add(SceneMode.BARCODE);
138                 } else if (Camera.Parameters.SCENE_MODE_BEACH.equals(scene)) {
139                     mSupportedSceneModes.add(SceneMode.BEACH);
140                 } else if (Camera.Parameters.SCENE_MODE_CANDLELIGHT.equals(scene)) {
141                     mSupportedSceneModes.add(SceneMode.CANDLELIGHT);
142                 } else if (Camera.Parameters.SCENE_MODE_FIREWORKS.equals(scene)) {
143                     mSupportedSceneModes.add(SceneMode.FIREWORKS);
144                 } else if (Camera.Parameters.SCENE_MODE_HDR.equals(scene)) {
145                     mSupportedSceneModes.add(SceneMode.HDR);
146                 } else if (Camera.Parameters.SCENE_MODE_LANDSCAPE.equals(scene)) {
147                     mSupportedSceneModes.add(SceneMode.LANDSCAPE);
148                 } else if (Camera.Parameters.SCENE_MODE_NIGHT.equals(scene)) {
149                     mSupportedSceneModes.add(SceneMode.NIGHT);
150                 } else if (Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT.equals(scene)) {
151                     mSupportedSceneModes.add(SceneMode.NIGHT_PORTRAIT);
152                 } else if (Camera.Parameters.SCENE_MODE_PARTY.equals(scene)) {
153                     mSupportedSceneModes.add(SceneMode.PARTY);
154                 } else if (Camera.Parameters.SCENE_MODE_PORTRAIT.equals(scene)) {
155                     mSupportedSceneModes.add(SceneMode.PORTRAIT);
156                 } else if (Camera.Parameters.SCENE_MODE_SNOW.equals(scene)) {
157                     mSupportedSceneModes.add(SceneMode.SNOW);
158                 } else if (Camera.Parameters.SCENE_MODE_SPORTS.equals(scene)) {
159                     mSupportedSceneModes.add(SceneMode.SPORTS);
160                 } else if (Camera.Parameters.SCENE_MODE_STEADYPHOTO.equals(scene)) {
161                     mSupportedSceneModes.add(SceneMode.STEADYPHOTO);
162                 } else if (Camera.Parameters.SCENE_MODE_SUNSET.equals(scene)) {
163                     mSupportedSceneModes.add(SceneMode.SUNSET);
164                 } else if (Camera.Parameters.SCENE_MODE_THEATRE.equals(scene)) {
165                     mSupportedSceneModes.add(SceneMode.THEATRE);
166                 }
167             }
168         }
169     }
170 
buildFlashModes(Camera.Parameters p)171     private void buildFlashModes(Camera.Parameters p) {
172         List<String> supportedFlashModes = p.getSupportedFlashModes();
173         if (supportedFlashModes == null) {
174             // Camera 1 will return NULL if no flash mode is supported.
175             mSupportedFlashModes.add(FlashMode.NO_FLASH);
176         } else {
177             for (String flash : supportedFlashModes) {
178                 if (Camera.Parameters.FLASH_MODE_AUTO.equals(flash)) {
179                     mSupportedFlashModes.add(FlashMode.AUTO);
180                 } else if (Camera.Parameters.FLASH_MODE_OFF.equals(flash)) {
181                     mSupportedFlashModes.add(FlashMode.OFF);
182                 } else if (Camera.Parameters.FLASH_MODE_ON.equals(flash)) {
183                     mSupportedFlashModes.add(FlashMode.ON);
184                 } else if (Camera.Parameters.FLASH_MODE_RED_EYE.equals(flash)) {
185                     mSupportedFlashModes.add(FlashMode.RED_EYE);
186                 } else if (Camera.Parameters.FLASH_MODE_TORCH.equals(flash)) {
187                     mSupportedFlashModes.add(FlashMode.TORCH);
188                 }
189             }
190         }
191     }
192 
buildFocusModes(Camera.Parameters p)193     private void buildFocusModes(Camera.Parameters p) {
194         List<String> supportedFocusModes = p.getSupportedFocusModes();
195         if (supportedFocusModes != null) {
196             for (String focus : supportedFocusModes) {
197                 if (Camera.Parameters.FOCUS_MODE_AUTO.equals(focus)) {
198                     mSupportedFocusModes.add(FocusMode.AUTO);
199                 } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(focus)) {
200                     mSupportedFocusModes.add(FocusMode.CONTINUOUS_PICTURE);
201                 } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO.equals(focus)) {
202                     mSupportedFocusModes.add(FocusMode.CONTINUOUS_VIDEO);
203                 } else if (Camera.Parameters.FOCUS_MODE_EDOF.equals(focus)) {
204                     mSupportedFocusModes.add(FocusMode.EXTENDED_DOF);
205                 } else if (Camera.Parameters.FOCUS_MODE_FIXED.equals(focus)) {
206                     mSupportedFocusModes.add(FocusMode.FIXED);
207                 } else if (Camera.Parameters.FOCUS_MODE_INFINITY.equals(focus)) {
208                     mSupportedFocusModes.add(FocusMode.INFINITY);
209                 } else if (Camera.Parameters.FOCUS_MODE_MACRO.equals(focus)) {
210                     mSupportedFocusModes.add(FocusMode.MACRO);
211                 }
212             }
213         }
214     }
215 
buildWhiteBalances(Camera.Parameters p)216     private void buildWhiteBalances(Camera.Parameters p) {
217         List<String> supportedWhiteBalances = p.getSupportedWhiteBalance();
218         if (supportedWhiteBalances != null) {
219             for (String wb : supportedWhiteBalances) {
220                 if (Camera.Parameters.WHITE_BALANCE_AUTO.equals(wb)) {
221                     mSupportedWhiteBalances.add(WhiteBalance.AUTO);
222                 } else if (Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT.equals(wb)) {
223                     mSupportedWhiteBalances.add(WhiteBalance.CLOUDY_DAYLIGHT);
224                 } else if (Camera.Parameters.WHITE_BALANCE_DAYLIGHT.equals(wb)) {
225                     mSupportedWhiteBalances.add(WhiteBalance.DAYLIGHT);
226                 } else if (Camera.Parameters.WHITE_BALANCE_FLUORESCENT.equals(wb)) {
227                     mSupportedWhiteBalances.add(WhiteBalance.FLUORESCENT);
228                 } else if (Camera.Parameters.WHITE_BALANCE_INCANDESCENT.equals(wb)) {
229                     mSupportedWhiteBalances.add(WhiteBalance.INCANDESCENT);
230                 } else if (Camera.Parameters.WHITE_BALANCE_SHADE.equals(wb)) {
231                     mSupportedWhiteBalances.add(WhiteBalance.SHADE);
232                 } else if (Camera.Parameters.WHITE_BALANCE_TWILIGHT.equals(wb)) {
233                     mSupportedWhiteBalances.add(WhiteBalance.TWILIGHT);
234                 } else if (Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT.equals(wb)) {
235                     mSupportedWhiteBalances.add(WhiteBalance.WARM_FLUORESCENT);
236                 }
237             }
238         }
239     }
240 
241     private static class FpsComparator implements Comparator<int[]> {
242         @Override
compare(int[] fps1, int[] fps2)243         public int compare(int[] fps1, int[] fps2) {
244             return (fps1[0] == fps2[0] ? fps1[1] - fps2[1] : fps1[0] - fps2[0]);
245         }
246     }
247 
248     private static class SizeComparator implements Comparator<Size> {
249 
250         @Override
compare(Size size1, Size size2)251         public int compare(Size size1, Size size2) {
252             return (size1.width() == size2.width() ? size1.height() - size2.height() :
253                     size1.width() - size2.width());
254         }
255     }
256 }
257