Skip to content

Commit bf2e3e4

Browse files
committed
Revert "[camera] Fix CamcorderProfile Usages (flutter#4423) (cherry picked from commit 29f46b4)"
This reverts commit 253cf48
1 parent a0744e7 commit bf2e3e4

12 files changed

Lines changed: 67 additions & 656 deletions

File tree

packages/camera/camera/android/build.gradle

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ buildscript {
99
}
1010

1111
dependencies {
12-
classpath 'com.android.tools.build:gradle:7.0.2'
12+
classpath 'com.android.tools.build:gradle:3.5.0'
1313
}
1414
}
1515

@@ -27,10 +27,9 @@ project.getTasks().withType(JavaCompile){
2727
apply plugin: 'com.android.library'
2828

2929
android {
30-
compileSdkVersion 31
30+
compileSdkVersion 29
3131

3232
defaultConfig {
33-
targetSdkVersion 31
3433
minSdkVersion 21
3534
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
3635
}
@@ -61,7 +60,7 @@ android {
6160
dependencies {
6261
compileOnly 'androidx.annotation:annotation:1.1.0'
6362
testImplementation 'junit:junit:4.12'
64-
testImplementation 'org.mockito:mockito-inline:4.0.0'
63+
testImplementation 'org.mockito:mockito-inline:3.12.4'
6564
testImplementation 'androidx.test:core:1.3.0'
66-
testImplementation 'org.robolectric:robolectric:4.5'
65+
testImplementation 'org.robolectric:robolectric:4.3'
6766
}

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

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import android.hardware.camera2.params.OutputConfiguration;
2121
import android.hardware.camera2.params.SessionConfiguration;
2222
import android.media.CamcorderProfile;
23-
import android.media.EncoderProfiles;
2423
import android.media.Image;
2524
import android.media.ImageReader;
2625
import android.media.MediaRecorder;
@@ -200,16 +199,8 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
200199
((SensorOrientationFeature) cameraFeatures.getSensorOrientation())
201200
.getLockedCaptureOrientation();
202201

203-
MediaRecorderBuilder mediaRecorderBuilder;
204-
205-
if (Build.VERSION.SDK_INT >= 31) {
206-
mediaRecorderBuilder = new MediaRecorderBuilder(getRecordingProfile(), outputFilePath);
207-
} else {
208-
mediaRecorderBuilder = new MediaRecorderBuilder(getRecordingProfileLegacy(), outputFilePath);
209-
}
210-
211202
mediaRecorder =
212-
mediaRecorderBuilder
203+
new MediaRecorderBuilder(getRecordingProfile(), outputFilePath)
213204
.setEnableAudio(enableAudio)
214205
.setMediaOrientation(
215206
lockedOrientation == null
@@ -931,12 +922,8 @@ public float getMinZoomLevel() {
931922
return cameraFeatures.getZoomLevel().getMinimumZoomLevel();
932923
}
933924

934-
/** Shortcut to get current recording profile. Legacy method provides support for SDK < 31. */
935-
CamcorderProfile getRecordingProfileLegacy() {
936-
return cameraFeatures.getResolution().getRecordingProfileLegacy();
937-
}
938-
939-
EncoderProfiles getRecordingProfile() {
925+
/** Shortcut to get current recording profile. */
926+
CamcorderProfile getRecordingProfile() {
940927
return cameraFeatures.getResolution().getRecordingProfile();
941928
}
942929

packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/features/resolution/ResolutionFeature.java

Lines changed: 12 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@
44

55
package io.flutter.plugins.camera.features.resolution;
66

7-
import android.annotation.TargetApi;
87
import android.hardware.camera2.CaptureRequest;
98
import android.media.CamcorderProfile;
10-
import android.media.EncoderProfiles;
11-
import android.os.Build;
129
import android.util.Size;
1310
import androidx.annotation.VisibleForTesting;
1411
import io.flutter.plugins.camera.CameraProperties;
1512
import io.flutter.plugins.camera.features.CameraFeature;
16-
import java.util.List;
1713

1814
/**
1915
* Controls the resolutions configuration on the {@link android.hardware.camera2} API.
@@ -25,8 +21,7 @@
2521
public class ResolutionFeature extends CameraFeature<ResolutionPreset> {
2622
private Size captureSize;
2723
private Size previewSize;
28-
private CamcorderProfile recordingProfileLegacy;
29-
private EncoderProfiles recordingProfile;
24+
private CamcorderProfile recordingProfile;
3025
private ResolutionPreset currentSetting;
3126
private int cameraId;
3227

@@ -56,11 +51,7 @@ public ResolutionFeature(
5651
*
5752
* @return Resolution information to configure the {@link android.hardware.camera2} API.
5853
*/
59-
public CamcorderProfile getRecordingProfileLegacy() {
60-
return this.recordingProfileLegacy;
61-
}
62-
63-
public EncoderProfiles getRecordingProfile() {
54+
public CamcorderProfile getRecordingProfile() {
6455
return this.recordingProfile;
6556
}
6657

@@ -109,29 +100,19 @@ public void updateBuilder(CaptureRequest.Builder requestBuilder) {
109100
}
110101

111102
@VisibleForTesting
112-
static Size computeBestPreviewSize(int cameraId, ResolutionPreset preset)
113-
throws IndexOutOfBoundsException {
103+
static Size computeBestPreviewSize(int cameraId, ResolutionPreset preset) {
114104
if (preset.ordinal() > ResolutionPreset.high.ordinal()) {
115105
preset = ResolutionPreset.high;
116106
}
117-
if (Build.VERSION.SDK_INT >= 31) {
118-
EncoderProfiles profile =
119-
getBestAvailableCamcorderProfileForResolutionPreset(cameraId, preset);
120-
List<EncoderProfiles.VideoProfile> videoProfiles = profile.getVideoProfiles();
121-
EncoderProfiles.VideoProfile defaultVideoProfile = videoProfiles.get(0);
122107

123-
return new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight());
124-
} else {
125-
@SuppressWarnings("deprecation")
126-
CamcorderProfile profile =
127-
getBestAvailableCamcorderProfileForResolutionPresetLegacy(cameraId, preset);
128-
return new Size(profile.videoFrameWidth, profile.videoFrameHeight);
129-
}
108+
CamcorderProfile profile =
109+
getBestAvailableCamcorderProfileForResolutionPreset(cameraId, preset);
110+
return new Size(profile.videoFrameWidth, profile.videoFrameHeight);
130111
}
131112

132113
/**
133114
* Gets the best possible {@link android.media.CamcorderProfile} for the supplied {@link
134-
* ResolutionPreset}. Supports SDK < 31.
115+
* ResolutionPreset}.
135116
*
136117
* @param cameraId Camera identifier which indicates the device's camera for which to select a
137118
* {@link android.media.CamcorderProfile}.
@@ -140,7 +121,7 @@ static Size computeBestPreviewSize(int cameraId, ResolutionPreset preset)
140121
* @return The best possible {@link android.media.CamcorderProfile} that matches the supplied
141122
* {@link ResolutionPreset}.
142123
*/
143-
public static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPresetLegacy(
124+
public static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPreset(
144125
int cameraId, ResolutionPreset preset) {
145126
if (cameraId < 0) {
146127
throw new AssertionError(
@@ -183,74 +164,13 @@ public static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPres
183164
}
184165
}
185166

186-
@TargetApi(Build.VERSION_CODES.S)
187-
public static EncoderProfiles getBestAvailableCamcorderProfileForResolutionPreset(
188-
int cameraId, ResolutionPreset preset) {
189-
if (cameraId < 0) {
190-
throw new AssertionError(
191-
"getBestAvailableCamcorderProfileForResolutionPreset can only be used with valid (>=0) camera identifiers.");
192-
}
193-
194-
String cameraIdString = Integer.toString(cameraId);
195-
196-
switch (preset) {
197-
// All of these cases deliberately fall through to get the best available profile.
198-
case max:
199-
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_HIGH)) {
200-
return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_HIGH);
201-
}
202-
case ultraHigh:
203-
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_2160P)) {
204-
return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_2160P);
205-
}
206-
case veryHigh:
207-
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_1080P)) {
208-
return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_1080P);
209-
}
210-
case high:
211-
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_720P)) {
212-
return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_720P);
213-
}
214-
case medium:
215-
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_480P)) {
216-
return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_480P);
217-
}
218-
case low:
219-
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_QVGA)) {
220-
return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_QVGA);
221-
}
222-
default:
223-
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_LOW)) {
224-
return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_LOW);
225-
}
226-
227-
throw new IllegalArgumentException(
228-
"No capture session available for current capture session.");
229-
}
230-
}
231-
232-
private void configureResolution(ResolutionPreset resolutionPreset, int cameraId)
233-
throws IndexOutOfBoundsException {
167+
private void configureResolution(ResolutionPreset resolutionPreset, int cameraId) {
234168
if (!checkIsSupported()) {
235169
return;
236170
}
237-
238-
if (Build.VERSION.SDK_INT >= 31) {
239-
recordingProfile =
240-
getBestAvailableCamcorderProfileForResolutionPreset(cameraId, resolutionPreset);
241-
List<EncoderProfiles.VideoProfile> videoProfiles = recordingProfile.getVideoProfiles();
242-
243-
EncoderProfiles.VideoProfile defaultVideoProfile = videoProfiles.get(0);
244-
captureSize = new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight());
245-
} else {
246-
@SuppressWarnings("deprecation")
247-
CamcorderProfile camcorderProfile =
248-
getBestAvailableCamcorderProfileForResolutionPresetLegacy(cameraId, resolutionPreset);
249-
recordingProfileLegacy = camcorderProfile;
250-
captureSize =
251-
new Size(recordingProfileLegacy.videoFrameWidth, recordingProfileLegacy.videoFrameHeight);
252-
}
253-
171+
recordingProfile =
172+
getBestAvailableCamcorderProfileForResolutionPreset(cameraId, resolutionPreset);
173+
captureSize = new Size(recordingProfile.videoFrameWidth, recordingProfile.videoFrameHeight);
254174
previewSize = computeBestPreviewSize(cameraId, resolutionPreset);
255175
}
256176
}

packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,35 @@
55
package io.flutter.plugins.camera.media;
66

77
import android.media.CamcorderProfile;
8-
import android.media.EncoderProfiles;
98
import android.media.MediaRecorder;
10-
import android.os.Build;
119
import androidx.annotation.NonNull;
1210
import java.io.IOException;
1311

1412
public class MediaRecorderBuilder {
15-
@SuppressWarnings("deprecation")
1613
static class MediaRecorderFactory {
1714
MediaRecorder makeMediaRecorder() {
1815
return new MediaRecorder();
1916
}
2017
}
2118

2219
private final String outputFilePath;
23-
private final CamcorderProfile camcorderProfile;
24-
private final EncoderProfiles encoderProfiles;
20+
private final CamcorderProfile recordingProfile;
2521
private final MediaRecorderFactory recorderFactory;
2622

2723
private boolean enableAudio;
2824
private int mediaOrientation;
2925

3026
public MediaRecorderBuilder(
31-
@NonNull CamcorderProfile camcorderProfile, @NonNull String outputFilePath) {
32-
this(camcorderProfile, outputFilePath, new MediaRecorderFactory());
33-
}
34-
35-
public MediaRecorderBuilder(
36-
@NonNull EncoderProfiles encoderProfiles, @NonNull String outputFilePath) {
37-
this(encoderProfiles, outputFilePath, new MediaRecorderFactory());
27+
@NonNull CamcorderProfile recordingProfile, @NonNull String outputFilePath) {
28+
this(recordingProfile, outputFilePath, new MediaRecorderFactory());
3829
}
3930

4031
MediaRecorderBuilder(
41-
@NonNull CamcorderProfile camcorderProfile,
32+
@NonNull CamcorderProfile recordingProfile,
4233
@NonNull String outputFilePath,
4334
MediaRecorderFactory helper) {
4435
this.outputFilePath = outputFilePath;
45-
this.camcorderProfile = camcorderProfile;
46-
this.encoderProfiles = null;
47-
this.recorderFactory = helper;
48-
}
49-
50-
MediaRecorderBuilder(
51-
@NonNull EncoderProfiles encoderProfiles,
52-
@NonNull String outputFilePath,
53-
MediaRecorderFactory helper) {
54-
this.outputFilePath = outputFilePath;
55-
this.encoderProfiles = encoderProfiles;
56-
this.camcorderProfile = null;
36+
this.recordingProfile = recordingProfile;
5737
this.recorderFactory = helper;
5838
}
5939

@@ -67,43 +47,23 @@ public MediaRecorderBuilder setMediaOrientation(int orientation) {
6747
return this;
6848
}
6949

70-
public MediaRecorder build() throws IOException, NullPointerException, IndexOutOfBoundsException {
50+
public MediaRecorder build() throws IOException {
7151
MediaRecorder mediaRecorder = recorderFactory.makeMediaRecorder();
7252

7353
// There's a fixed order that mediaRecorder expects. Only change these functions accordingly.
7454
// You can find the specifics here: https://developer.android.com/reference/android/media/MediaRecorder.
7555
if (enableAudio) mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
7656
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
77-
78-
if (Build.VERSION.SDK_INT >= 31) {
79-
EncoderProfiles.VideoProfile videoProfile = encoderProfiles.getVideoProfiles().get(0);
80-
EncoderProfiles.AudioProfile audioProfile = encoderProfiles.getAudioProfiles().get(0);
81-
82-
mediaRecorder.setOutputFormat(encoderProfiles.getRecommendedFileFormat());
83-
if (enableAudio) {
84-
mediaRecorder.setAudioEncoder(audioProfile.getCodec());
85-
mediaRecorder.setAudioEncodingBitRate(audioProfile.getBitrate());
86-
mediaRecorder.setAudioSamplingRate(audioProfile.getSampleRate());
87-
}
88-
mediaRecorder.setVideoEncoder(videoProfile.getCodec());
89-
mediaRecorder.setVideoEncodingBitRate(videoProfile.getBitrate());
90-
mediaRecorder.setVideoFrameRate(videoProfile.getFrameRate());
91-
mediaRecorder.setVideoSize(videoProfile.getWidth(), videoProfile.getHeight());
92-
mediaRecorder.setVideoSize(videoProfile.getWidth(), videoProfile.getHeight());
93-
} else {
94-
mediaRecorder.setOutputFormat(camcorderProfile.fileFormat);
95-
if (enableAudio) {
96-
mediaRecorder.setAudioEncoder(camcorderProfile.audioCodec);
97-
mediaRecorder.setAudioEncodingBitRate(camcorderProfile.audioBitRate);
98-
mediaRecorder.setAudioSamplingRate(camcorderProfile.audioSampleRate);
99-
}
100-
mediaRecorder.setVideoEncoder(camcorderProfile.videoCodec);
101-
mediaRecorder.setVideoEncodingBitRate(camcorderProfile.videoBitRate);
102-
mediaRecorder.setVideoFrameRate(camcorderProfile.videoFrameRate);
103-
mediaRecorder.setVideoSize(
104-
camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight);
57+
mediaRecorder.setOutputFormat(recordingProfile.fileFormat);
58+
if (enableAudio) {
59+
mediaRecorder.setAudioEncoder(recordingProfile.audioCodec);
60+
mediaRecorder.setAudioEncodingBitRate(recordingProfile.audioBitRate);
61+
mediaRecorder.setAudioSamplingRate(recordingProfile.audioSampleRate);
10562
}
106-
63+
mediaRecorder.setVideoEncoder(recordingProfile.videoCodec);
64+
mediaRecorder.setVideoEncodingBitRate(recordingProfile.videoBitRate);
65+
mediaRecorder.setVideoFrameRate(recordingProfile.videoFrameRate);
66+
mediaRecorder.setVideoSize(recordingProfile.videoFrameWidth, recordingProfile.videoFrameHeight);
10767
mediaRecorder.setOutputFile(outputFilePath);
10868
mediaRecorder.setOrientationHint(this.mediaOrientation);
10969

packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.hardware.camera2.CameraCaptureSession;
2323
import android.hardware.camera2.CameraMetadata;
2424
import android.hardware.camera2.CaptureRequest;
25+
import android.media.CamcorderProfile;
2526
import android.media.MediaRecorder;
2627
import android.os.Build;
2728
import android.os.Handler;
@@ -248,6 +249,20 @@ public void getMinZoomLevel() {
248249
assertEquals(expectedMinZoomLevel, actualMinZoomLevel, 0);
249250
}
250251

252+
@Test
253+
public void getRecordingProfile() {
254+
ResolutionFeature mockResolutionFeature =
255+
mockCameraFeatureFactory.createResolutionFeature(mockCameraProperties, null, null);
256+
CamcorderProfile mockCamcorderProfile = mock(CamcorderProfile.class);
257+
258+
when(mockResolutionFeature.getRecordingProfile()).thenReturn(mockCamcorderProfile);
259+
260+
CamcorderProfile actualRecordingProfile = camera.getRecordingProfile();
261+
262+
verify(mockResolutionFeature, times(1)).getRecordingProfile();
263+
assertEquals(mockCamcorderProfile, actualRecordingProfile);
264+
}
265+
251266
@Test
252267
public void setExposureMode_shouldUpdateExposureLockFeature() {
253268
ExposureLockFeature mockExposureLockFeature =

0 commit comments

Comments
 (0)