Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/camera/camera_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.10.4

* Temporarily fixes issue with requested video profiles being null by falling back to deprecated behavior in that case.

## 0.10.3

* Adds back use of Optional type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,11 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {

MediaRecorderBuilder mediaRecorderBuilder;

if (Build.VERSION.SDK_INT >= 31) {
mediaRecorderBuilder = new MediaRecorderBuilder(getRecordingProfile(), outputFilePath);
// TODO(camsim99): Revert changes that allow legacy code to be used when recordingProfile is null
// once this has largely been fixed on the Android side. https://github.com/flutter/flutter/issues/119668
EncoderProfiles recordingProfile = getRecordingProfile();
if (Build.VERSION.SDK_INT >= 31 && recordingProfile != null) {
Comment thread
camsim99 marked this conversation as resolved.
Outdated
mediaRecorderBuilder = new MediaRecorderBuilder(recordingProfile, outputFilePath);
} else {
mediaRecorderBuilder = new MediaRecorderBuilder(getRecordingProfileLegacy(), outputFilePath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,15 @@ static Size computeBestPreviewSize(int cameraId, ResolutionPreset preset)
List<EncoderProfiles.VideoProfile> videoProfiles = profile.getVideoProfiles();
EncoderProfiles.VideoProfile defaultVideoProfile = videoProfiles.get(0);

return new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight());
} else {
@SuppressWarnings("deprecation")
CamcorderProfile profile =
getBestAvailableCamcorderProfileForResolutionPresetLegacy(cameraId, preset);
return new Size(profile.videoFrameWidth, profile.videoFrameHeight);
if (defaultVideoProfile != null) {
return new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight());
}
}

@SuppressWarnings("deprecation")
Comment thread
reidbaker marked this conversation as resolved.
CamcorderProfile profile =
getBestAvailableCamcorderProfileForResolutionPresetLegacy(cameraId, preset);
return new Size(profile.videoFrameWidth, profile.videoFrameHeight);
}

/**
Expand Down Expand Up @@ -234,15 +236,24 @@ private void configureResolution(ResolutionPreset resolutionPreset, int cameraId
if (!checkIsSupported()) {
return;
}
boolean captureSizeCalculated = false;

if (Build.VERSION.SDK_INT >= 31) {
Comment thread
camsim99 marked this conversation as resolved.
Outdated
recordingProfileLegacy = null;
recordingProfile =
getBestAvailableCamcorderProfileForResolutionPreset(cameraId, resolutionPreset);
List<EncoderProfiles.VideoProfile> videoProfiles = recordingProfile.getVideoProfiles();

EncoderProfiles.VideoProfile defaultVideoProfile = videoProfiles.get(0);
captureSize = new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight());
} else {

if (defaultVideoProfile != null) {
captureSizeCalculated = true;
captureSize = new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight());
}
}

if (!captureSizeCalculated) {
recordingProfile = null;
@SuppressWarnings("deprecation")
CamcorderProfile camcorderProfile =
getBestAvailableCamcorderProfileForResolutionPresetLegacy(cameraId, resolutionPreset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public MediaRecorder build() throws IOException, NullPointerException, IndexOutO
if (enableAudio) mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);

if (Build.VERSION.SDK_INT >= 31) {
if (Build.VERSION.SDK_INT >= 31 && encoderProfiles != null) {
Comment thread
camsim99 marked this conversation as resolved.
Outdated
EncoderProfiles.VideoProfile videoProfile = encoderProfiles.getVideoProfiles().get(0);
EncoderProfiles.AudioProfile audioProfile = encoderProfiles.getAudioProfiles().get(0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,27 @@
package io.flutter.plugins.camera.features.resolution;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;

import android.media.CamcorderProfile;
import android.media.EncoderProfiles;
import android.util.Size;
import io.flutter.plugins.camera.CameraProperties;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockedStatic;
import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

Expand Down Expand Up @@ -329,4 +336,95 @@ public void computeBestPreviewSize_shouldUseQVGAWhenResolutionPresetLow() {

mockedStaticProfile.verify(() -> CamcorderProfile.getAll("1", CamcorderProfile.QUALITY_QVGA));
}

@Config(minSdk = 31)
Comment thread
reidbaker marked this conversation as resolved.
@Test
public void computeBestPreviewSize_shouldUseLegacyBehaviorWhenEncoderProfilesNull() {
try (MockedStatic<ResolutionFeature> mockedResolutionFeature =
mockStatic(ResolutionFeature.class)) {
mockedResolutionFeature
.when(
() ->
ResolutionFeature.getBestAvailableCamcorderProfileForResolutionPreset(
anyInt(), any(ResolutionPreset.class)))
.thenAnswer(
(Answer<EncoderProfiles>)
invocation -> {
EncoderProfiles mockEncoderProfiles = mock(EncoderProfiles.class);
List<EncoderProfiles.VideoProfile> videoProfiles =
new ArrayList<EncoderProfiles.VideoProfile>() {
{
add(null);
}
};
when(mockEncoderProfiles.getVideoProfiles()).thenReturn(videoProfiles);
return mockEncoderProfiles;
});
mockedResolutionFeature
.when(
() ->
ResolutionFeature.getBestAvailableCamcorderProfileForResolutionPresetLegacy(
anyInt(), any(ResolutionPreset.class)))
.thenAnswer(
(Answer<CamcorderProfile>)
invocation -> {
CamcorderProfile mockCamcorderProfile = mock(CamcorderProfile.class);
mockCamcorderProfile.videoFrameWidth = 10;
mockCamcorderProfile.videoFrameHeight = 50;
return mockCamcorderProfile;
});
mockedResolutionFeature
.when(() -> ResolutionFeature.computeBestPreviewSize(1, ResolutionPreset.max))
.thenCallRealMethod();

Size testPreviewSize = ResolutionFeature.computeBestPreviewSize(1, ResolutionPreset.max);
assertEquals(testPreviewSize.getWidth(), 10);
assertEquals(testPreviewSize.getHeight(), 50);
}
}

@Config(minSdk = 31)
@Test
public void resolutionFeatureShouldUseLegacyBehaviorWhenEncoderProfilesNull() {
beforeLegacy();
try (MockedStatic<ResolutionFeature> mockedResolutionFeature =
mockStatic(ResolutionFeature.class)) {
mockedResolutionFeature
.when(
() ->
ResolutionFeature.getBestAvailableCamcorderProfileForResolutionPreset(
anyInt(), any(ResolutionPreset.class)))
.thenAnswer(
(Answer<EncoderProfiles>)
invocation -> {
EncoderProfiles mockEncoderProfiles = mock(EncoderProfiles.class);
List<EncoderProfiles.VideoProfile> videoProfiles =
new ArrayList<EncoderProfiles.VideoProfile>() {
{
add(null);
}
};
when(mockEncoderProfiles.getVideoProfiles()).thenReturn(videoProfiles);
return mockEncoderProfiles;
});
mockedResolutionFeature
.when(
() ->
ResolutionFeature.getBestAvailableCamcorderProfileForResolutionPresetLegacy(
anyInt(), any(ResolutionPreset.class)))
.thenAnswer(
(Answer<CamcorderProfile>)
invocation -> {
CamcorderProfile mockCamcorderProfile = mock(CamcorderProfile.class);
return mockCamcorderProfile;
});

CameraProperties mockCameraProperties = mock(CameraProperties.class);
ResolutionFeature resolutionFeature =
new ResolutionFeature(mockCameraProperties, ResolutionPreset.max, cameraName);

assertNotNull(resolutionFeature.getRecordingProfileLegacy());
assertNull(resolutionFeature.getRecordingProfile());
}
}
}
2 changes: 1 addition & 1 deletion packages/camera/camera_android/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: camera_android
description: Android implementation of the camera plugin.
repository: https://github.com/flutter/plugins/tree/main/packages/camera/camera_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.10.3
version: 0.10.4
Comment thread
reidbaker marked this conversation as resolved.

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down