66
77import android .app .Activity ;
88import android .content .Context ;
9- import android .graphics .ImageFormat ;
109import android .hardware .camera2 .CameraAccessException ;
1110import android .hardware .camera2 .CameraCharacteristics ;
1211import android .hardware .camera2 .CameraManager ;
1312import android .hardware .camera2 .CameraMetadata ;
14- import android .hardware .camera2 .params .StreamConfigurationMap ;
15- import android .media .CamcorderProfile ;
16- import android .util .Size ;
1713import io .flutter .embedding .engine .systemchannels .PlatformChannel ;
18- import io .flutter .plugins .camera .types .ResolutionPreset ;
1914import java .util .ArrayList ;
20- import java .util .Arrays ;
21- import java .util .Collections ;
22- import java .util .Comparator ;
2315import java .util .HashMap ;
2416import java .util .List ;
2517import java .util .Map ;
@@ -29,23 +21,24 @@ public final class CameraUtils {
2921
3022 private CameraUtils () {}
3123
32- static PlatformChannel .DeviceOrientation getDeviceOrientationFromDegrees (int degrees ) {
33- // Round to the nearest 90 degrees.
34- degrees = (int ) (Math .round (degrees / 90.0 ) * 90 ) % 360 ;
35- // Determine the corresponding device orientation.
36- switch (degrees ) {
37- case 90 :
38- return PlatformChannel .DeviceOrientation .LANDSCAPE_LEFT ;
39- case 180 :
40- return PlatformChannel .DeviceOrientation .PORTRAIT_DOWN ;
41- case 270 :
42- return PlatformChannel .DeviceOrientation .LANDSCAPE_RIGHT ;
43- case 0 :
44- default :
45- return PlatformChannel .DeviceOrientation .PORTRAIT_UP ;
46- }
24+ /**
25+ * Gets the {@link CameraManager} singleton.
26+ *
27+ * @param context The context to get the {@link CameraManager} singleton from.
28+ * @return The {@link CameraManager} singleton.
29+ */
30+ static CameraManager getCameraManager (Context context ) {
31+ return (CameraManager ) context .getSystemService (Context .CAMERA_SERVICE );
4732 }
4833
34+ /**
35+ * Serializes the {@link PlatformChannel.DeviceOrientation} to a string value.
36+ *
37+ * @param orientation The orientation to serialize.
38+ * @return The serialized orientation.
39+ * @throws UnsupportedOperationException when the provided orientation not have a corresponding
40+ * string value.
41+ */
4942 static String serializeDeviceOrientation (PlatformChannel .DeviceOrientation orientation ) {
5043 if (orientation == null )
5144 throw new UnsupportedOperationException ("Could not serialize null device orientation." );
@@ -64,6 +57,15 @@ static String serializeDeviceOrientation(PlatformChannel.DeviceOrientation orien
6457 }
6558 }
6659
60+ /**
61+ * Deserializes a string value to its corresponding {@link PlatformChannel.DeviceOrientation}
62+ * value.
63+ *
64+ * @param orientation The string value to deserialize.
65+ * @return The deserialized orientation.
66+ * @throws UnsupportedOperationException when the provided string value does not have a
67+ * corresponding {@link PlatformChannel.DeviceOrientation}.
68+ */
6769 static PlatformChannel .DeviceOrientation deserializeDeviceOrientation (String orientation ) {
6870 if (orientation == null )
6971 throw new UnsupportedOperationException ("Could not deserialize null device orientation." );
@@ -82,23 +84,13 @@ static PlatformChannel.DeviceOrientation deserializeDeviceOrientation(String ori
8284 }
8385 }
8486
85- static Size computeBestPreviewSize (String cameraName , ResolutionPreset preset ) {
86- if (preset .ordinal () > ResolutionPreset .high .ordinal ()) {
87- preset = ResolutionPreset .high ;
88- }
89-
90- CamcorderProfile profile =
91- getBestAvailableCamcorderProfileForResolutionPreset (cameraName , preset );
92- return new Size (profile .videoFrameWidth , profile .videoFrameHeight );
93- }
94-
95- static Size computeBestCaptureSize (StreamConfigurationMap streamConfigurationMap ) {
96- // For still image captures, we use the largest available size.
97- return Collections .max (
98- Arrays .asList (streamConfigurationMap .getOutputSizes (ImageFormat .JPEG )),
99- new CompareSizesByArea ());
100- }
101-
87+ /**
88+ * Gets all the available cameras for the device.
89+ *
90+ * @param activity The current Android activity.
91+ * @return A map of all the available cameras, with their name as their key.
92+ * @throws CameraAccessException when the camera could not be accessed.
93+ */
10294 public static List <Map <String , Object >> getAvailableCameras (Activity activity )
10395 throws CameraAccessException {
10496 CameraManager cameraManager = (CameraManager ) activity .getSystemService (Context .CAMERA_SERVICE );
@@ -127,52 +119,4 @@ public static List<Map<String, Object>> getAvailableCameras(Activity activity)
127119 }
128120 return cameras ;
129121 }
130-
131- static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPreset (
132- String cameraName , ResolutionPreset preset ) {
133- int cameraId = Integer .parseInt (cameraName );
134- switch (preset ) {
135- // All of these cases deliberately fall through to get the best available profile.
136- case max :
137- if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_HIGH )) {
138- return CamcorderProfile .get (cameraId , CamcorderProfile .QUALITY_HIGH );
139- }
140- case ultraHigh :
141- if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_2160P )) {
142- return CamcorderProfile .get (cameraId , CamcorderProfile .QUALITY_2160P );
143- }
144- case veryHigh :
145- if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_1080P )) {
146- return CamcorderProfile .get (cameraId , CamcorderProfile .QUALITY_1080P );
147- }
148- case high :
149- if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_720P )) {
150- return CamcorderProfile .get (cameraId , CamcorderProfile .QUALITY_720P );
151- }
152- case medium :
153- if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_480P )) {
154- return CamcorderProfile .get (cameraId , CamcorderProfile .QUALITY_480P );
155- }
156- case low :
157- if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_QVGA )) {
158- return CamcorderProfile .get (cameraId , CamcorderProfile .QUALITY_QVGA );
159- }
160- default :
161- if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_LOW )) {
162- return CamcorderProfile .get (cameraId , CamcorderProfile .QUALITY_LOW );
163- } else {
164- throw new IllegalArgumentException (
165- "No capture session available for current capture session." );
166- }
167- }
168- }
169-
170- private static class CompareSizesByArea implements Comparator <Size > {
171- @ Override
172- public int compare (Size lhs , Size rhs ) {
173- // We cast here to ensure the multiplications won't overflow.
174- return Long .signum (
175- (long ) lhs .getWidth () * lhs .getHeight () - (long ) rhs .getWidth () * rhs .getHeight ());
176- }
177- }
178122}
0 commit comments