Skip to content

Commit 036cb1e

Browse files
[camera] Revert Android part of #3272 (#3405)
Reverts the Android part of #3272 (commit d311478), which introduced significant crash flake in the tests.
1 parent 5eefd07 commit 036cb1e

File tree

12 files changed

+47
-780
lines changed

12 files changed

+47
-780
lines changed

packages/camera/camera_android/CHANGELOG.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
## 0.10.5
2-
3-
* Allows camera to be switched while video recording.
4-
51
## 0.10.4+2
62

73
* Aligns Dart and Flutter SDK constraints.

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

Lines changed: 25 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -96,28 +96,13 @@ class Camera
9696
* Holds all of the camera features/settings and will be used to update the request builder when
9797
* one changes.
9898
*/
99-
private CameraFeatures cameraFeatures;
100-
101-
private String imageFormatGroup;
102-
103-
/**
104-
* Takes an input/output surface and orients the recording correctly. This is needed because
105-
* switching cameras while recording causes the wrong orientation.
106-
*/
107-
private VideoRenderer videoRenderer;
108-
109-
/**
110-
* Whether or not the camera aligns with the initial way the camera was facing if the camera was
111-
* flipped.
112-
*/
113-
private int initialCameraFacing;
99+
private final CameraFeatures cameraFeatures;
114100

115101
private final SurfaceTextureEntry flutterTexture;
116-
private final ResolutionPreset resolutionPreset;
117102
private final boolean enableAudio;
118103
private final Context applicationContext;
119104
private final DartMessenger dartMessenger;
120-
private CameraProperties cameraProperties;
105+
private final CameraProperties cameraProperties;
121106
private final CameraFeatureFactory cameraFeatureFactory;
122107
private final Activity activity;
123108
/** A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture. */
@@ -207,7 +192,6 @@ public Camera(
207192
this.applicationContext = activity.getApplicationContext();
208193
this.cameraProperties = cameraProperties;
209194
this.cameraFeatureFactory = cameraFeatureFactory;
210-
this.resolutionPreset = resolutionPreset;
211195
this.cameraFeatures =
212196
CameraFeatures.init(
213197
cameraFeatureFactory, cameraProperties, activity, dartMessenger, resolutionPreset);
@@ -248,7 +232,6 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
248232
if (mediaRecorder != null) {
249233
mediaRecorder.release();
250234
}
251-
closeRenderer();
252235

253236
final PlatformChannel.DeviceOrientation lockedOrientation =
254237
cameraFeatures.getSensorOrientation().getLockedCaptureOrientation();
@@ -276,7 +259,6 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
276259

277260
@SuppressLint("MissingPermission")
278261
public void open(String imageFormatGroup) throws CameraAccessException {
279-
this.imageFormatGroup = imageFormatGroup;
280262
final ResolutionFeature resolutionFeature = cameraFeatures.getResolution();
281263

282264
if (!resolutionFeature.checkIsSupported()) {
@@ -321,16 +303,14 @@ public void onOpened(@NonNull CameraDevice device) {
321303
cameraDevice = new DefaultCameraDeviceWrapper(device);
322304
try {
323305
startPreview();
324-
if (!recordingVideo) // only send initialization if we werent already recording and switching cameras
325306
dartMessenger.sendCameraInitializedEvent(
326-
resolutionFeature.getPreviewSize().getWidth(),
327-
resolutionFeature.getPreviewSize().getHeight(),
328-
cameraFeatures.getExposureLock().getValue(),
329-
cameraFeatures.getAutoFocus().getValue(),
330-
cameraFeatures.getExposurePoint().checkIsSupported(),
331-
cameraFeatures.getFocusPoint().checkIsSupported());
332-
333-
} catch (CameraAccessException | InterruptedException e) {
307+
resolutionFeature.getPreviewSize().getWidth(),
308+
resolutionFeature.getPreviewSize().getHeight(),
309+
cameraFeatures.getExposureLock().getValue(),
310+
cameraFeatures.getAutoFocus().getValue(),
311+
cameraFeatures.getExposurePoint().checkIsSupported(),
312+
cameraFeatures.getFocusPoint().checkIsSupported());
313+
} catch (CameraAccessException e) {
334314
dartMessenger.sendCameraErrorEvent(e.getMessage());
335315
close();
336316
}
@@ -340,8 +320,7 @@ public void onOpened(@NonNull CameraDevice device) {
340320
public void onClosed(@NonNull CameraDevice camera) {
341321
Log.i(TAG, "open | onClosed");
342322

343-
// Prevents calls to methods that would otherwise result in IllegalStateException
344-
// exceptions.
323+
// Prevents calls to methods that would otherwise result in IllegalStateException exceptions.
345324
cameraDevice = null;
346325
closeCaptureSession();
347326
dartMessenger.sendCameraClosingEvent();
@@ -756,7 +735,7 @@ public void startVideoRecording(
756735
if (imageStreamChannel != null) {
757736
setStreamHandler(imageStreamChannel);
758737
}
759-
initialCameraFacing = cameraProperties.getLensFacing();
738+
760739
recordingVideo = true;
761740
try {
762741
startCapture(true, imageStreamChannel != null);
@@ -768,13 +747,6 @@ public void startVideoRecording(
768747
}
769748
}
770749

771-
private void closeRenderer() {
772-
if (videoRenderer != null) {
773-
videoRenderer.close();
774-
videoRenderer = null;
775-
}
776-
}
777-
778750
public void stopVideoRecording(@NonNull final Result result) {
779751
if (!recordingVideo) {
780752
result.success(null);
@@ -785,7 +757,6 @@ public void stopVideoRecording(@NonNull final Result result) {
785757
cameraFeatureFactory.createAutoFocusFeature(cameraProperties, false));
786758
recordingVideo = false;
787759
try {
788-
closeRenderer();
789760
captureSession.abortCaptures();
790761
mediaRecorder.stop();
791762
} catch (CameraAccessException | IllegalStateException e) {
@@ -794,7 +765,7 @@ public void stopVideoRecording(@NonNull final Result result) {
794765
mediaRecorder.reset();
795766
try {
796767
startPreview();
797-
} catch (CameraAccessException | IllegalStateException | InterruptedException e) {
768+
} catch (CameraAccessException | IllegalStateException e) {
798769
result.error("videoRecordingFailed", e.getMessage(), null);
799770
return;
800771
}
@@ -1078,48 +1049,11 @@ public void resumePreview() {
10781049
null, (code, message) -> dartMessenger.sendCameraErrorEvent(message));
10791050
}
10801051

1081-
public void startPreview() throws CameraAccessException, InterruptedException {
1082-
// If recording is already in progress, the camera is being flipped, so send it through the VideoRenderer to keep the correct orientation.
1083-
if (recordingVideo) {
1084-
startPreviewWithVideoRendererStream();
1085-
} else {
1086-
startRegularPreview();
1087-
}
1088-
}
1089-
1090-
private void startRegularPreview() throws CameraAccessException {
1052+
public void startPreview() throws CameraAccessException {
10911053
if (pictureImageReader == null || pictureImageReader.getSurface() == null) return;
10921054
Log.i(TAG, "startPreview");
1093-
createCaptureSession(CameraDevice.TEMPLATE_PREVIEW, pictureImageReader.getSurface());
1094-
}
1095-
1096-
private void startPreviewWithVideoRendererStream()
1097-
throws CameraAccessException, InterruptedException {
1098-
if (videoRenderer == null) return;
1099-
1100-
// get rotation for rendered video
1101-
final PlatformChannel.DeviceOrientation lockedOrientation =
1102-
cameraFeatures.getSensorOrientation().getLockedCaptureOrientation();
1103-
DeviceOrientationManager orientationManager =
1104-
cameraFeatures.getSensorOrientation().getDeviceOrientationManager();
1105-
1106-
int rotation = 0;
1107-
if (orientationManager != null) {
1108-
rotation =
1109-
lockedOrientation == null
1110-
? orientationManager.getVideoOrientation()
1111-
: orientationManager.getVideoOrientation(lockedOrientation);
1112-
}
1113-
1114-
if (cameraProperties.getLensFacing() != initialCameraFacing) {
1115-
1116-
// If the new camera is facing the opposite way than the initial recording,
1117-
// the rotation should be flipped 180 degrees.
1118-
rotation = (rotation + 180) % 360;
1119-
}
1120-
videoRenderer.setRotation(rotation);
11211055

1122-
createCaptureSession(CameraDevice.TEMPLATE_RECORD, videoRenderer.getInputSurface());
1056+
createCaptureSession(CameraDevice.TEMPLATE_PREVIEW, pictureImageReader.getSurface());
11231057
}
11241058

11251059
public void startPreviewWithImageStream(EventChannel imageStreamChannel)
@@ -1245,7 +1179,17 @@ private void closeCaptureSession() {
12451179
public void close() {
12461180
Log.i(TAG, "close");
12471181

1248-
stopAndReleaseCamera();
1182+
if (cameraDevice != null) {
1183+
cameraDevice.close();
1184+
cameraDevice = null;
1185+
1186+
// Closing the CameraDevice without closing the CameraCaptureSession is recommended
1187+
// for quickly closing the camera:
1188+
// https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession#close()
1189+
captureSession = null;
1190+
} else {
1191+
closeCaptureSession();
1192+
}
12491193

12501194
if (pictureImageReader != null) {
12511195
pictureImageReader.close();
@@ -1264,75 +1208,6 @@ public void close() {
12641208
stopBackgroundThread();
12651209
}
12661210

1267-
private void stopAndReleaseCamera() {
1268-
if (cameraDevice != null) {
1269-
cameraDevice.close();
1270-
cameraDevice = null;
1271-
1272-
// Closing the CameraDevice without closing the CameraCaptureSession is recommended
1273-
// for quickly closing the camera:
1274-
// https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession#close()
1275-
captureSession = null;
1276-
} else {
1277-
closeCaptureSession();
1278-
}
1279-
}
1280-
1281-
private void prepareVideoRenderer() {
1282-
if (videoRenderer != null) return;
1283-
final ResolutionFeature resolutionFeature = cameraFeatures.getResolution();
1284-
1285-
// handle videoRenderer errors
1286-
Thread.UncaughtExceptionHandler videoRendererUncaughtExceptionHandler =
1287-
new Thread.UncaughtExceptionHandler() {
1288-
@Override
1289-
public void uncaughtException(Thread thread, Throwable ex) {
1290-
dartMessenger.sendCameraErrorEvent(
1291-
"Failed to process frames after camera was flipped.");
1292-
}
1293-
};
1294-
1295-
videoRenderer =
1296-
new VideoRenderer(
1297-
mediaRecorder.getSurface(),
1298-
resolutionFeature.getCaptureSize().getWidth(),
1299-
resolutionFeature.getCaptureSize().getHeight(),
1300-
videoRendererUncaughtExceptionHandler);
1301-
}
1302-
1303-
public void setDescriptionWhileRecording(
1304-
@NonNull final Result result, CameraProperties properties) {
1305-
1306-
if (!recordingVideo) {
1307-
result.error("setDescriptionWhileRecordingFailed", "Device was not recording", null);
1308-
return;
1309-
}
1310-
1311-
// See VideoRenderer.java requires API 26 to switch camera while recording
1312-
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
1313-
result.error(
1314-
"setDescriptionWhileRecordingFailed",
1315-
"Device does not support switching the camera while recording",
1316-
null);
1317-
return;
1318-
}
1319-
1320-
stopAndReleaseCamera();
1321-
prepareVideoRenderer();
1322-
cameraProperties = properties;
1323-
cameraFeatures =
1324-
CameraFeatures.init(
1325-
cameraFeatureFactory, cameraProperties, activity, dartMessenger, resolutionPreset);
1326-
cameraFeatures.setAutoFocus(
1327-
cameraFeatureFactory.createAutoFocusFeature(cameraProperties, true));
1328-
try {
1329-
open(imageFormatGroup);
1330-
} catch (CameraAccessException e) {
1331-
result.error("setDescriptionWhileRecordingFailed", e.getMessage(), null);
1332-
}
1333-
result.success(null);
1334-
}
1335-
13361211
public void dispose() {
13371212
Log.i(TAG, "dispose");
13381213

packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -354,18 +354,6 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result)
354354
result.success(null);
355355
break;
356356
}
357-
case "setDescriptionWhileRecording":
358-
{
359-
try {
360-
String cameraName = call.argument("cameraName");
361-
CameraProperties cameraProperties =
362-
new CameraPropertiesImpl(cameraName, CameraUtils.getCameraManager(activity));
363-
camera.setDescriptionWhileRecording(result, cameraProperties);
364-
} catch (Exception e) {
365-
handleException(e, result);
366-
}
367-
break;
368-
}
369357
case "dispose":
370358
{
371359
if (camera != null) {

0 commit comments

Comments
 (0)