Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 5ece84b

Browse files
committed
Merge with master
2 parents 3a69c94 + 9242af0 commit 5ece84b

File tree

14 files changed

+613
-195
lines changed

14 files changed

+613
-195
lines changed

packages/camera/camera/CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1+
2+
## 0.7.0
3+
4+
* Added support for capture orientation locking on Android and iOS.
5+
* Fixed camera preview not rotating correctly on Android and iOS.
6+
* Fixed camera preview sometimes appearing stretched on Android and iOS.
7+
* Fixed videos & photos saving with the incorrect rotation on iOS.
8+
* BREAKING CHANGE: `CameraValue.aspectRatio` now returns `width / height` rather than `height / width`.
9+
110
## 0.6.4+3
211

312
* Detect if selected camera supports auto focus and act accordingly on Android. This solves a problem where front facing cameras are not capturing the picture because auto focus is not supported.
413

514
## 0.6.4+2
615

7-
* Set ImageStreamReader listener to null to prevent stale images when streaming images.
16+
* Set ImageStreamReader listener to null to prevent stale images when streaming images.
817

918
## 0.6.4+1
1019

packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.flutter.plugins.camera;
22

3-
import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN;
43
import static io.flutter.plugins.camera.CameraUtils.computeBestPreviewSize;
54

65
import android.annotation.SuppressLint;
@@ -37,10 +36,10 @@
3736
import android.util.Range;
3837
import android.util.Rational;
3938
import android.util.Size;
40-
import android.view.OrientationEventListener;
4139
import android.view.Surface;
4240
import androidx.annotation.NonNull;
4341
import androidx.annotation.Nullable;
42+
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
4443
import io.flutter.plugin.common.EventChannel;
4544
import io.flutter.plugin.common.MethodChannel.Result;
4645
import io.flutter.plugins.camera.PictureCaptureRequest.State;
@@ -69,8 +68,7 @@ interface ErrorCallback {
6968
public class Camera {
7069
private final SurfaceTextureEntry flutterTexture;
7170
private final CameraManager cameraManager;
72-
private final OrientationEventListener orientationEventListener;
73-
private final DeviceOrientationListener deviceOrientationListener;
71+
private final DeviceOrientationManager deviceOrientationListener;
7472
private final boolean isFrontFacing;
7573
private final int sensorOrientation;
7674
private final String cameraName;
@@ -91,14 +89,14 @@ public class Camera {
9189
private MediaRecorder mediaRecorder;
9290
private boolean recordingVideo;
9391
private File videoRecordingFile;
94-
private int currentOrientation = ORIENTATION_UNKNOWN;
9592
private FlashMode flashMode;
9693
private ExposureMode exposureMode;
9794
private PictureCaptureRequest pictureCaptureRequest;
9895
private CameraRegions cameraRegions;
9996
private int exposureOffset;
10097
private boolean useAutoFocus;
10198
private Range<Integer> fpsRange;
99+
private PlatformChannel.DeviceOrientation lockedCaptureOrientation;
102100

103101
public Camera(
104102
final Activity activity,
@@ -120,21 +118,6 @@ public Camera(
120118
this.flashMode = FlashMode.auto;
121119
this.exposureMode = ExposureMode.auto;
122120
this.exposureOffset = 0;
123-
orientationEventListener =
124-
new OrientationEventListener(activity.getApplicationContext()) {
125-
@Override
126-
public void onOrientationChanged(int i) {
127-
if (i == ORIENTATION_UNKNOWN) {
128-
return;
129-
}
130-
// Convert the raw deg angle to the nearest multiple of 90.
131-
currentOrientation = (int) (Math.round(i / 90.0) * 90) % 360;
132-
}
133-
};
134-
orientationEventListener.enable();
135-
deviceOrientationListener =
136-
new DeviceOrientationListener(activity.getApplicationContext(), dartMessenger);
137-
deviceOrientationListener.start();
138121

139122
cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraName);
140123
initFps(cameraCharacteristics);
@@ -151,6 +134,11 @@ public void onOrientationChanged(int i) {
151134
new CameraZoom(
152135
cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE),
153136
cameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM));
137+
138+
deviceOrientationListener =
139+
new DeviceOrientationManager(
140+
activity.getApplicationContext(), dartMessenger, isFrontFacing, sensorOrientation);
141+
deviceOrientationListener.start();
154142
}
155143

156144
private void initFps(CameraCharacteristics cameraCharacteristics) {
@@ -182,7 +170,10 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
182170
mediaRecorder =
183171
new MediaRecorderBuilder(recordingProfile, outputFilePath)
184172
.setEnableAudio(enableAudio)
185-
.setMediaOrientation(getMediaOrientation())
173+
.setMediaOrientation(
174+
lockedCaptureOrientation == null
175+
? deviceOrientationListener.getMediaOrientation()
176+
: deviceOrientationListener.getMediaOrientation(lockedCaptureOrientation))
186177
.build();
187178
}
188179

@@ -525,7 +516,11 @@ private void runPictureCapture() {
525516
final CaptureRequest.Builder captureBuilder =
526517
cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
527518
captureBuilder.addTarget(pictureImageReader.getSurface());
528-
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getMediaOrientation());
519+
captureBuilder.set(
520+
CaptureRequest.JPEG_ORIENTATION,
521+
lockedCaptureOrientation == null
522+
? deviceOrientationListener.getMediaOrientation()
523+
: deviceOrientationListener.getMediaOrientation(lockedCaptureOrientation));
529524
switch (flashMode) {
530525
case off:
531526
captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
@@ -859,7 +854,7 @@ public void setExposureOffset(@NonNull final Result result, double offset)
859854
this.cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null);
860855
result.success(offset);
861856
}
862-
857+
863858
public float getMaxZoomLevel() {
864859
return cameraZoom.maxZoom;
865860
}
@@ -893,6 +888,14 @@ public void setZoomLevel(@NonNull final Result result, float zoom) throws Camera
893888
result.success(null);
894889
}
895890

891+
public void lockCaptureOrientation(PlatformChannel.DeviceOrientation orientation) {
892+
this.lockedCaptureOrientation = orientation;
893+
}
894+
895+
public void unlockCaptureOrientation() {
896+
this.lockedCaptureOrientation = null;
897+
}
898+
896899
private void updateFpsRange() {
897900
if (fpsRange == null) {
898901
return;
@@ -1068,15 +1071,6 @@ public void close() {
10681071
public void dispose() {
10691072
close();
10701073
flutterTexture.release();
1071-
orientationEventListener.disable();
10721074
deviceOrientationListener.stop();
10731075
}
1074-
1075-
private int getMediaOrientation() {
1076-
final int sensorOrientationOffset =
1077-
(currentOrientation == ORIENTATION_UNKNOWN)
1078-
? 0
1079-
: (isFrontFacing) ? -currentOrientation : currentOrientation;
1080-
return (sensorOrientationOffset + sensorOrientation + 360) % 360;
1081-
}
10821076
}

packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ static PlatformChannel.DeviceOrientation getDeviceOrientationFromDegrees(int deg
4343
}
4444

4545
static String serializeDeviceOrientation(PlatformChannel.DeviceOrientation orientation) {
46-
assert (orientation != null);
46+
if (orientation == null)
47+
throw new UnsupportedOperationException("Could not serialize null device orientation.");
4748
switch (orientation) {
4849
case PORTRAIT_UP:
4950
return "portraitUp";
@@ -59,6 +60,24 @@ static String serializeDeviceOrientation(PlatformChannel.DeviceOrientation orien
5960
}
6061
}
6162

63+
static PlatformChannel.DeviceOrientation deserializeDeviceOrientation(String orientation) {
64+
if (orientation == null)
65+
throw new UnsupportedOperationException("Could not deserialize null device orientation.");
66+
switch (orientation) {
67+
case "portraitUp":
68+
return PlatformChannel.DeviceOrientation.PORTRAIT_UP;
69+
case "portraitDown":
70+
return PlatformChannel.DeviceOrientation.PORTRAIT_DOWN;
71+
case "landscapeLeft":
72+
return PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT;
73+
case "landscapeRight":
74+
return PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT;
75+
default:
76+
throw new UnsupportedOperationException(
77+
"Could not deserialize device orientation: " + orientation);
78+
}
79+
}
80+
6281
static Size computeBestPreviewSize(String cameraName, ResolutionPreset preset) {
6382
if (preset.ordinal() > ResolutionPreset.high.ordinal()) {
6483
preset = ResolutionPreset.high;

packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationListener.java

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)