diff options
author | Tahsin Masrur <tahsinm@google.com> | 2024-04-25 18:28:26 +0800 |
---|---|---|
committer | Tahsin Masrur <tahsinm@google.com> | 2024-05-07 15:36:20 +0800 |
commit | edac2ff0f2ccf26228bf0cc602b1c48d33acf7de (patch) | |
tree | 44648ba25a5dbbda7dfdb44fff297dcb8ea34654 | |
parent | ef83e8c33448261d208e223ec6b349be2c3eebe5 (diff) | |
download | support-edac2ff0f2ccf26228bf0cc602b1c48d33acf7de.tar.gz |
Convert CaptureConfigTest and SessionConfigTest to host tests
Currently, they are device tests but don't have any device dependencies (uses fake/mock dependencies for surfaces). Converting them to host tests will ensure they are always run at AOSP presubmit if relevant code is changed.
Bug: N/A
Test: ./gradlew bOS
Change-Id: Ibdd138830dcc70b4fbc2f5b0d22b8ec47f8e3a05
4 files changed, 1618 insertions, 1460 deletions
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CaptureConfigTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CaptureConfigTest.java deleted file mode 100644 index be2063057ed..00000000000 --- a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CaptureConfigTest.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.camera.core.impl; - -import static androidx.camera.core.impl.Config.OptionPriority.REQUIRED; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.mock; - -import android.hardware.camera2.CameraDevice; -import android.util.Range; -import android.view.Surface; - -import androidx.annotation.NonNull; -import androidx.camera.core.impl.Config.Option; -import androidx.camera.testing.impl.DeferrableSurfacesUtil; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.LargeTest; -import androidx.test.filters.SdkSuppress; - -import com.google.common.collect.Lists; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Arrays; -import java.util.List; - -@LargeTest -@RunWith(AndroidJUnit4.class) -@SdkSuppress(minSdkVersion = 21) -public class CaptureConfigTest { - private static final Option<Integer> OPTION = Config.Option.create( - "camerax.test.option_0", Integer.class); - - private DeferrableSurface mMockSurface0; - private static final Config.Option<FakeMultiValueSet> FAKE_MULTI_VALUE_SET_OPTION = - Config.Option.create("option.fakeMultiValueSet.1", FakeMultiValueSet.class); - - @Before - public void setup() { - mMockSurface0 = mock(DeferrableSurface.class); - } - - @Test - public void builderSetTemplate() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - builder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - CaptureConfig captureConfig = builder.build(); - - assertThat(captureConfig.getTemplateType()).isEqualTo(CameraDevice.TEMPLATE_PREVIEW); - } - - @Test - public void builderNotSetTemplate() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - CaptureConfig captureConfig = builder.build(); - - assertThat(captureConfig.getTemplateType()).isEqualTo(CaptureConfig.TEMPLATE_TYPE_NONE); - } - - @Test - public void builderAddSurface() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - builder.addSurface(mMockSurface0); - CaptureConfig captureConfig = builder.build(); - - List<DeferrableSurface> surfaces = captureConfig.getSurfaces(); - - assertThat(surfaces).hasSize(1); - assertThat(surfaces).contains(mMockSurface0); - } - - @Test - public void builderRemoveSurface() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - builder.addSurface(mMockSurface0); - builder.removeSurface(mMockSurface0); - CaptureConfig captureConfig = builder.build(); - - List<Surface> surfaces = DeferrableSurfacesUtil.surfaceList(captureConfig.getSurfaces()); - assertThat(surfaces).isEmpty(); - } - - @Test - public void builderClearSurface() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - builder.addSurface(mMockSurface0); - builder.clearSurfaces(); - CaptureConfig captureConfig = builder.build(); - - List<Surface> surfaces = DeferrableSurfacesUtil.surfaceList(captureConfig.getSurfaces()); - assertThat(surfaces.size()).isEqualTo(0); - } - - @Test - public void builderAddOption() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - MutableOptionsBundle options = MutableOptionsBundle.create(); - options.insertOption(OPTION, 1); - builder.addImplementationOptions(options); - CaptureConfig captureConfig = builder.build(); - - Config config = captureConfig.getImplementationOptions(); - - assertThat(config.containsOption(OPTION)).isTrue(); - assertThat(config.retrieveOption(OPTION)).isEqualTo(1); - } - - @Test - public void addOption_priorityIsKept() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - MutableOptionsBundle options = MutableOptionsBundle.create(); - options.insertOption(OPTION, REQUIRED, 1); - builder.addImplementationOptions(options); - CaptureConfig captureConfig = builder.build(); - - Config config = captureConfig.getImplementationOptions(); - - assertThat(config.containsOption(OPTION)).isTrue(); - assertThat(config.retrieveOption(OPTION)).isEqualTo(1); - assertThat(config.getOptionPriority(OPTION)).isEqualTo(REQUIRED); - } - - @Test - public void builderSetUseTargetedSurface() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - builder.setUseRepeatingSurface(true); - CaptureConfig captureConfig = builder.build(); - - assertThat(captureConfig.isUseRepeatingSurface()).isTrue(); - } - - @Test - public void builderAddMultipleCameraCaptureCallbacks() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - CameraCaptureCallback callback0 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - - builder.addCameraCaptureCallback(callback0); - builder.addCameraCaptureCallback(callback1); - CaptureConfig configuration = builder.build(); - - assertThat(configuration.getCameraCaptureCallbacks()).containsExactly(callback0, callback1); - } - - @Test - public void builderAddAllCameraCaptureCallbacks() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - CameraCaptureCallback callback0 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - List<CameraCaptureCallback> callbacks = Lists.newArrayList(callback0, callback1); - - builder.addAllRepeatingCameraCaptureCallbacks(callbacks); - SessionConfig configuration = builder.build(); - - assertThat(configuration.getRepeatingCameraCaptureCallbacks()) - .containsExactly(callback0, callback1); - } - - @Test - public void builderAddImplementationMultiValue() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - Object obj1 = new Object(); - FakeMultiValueSet fakeMultiValueSet1 = new FakeMultiValueSet(); - fakeMultiValueSet1.addAll(Arrays.asList(obj1)); - MutableOptionsBundle fakeConfig1 = MutableOptionsBundle.create(); - fakeConfig1.insertOption(FAKE_MULTI_VALUE_SET_OPTION, fakeMultiValueSet1); - builder.addImplementationOptions(fakeConfig1); - - Object obj2 = new Object(); - FakeMultiValueSet fakeMultiValueSet2 = new FakeMultiValueSet(); - fakeMultiValueSet2.addAll(Arrays.asList(obj2)); - MutableOptionsBundle fakeConfig2 = MutableOptionsBundle.create(); - fakeConfig2.insertOption(FAKE_MULTI_VALUE_SET_OPTION, fakeMultiValueSet2); - builder.addImplementationOptions(fakeConfig2); - - CaptureConfig captureConfig = builder.build(); - - FakeMultiValueSet fakeMultiValueSet = - captureConfig.getImplementationOptions().retrieveOption( - FAKE_MULTI_VALUE_SET_OPTION); - - assertThat(fakeMultiValueSet).isNotNull(); - assertThat(fakeMultiValueSet.getAllItems()).containsExactly(obj1, obj2); - } - - @Test - public void builderAddSingleImplementationOption() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - builder.addImplementationOption(CaptureConfig.OPTION_ROTATION, 90); - - CaptureConfig captureConfig = builder.build(); - - assertThat(captureConfig.getImplementationOptions().retrieveOption( - CaptureConfig.OPTION_ROTATION)).isEqualTo(90); - } - - @Test - public void builderFromPrevious_containsCameraCaptureCallbacks() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - CameraCaptureCallback callback0 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - builder.addCameraCaptureCallback(callback0); - builder.addCameraCaptureCallback(callback1); - builder = CaptureConfig.Builder.from(builder.build()); - CameraCaptureCallback callback2 = mock(CameraCaptureCallback.class); - - builder.addCameraCaptureCallback(callback2); - CaptureConfig configuration = builder.build(); - - assertThat(configuration.getCameraCaptureCallbacks()) - .containsExactly(callback0, callback1, callback2); - } - - @Test - public void builderRemoveCameraCaptureCallback_returnsFalseIfNotAdded() { - CameraCaptureCallback mockCallback = mock(CameraCaptureCallback.class); - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - assertThat(builder.removeCameraCaptureCallback(mockCallback)).isFalse(); - } - - @Test - public void builderRemoveCameraCaptureCallback_removesAddedCallback() { - // Arrange. - CameraCaptureCallback mockCallback = mock(CameraCaptureCallback.class); - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - // Act. - builder.addCameraCaptureCallback(mockCallback); - CaptureConfig configWithCallback = builder.build(); - - // Assert. - assertThat(configWithCallback.getCameraCaptureCallbacks()).contains(mockCallback); - - // Act. - boolean removedCallback = builder.removeCameraCaptureCallback(mockCallback); - CaptureConfig configWithoutCallback = builder.build(); - - // Assert. - assertThat(removedCallback).isTrue(); - assertThat(configWithoutCallback.getCameraCaptureCallbacks()).doesNotContain(mockCallback); - } - - @Test(expected = UnsupportedOperationException.class) - public void cameraCaptureCallbacks_areImmutable() { - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - CaptureConfig configuration = builder.build(); - - configuration.getCameraCaptureCallbacks().add(mock(CameraCaptureCallback.class)); - } - - @Test - public void postviewEnabledDefaultIsFalse() { - // 1. Arrange / Act - CaptureConfig captureConfig = new CaptureConfig.Builder().build(); - - // 3. Assert - assertThat(captureConfig.isPostviewEnabled()).isFalse(); - } - - @Test - public void canSetPostviewEnabled() { - // 1. Arrange - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - - // 2. Act - builder.setPostviewEnabled(true); - CaptureConfig captureConfig = builder.build(); - - // 3. Assert - assertThat(captureConfig.isPostviewEnabled()).isTrue(); - - } - - @Test - public void builderChange_doNotChangeEarlierBuiltInstance() { - // 1. Arrange - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback2 = mock(CameraCaptureCallback.class); - DeferrableSurface deferrableSurface1 = mock(DeferrableSurface.class); - DeferrableSurface deferrableSurface2 = mock(DeferrableSurface.class); - Range<Integer> fpsRange1 = new Range<>(30, 30); - Range<Integer> fpsRange2 = new Range<>(15, 30); - int optionValue1 = 1; - int optionValue2 = 2; - int tagValue1 = 1; - int tagValue2 = 2; - int template1 = CameraDevice.TEMPLATE_PREVIEW; - int template2 = CameraDevice.TEMPLATE_RECORD; - - CaptureConfig.Builder builder = new CaptureConfig.Builder(); - builder.addSurface(deferrableSurface1); - builder.setExpectedFrameRateRange(fpsRange1); - builder.addCameraCaptureCallback(callback1); - builder.setTemplateType(template1); - builder.addTag("KEY", tagValue1); - builder.addImplementationOption(OPTION, optionValue1); - CaptureConfig captureConfig = builder.build(); - - // 2. Act - // builder change should not affect the instance built earlier. - builder.addSurface(deferrableSurface2); - builder.setExpectedFrameRateRange(fpsRange2); - builder.addCameraCaptureCallback(callback2); - builder.setTemplateType(template2); - builder.addTag("KEY", tagValue2); - builder.addImplementationOption(OPTION, optionValue2); - - // 3. Verify - assertThat(captureConfig.getSurfaces()).containsExactly(deferrableSurface1); - assertThat(captureConfig.getExpectedFrameRateRange()).isEqualTo(fpsRange1); - assertThat(captureConfig.getCameraCaptureCallbacks()).containsExactly(callback1); - assertThat(captureConfig.getTemplateType()).isEqualTo(template1); - assertThat(captureConfig.getTagBundle().getTag("KEY")).isEqualTo(tagValue1); - assertThat(captureConfig.getImplementationOptions().retrieveOption(OPTION)) - .isEqualTo(optionValue1); - } - - /** - * A fake {@link MultiValueSet}. - */ - static class FakeMultiValueSet extends MultiValueSet<Object> { - @NonNull - @Override - public MultiValueSet<Object> clone() { - FakeMultiValueSet multiValueSet = new FakeMultiValueSet(); - multiValueSet.addAll(getAllItems()); - return multiValueSet; - } - } -} diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/SessionConfigTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/SessionConfigTest.java deleted file mode 100644 index 5ae7d2d90a3..00000000000 --- a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/SessionConfigTest.java +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.camera.core.impl; - -import static androidx.camera.core.impl.SessionConfig.OutputConfig.SURFACE_GROUP_ID_NONE; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.mock; - -import android.hardware.camera2.CameraCaptureSession; -import android.hardware.camera2.CameraDevice; -import android.hardware.camera2.params.SessionConfiguration; -import android.util.Range; -import android.view.Surface; - -import androidx.camera.camera2.impl.Camera2ImplConfig; -import androidx.camera.core.ImageCapture; -import androidx.camera.core.Preview; -import androidx.camera.core.impl.Config.Option; -import androidx.camera.testing.impl.DeferrableSurfacesUtil; -import androidx.camera.testing.impl.fakes.FakeMultiValueSet; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.MediumTest; -import androidx.test.filters.SdkSuppress; - -import com.google.common.collect.Lists; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Arrays; -import java.util.List; - -@MediumTest -@RunWith(AndroidJUnit4.class) -@SdkSuppress(minSdkVersion = 21) -public class SessionConfigTest { - private static final Option<Integer> OPTION = Option.create( - "camerax.test.option_0", Integer.class); - private static final Option<String> OPTION_1 = Option.create( - "camerax.test.option_1", String.class); - private DeferrableSurface mMockSurface0; - private DeferrableSurface mMockSurface1; - - @Before - public void setup() { - mMockSurface0 = new ImmediateSurface(mock(Surface.class)); - mMockSurface1 = new ImmediateSurface(mock(Surface.class)); - } - - @After - public void tearDown() { - mMockSurface0.close(); - mMockSurface1.close(); - } - - @Test - public void builderSetTemplate() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - - builder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - SessionConfig sessionConfig = builder.build(); - - assertThat(sessionConfig.getTemplateType()).isEqualTo(CameraDevice.TEMPLATE_PREVIEW); - } - - @Test - public void builderAddSurface() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - - builder.addSurface(mMockSurface0); - SessionConfig sessionConfig = builder.build(); - - List<DeferrableSurface> surfaces = sessionConfig.getSurfaces(); - List<SessionConfig.OutputConfig> outputConfigs = sessionConfig.getOutputConfigs(); - - assertThat(surfaces).hasSize(1); - assertThat(surfaces).contains(mMockSurface0); - assertThat(outputConfigs).hasSize(1); - assertThat(outputConfigs.get(0).getSurface()).isEqualTo(mMockSurface0); - assertThat(outputConfigs.get(0).getSharedSurfaces()).isEmpty(); - assertThat(outputConfigs.get(0).getPhysicalCameraId()).isNull(); - assertThat(outputConfigs.get(0).getSurfaceGroupId()).isEqualTo(SURFACE_GROUP_ID_NONE); - } - - @Test - public void builderAddOutputConfig() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - DeferrableSurface sharedSurface1 = new ImmediateSurface(mock(Surface.class)); - DeferrableSurface sharedSurface2 = new ImmediateSurface(mock(Surface.class)); - SessionConfig.OutputConfig outputConfig = SessionConfig.OutputConfig.builder(mMockSurface0) - .setSurfaceGroupId(1) - .setSharedSurfaces(Arrays.asList(sharedSurface1, sharedSurface2)) - .setPhysicalCameraId("4") - .build(); - - builder.addOutputConfig(outputConfig); - SessionConfig sessionConfig = builder.build(); - - List<DeferrableSurface> surfaces = sessionConfig.getSurfaces(); - List<SessionConfig.OutputConfig> outputConfigs = sessionConfig.getOutputConfigs(); - - assertThat(surfaces).containsExactly(mMockSurface0, sharedSurface1, sharedSurface2); - assertThat(outputConfigs).hasSize(1); - assertThat(outputConfigs.get(0).getSurface()).isEqualTo(mMockSurface0); - assertThat(outputConfigs.get(0).getSharedSurfaces()) - .containsExactly(sharedSurface1, sharedSurface2); - assertThat(outputConfigs.get(0).getSurfaceGroupId()).isEqualTo(1); - assertThat(outputConfigs.get(0).getPhysicalCameraId()).isEqualTo("4"); - } - - @Test - public void builderAddNonRepeatingSurface() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - - builder.addNonRepeatingSurface(mMockSurface0); - SessionConfig sessionConfig = builder.build(); - - List<DeferrableSurface> surfaces = sessionConfig.getSurfaces(); - List<SessionConfig.OutputConfig> outputConfigs = sessionConfig.getOutputConfigs(); - List<DeferrableSurface> repeatingSurfaces = - sessionConfig.getRepeatingCaptureConfig().getSurfaces(); - - assertThat(surfaces).containsExactly(mMockSurface0); - assertThat(outputConfigs).hasSize(1); - assertThat(outputConfigs.get(0).getSurface()).isEqualTo(mMockSurface0); - assertThat(repeatingSurfaces).isEmpty(); - assertThat(repeatingSurfaces).doesNotContain(mMockSurface0); - } - - @Test - public void builderAddSurfaceContainsRepeatingSurface() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - - builder.addSurface(mMockSurface0); - builder.addNonRepeatingSurface(mMockSurface1); - SessionConfig sessionConfig = builder.build(); - - List<Surface> surfaces = DeferrableSurfacesUtil.surfaceList(sessionConfig.getSurfaces()); - List<Surface> repeatingSurfaces = DeferrableSurfacesUtil.surfaceList( - sessionConfig.getRepeatingCaptureConfig().getSurfaces()); - - assertThat(surfaces.size()).isAtLeast(repeatingSurfaces.size()); - assertThat(surfaces).containsAtLeastElementsIn(repeatingSurfaces); - } - - @Test - public void builderRemoveSurface() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - - builder.addSurface(mMockSurface0); - builder.addSurface(mMockSurface1); - builder.removeSurface(mMockSurface0); - SessionConfig sessionConfig = builder.build(); - - assertThat(sessionConfig.getSurfaces()).containsExactly(mMockSurface1); - assertThat(sessionConfig.getOutputConfigs()).hasSize(1); - assertThat(sessionConfig.getOutputConfigs().get(0).getSurface()).isEqualTo(mMockSurface1); - } - - @Test - public void builderClearSurface() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - - builder.addSurface(mMockSurface0); - builder.clearSurfaces(); - SessionConfig sessionConfig = builder.build(); - - assertThat(sessionConfig.getSurfaces()).isEmpty(); - assertThat(sessionConfig.getOutputConfigs()).isEmpty(); - } - - @Test - public void builderAddOption() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - - MutableOptionsBundle options = MutableOptionsBundle.create(); - options.insertOption(OPTION, 1); - builder.addImplementationOptions(options); - SessionConfig sessionConfig = builder.build(); - - Config config = sessionConfig.getImplementationOptions(); - - assertThat(config.containsOption(OPTION)).isTrue(); - assertThat(config.retrieveOption(OPTION)).isEqualTo(1); - } - - @Test - public void builderDefaultSessionTypeIsRegular() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - SessionConfig sessionConfig = builder.build(); - assertThat(sessionConfig.getSessionType() == SessionConfiguration.SESSION_REGULAR); - } - - @Test - public void builderSetSessionType() { - SessionConfig.Builder builder = new SessionConfig.Builder() - .setSessionType(2); - SessionConfig sessionConfig = builder.build(); - assertThat(sessionConfig.getSessionType() == 2); - } - - @Test - public void builderSetPostviewSurface() { - SessionConfig.Builder builder = new SessionConfig.Builder() - .setPostviewSurface(mMockSurface0); - SessionConfig sessionConfig = builder.build(); - assertThat(sessionConfig.getPostviewOutputConfig().getSurface()).isEqualTo(mMockSurface0); - } - - @Test - public void prioritizeTemplateType_previewHigherThanUnsupportedType() { - SessionConfig.Builder builderPreview = new SessionConfig.Builder(); - builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - SessionConfig sessionConfigPreview = builderPreview.build(); - SessionConfig.Builder builderManual = new SessionConfig.Builder(); - builderManual.setTemplateType(CameraDevice.TEMPLATE_MANUAL); - SessionConfig sessionConfigManual = builderManual.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - - validatingBuilder.add(sessionConfigPreview); - validatingBuilder.add(sessionConfigManual); - - assertThat(validatingBuilder.isValid()).isTrue(); - - assertThat(validatingBuilder.build().getTemplateType()).isEqualTo( - CameraDevice.TEMPLATE_PREVIEW); - } - - @Test - public void prioritizeTemplateType_recordHigherThanPreview() { - SessionConfig.Builder builderPreview = new SessionConfig.Builder(); - builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - SessionConfig sessionConfigPreview = builderPreview.build(); - SessionConfig.Builder builderRecord = new SessionConfig.Builder(); - builderRecord.setTemplateType(CameraDevice.TEMPLATE_RECORD); - SessionConfig sessionConfigRecord = builderRecord.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - - validatingBuilder.add(sessionConfigPreview); - validatingBuilder.add(sessionConfigRecord); - - assertThat(validatingBuilder.isValid()).isTrue(); - - assertThat(validatingBuilder.build().getTemplateType()).isEqualTo( - CameraDevice.TEMPLATE_RECORD); - } - - @Test - public void prioritizeTemplateType_addZslFirst_zslHigherThanPreview() { - SessionConfig.Builder builderZsl = new SessionConfig.Builder(); - builderZsl.setTemplateType(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); - SessionConfig sessionConfigZsl = builderZsl.build(); - - SessionConfig.Builder builderPreview = new SessionConfig.Builder(); - builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - SessionConfig sessionConfigPreview = builderPreview.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - - validatingBuilder.add(sessionConfigZsl); - validatingBuilder.add(sessionConfigPreview); - - assertThat(validatingBuilder.isValid()).isTrue(); - - assertThat(validatingBuilder.build().getTemplateType()).isEqualTo( - CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); - } - - @Test - public void prioritizeTemplateType_addPreviewFirst_zslHigherThanPreview() { - SessionConfig.Builder builderZsl = new SessionConfig.Builder(); - builderZsl.setTemplateType(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); - SessionConfig sessionConfigZsl = builderZsl.build(); - - SessionConfig.Builder builderPreview = new SessionConfig.Builder(); - builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - SessionConfig sessionConfigPreview = builderPreview.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - - validatingBuilder.add(sessionConfigPreview); - validatingBuilder.add(sessionConfigZsl); - - assertThat(validatingBuilder.isValid()).isTrue(); - - assertThat(validatingBuilder.build().getTemplateType()).isEqualTo( - CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); - } - - @Test - public void setAndVerifyExpectedFrameRateRange_nullValue() { - SessionConfig.Builder builderPreview = new SessionConfig.Builder(); - builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - SessionConfig sessionConfigPreview = builderPreview.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - - validatingBuilder.add(sessionConfigPreview); - - assertThat(validatingBuilder.isValid()).isTrue(); - - assertThat(validatingBuilder.build().getExpectedFrameRateRange()).isEqualTo( - StreamSpec.FRAME_RATE_RANGE_UNSPECIFIED); - } - - @Test - public void setAndVerifyExpectedFrameRateRange_initialValue() { - Range<Integer> fpsRangeLow = new Range<>(30, 45); - SessionConfig.Builder builderPreview = new SessionConfig.Builder(); - builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - builderPreview.setExpectedFrameRateRange(fpsRangeLow); - SessionConfig sessionConfigPreview = builderPreview.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - - validatingBuilder.add(sessionConfigPreview); - - assertThat(validatingBuilder.isValid()).isTrue(); - - assertThat(validatingBuilder.build().getExpectedFrameRateRange()).isEqualTo( - fpsRangeLow); - } - - @Test - public void setAndVerifyExpectedFrameRateRange_sameValues() { - Range<Integer> fpsRangeLow = new Range<>(30, 45); - SessionConfig.Builder builderZsl = new SessionConfig.Builder(); - builderZsl.setTemplateType(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); - builderZsl.setExpectedFrameRateRange(fpsRangeLow); - SessionConfig sessionConfigZsl = builderZsl.build(); - - SessionConfig.Builder builderPreview = new SessionConfig.Builder(); - builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - builderPreview.setExpectedFrameRateRange(fpsRangeLow); - SessionConfig sessionConfigPreview = builderPreview.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - - validatingBuilder.add(sessionConfigPreview); - validatingBuilder.add(sessionConfigZsl); - - assertThat(validatingBuilder.isValid()).isTrue(); - - assertThat(validatingBuilder.build().getExpectedFrameRateRange()).isEqualTo( - fpsRangeLow); - } - - @Test - public void setAndVerifyExpectedFrameRateRange_differentValues() { - Range<Integer> fpsRangeLow = new Range<>(30, 45); - Range<Integer> fpsRangeHigh = new Range<>(45, 60); - SessionConfig.Builder builderZsl = new SessionConfig.Builder(); - builderZsl.setTemplateType(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); - builderZsl.setExpectedFrameRateRange(fpsRangeLow); - SessionConfig sessionConfigZsl = builderZsl.build(); - - SessionConfig.Builder builderPreview = new SessionConfig.Builder(); - builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - builderPreview.setExpectedFrameRateRange(fpsRangeHigh); - SessionConfig sessionConfigPreview = builderPreview.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - - validatingBuilder.add(sessionConfigPreview); - validatingBuilder.add(sessionConfigZsl); - - assertThat(validatingBuilder.isValid()).isFalse(); - } - - @Test - public void addImplementationOptionForStreamUseCase() { - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - assertThat(!validatingBuilder.build().getImplementationOptions().containsOption( - Camera2ImplConfig.STREAM_USE_CASE_OPTION)); - validatingBuilder.addImplementationOption(Camera2ImplConfig.STREAM_USE_CASE_OPTION, 1L); - assertThat(validatingBuilder.build().getImplementationOptions().retrieveOption( - Camera2ImplConfig.STREAM_USE_CASE_OPTION) == 1L); - } - - @Test - public void addDifferentNonDefaultSessionType() { - // 1. Arrange. - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - SessionConfig sessionConfig1 = new SessionConfig.Builder() - .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) - .setSessionType(1).build(); - SessionConfig sessionConfig2 = new SessionConfig.Builder() - .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) - .setSessionType(2).build(); - - // 2. Act. - validatingBuilder.add(sessionConfig1); - validatingBuilder.add(sessionConfig2); - - // 3. Assert. - assertThat(validatingBuilder.isValid()).isFalse(); - } - - @Test - public void addDefaultAndThenNonDefaultSessionType() { - // 1. Arrange. - final int sessionTypeToVerify = 2; - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - SessionConfig sessionConfig1 = new SessionConfig.Builder() - .setTemplateType(CameraDevice.TEMPLATE_PREVIEW).build(); - SessionConfig sessionConfig2 = new SessionConfig.Builder() - .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) - .setSessionType(sessionTypeToVerify).build(); - - // 2. Act. - validatingBuilder.add(sessionConfig1); - validatingBuilder.add(sessionConfig2); - - // 3. Assert. - assertThat(validatingBuilder.build().getSessionType()).isEqualTo(sessionTypeToVerify); - assertThat(validatingBuilder.isValid()).isTrue(); - } - - @Test - public void addNonDefaultAndThenDefaultSessionType() { - // 1. Arrange. - final int sessionTypeToVerify = 2; - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - SessionConfig sessionConfig1 = new SessionConfig.Builder() - .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) - .setSessionType(sessionTypeToVerify).build(); - SessionConfig sessionConfig2 = new SessionConfig.Builder() - .setTemplateType(CameraDevice.TEMPLATE_PREVIEW).build(); - - // 2. Act. - validatingBuilder.add(sessionConfig1); - validatingBuilder.add(sessionConfig2); - - // 3. Assert. - assertThat(validatingBuilder.build().getSessionType()).isEqualTo(sessionTypeToVerify); - assertThat(validatingBuilder.isValid()).isTrue(); - } - - @Test - public void addPostviewSurfaceTo_validatingBuilder() { - // 1. Arrange. - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - SessionConfig sessionConfig1 = new SessionConfig.Builder() - .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) - .setPostviewSurface(mMockSurface0) - .build(); - - // 2. Act. - validatingBuilder.add(sessionConfig1); - - // 3. Assert. - assertThat(validatingBuilder.build().getPostviewOutputConfig().getSurface()) - .isEqualTo(mMockSurface0); - assertThat(validatingBuilder.isValid()).isTrue(); - } - - @Test - public void addDifferentPostviewSurfacesTo_validatingBuilder() { - // 1. Arrange. - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - SessionConfig sessionConfig1 = new SessionConfig.Builder() - .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) - .setPostviewSurface(mMockSurface0) - .build(); - SessionConfig sessionConfig2 = new SessionConfig.Builder() - .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) - .setPostviewSurface(mMockSurface1) - .build(); - - // 2. Act. - validatingBuilder.add(sessionConfig1); - validatingBuilder.add(sessionConfig2); - - // 3. Assert. - assertThat(validatingBuilder.isValid()).isFalse(); - } - - @Test - public void conflictingOptions() { - SessionConfig.Builder builder0 = new SessionConfig.Builder(); - MutableOptionsBundle options0 = MutableOptionsBundle.create(); - options0.insertOption(OPTION, 1); - builder0.addImplementationOptions(options0); - SessionConfig config0 = builder0.build(); - - SessionConfig.Builder builder1 = new SessionConfig.Builder(); - MutableOptionsBundle options1 = MutableOptionsBundle.create(); - options1.insertOption(OPTION, 2); - builder1.addImplementationOptions(options1); - SessionConfig config1 = builder1.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - - validatingBuilder.add(config0); - validatingBuilder.add(config1); - - assertThat(validatingBuilder.isValid()).isFalse(); - } - - @Test - public void combineTwoSessionsValid() { - SessionConfig.Builder builder0 = new SessionConfig.Builder(); - builder0.addSurface(mMockSurface0); - builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - MutableOptionsBundle options0 = MutableOptionsBundle.create(); - options0.insertOption(OPTION, 1); - builder0.addImplementationOptions(options0); - - SessionConfig.Builder builder1 = new SessionConfig.Builder(); - builder1.addSurface(mMockSurface1); - builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - MutableOptionsBundle options1 = MutableOptionsBundle.create(); - options1.insertOption(OPTION_1, "test"); - builder1.addImplementationOptions(options1); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - validatingBuilder.add(builder0.build()); - validatingBuilder.add(builder1.build()); - - assertThat(validatingBuilder.isValid()).isTrue(); - } - - @Test - public void combineTwoSessionsTemplate() { - SessionConfig.Builder builder0 = new SessionConfig.Builder(); - builder0.addSurface(mMockSurface0); - builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - MutableOptionsBundle options0 = MutableOptionsBundle.create(); - options0.insertOption(OPTION, 1); - builder0.addImplementationOptions(options0); - - SessionConfig.Builder builder1 = new SessionConfig.Builder(); - builder1.addSurface(mMockSurface1); - builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - MutableOptionsBundle options1 = MutableOptionsBundle.create(); - options1.insertOption(OPTION_1, "test"); - builder1.addImplementationOptions(options1); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - validatingBuilder.add(builder0.build()); - validatingBuilder.add(builder1.build()); - - SessionConfig sessionConfig = validatingBuilder.build(); - - assertThat(sessionConfig.getTemplateType()).isEqualTo(CameraDevice.TEMPLATE_PREVIEW); - } - - private DeferrableSurface createSurface(Class<?> containerClass) { - DeferrableSurface deferrableSurface = new ImmediateSurface(mock(Surface.class)); - deferrableSurface.setContainerClass(containerClass); - return deferrableSurface; - } - - @Test - public void combineTwoSessionsSurfaces() { - DeferrableSurface previewSurface = createSurface(Preview.class); - DeferrableSurface imageCaptureSurface = createSurface(ImageCapture.class); - - SessionConfig.Builder builder1 = new SessionConfig.Builder(); - builder1.addSurface(previewSurface); - builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - - SessionConfig.Builder builder2 = new SessionConfig.Builder(); - builder2.addSurface(imageCaptureSurface); - builder2.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - validatingBuilder.add(builder1.build()); - validatingBuilder.add(builder2.build()); - - SessionConfig sessionConfig = validatingBuilder.build(); - - List<DeferrableSurface> surfaces = sessionConfig.getSurfaces(); - // Ensures the surfaces are all added and sorted correctly. - assertThat(surfaces).containsExactly(previewSurface, imageCaptureSurface).inOrder(); - } - - @Test - public void combineTwoSessionsOutputConfigs() { - DeferrableSurface nonRepeatingSurface = mock(DeferrableSurface.class); - - SessionConfig.Builder builder0 = new SessionConfig.Builder(); - SessionConfig.OutputConfig outputConfig0 = - SessionConfig.OutputConfig.builder(mMockSurface0).build(); - builder0.addOutputConfig(outputConfig0); - builder0.addNonRepeatingSurface(nonRepeatingSurface); - builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - - SessionConfig.Builder builder1 = new SessionConfig.Builder(); - SessionConfig.OutputConfig outputConfig1 = - SessionConfig.OutputConfig.builder(mMockSurface1).build(); - builder1.addOutputConfig(outputConfig1); - builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - validatingBuilder.add(builder0.build()); - validatingBuilder.add(builder1.build()); - - SessionConfig sessionConfig = validatingBuilder.build(); - - List<DeferrableSurface> surfaces = sessionConfig.getSurfaces(); - assertThat(surfaces).containsExactly(mMockSurface0, mMockSurface1, nonRepeatingSurface); - assertThat(sessionConfig.getOutputConfigs()).hasSize(3); - assertThat(sessionConfig.getOutputConfigs().get(0)).isEqualTo(outputConfig0); - assertThat(sessionConfig.getOutputConfigs().get(1).getSurface()) - .isEqualTo(nonRepeatingSurface); - assertThat(sessionConfig.getOutputConfigs().get(2)).isEqualTo(outputConfig1); - // Should not contain the nonRepeatingSurface. - assertThat(sessionConfig.getRepeatingCaptureConfig().getSurfaces()) - .containsExactly(mMockSurface0, mMockSurface1); - } - - @Test - public void combineTwoSessionsOptions() { - SessionConfig.Builder builder0 = new SessionConfig.Builder(); - builder0.addSurface(mMockSurface0); - builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - MutableOptionsBundle options0 = MutableOptionsBundle.create(); - options0.insertOption(OPTION, 1); - builder0.addImplementationOptions(options0); - - SessionConfig.Builder builder1 = new SessionConfig.Builder(); - builder1.addSurface(mMockSurface1); - builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - MutableOptionsBundle options1 = MutableOptionsBundle.create(); - options1.insertOption(OPTION_1, "test"); - builder1.addImplementationOptions(options1); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - validatingBuilder.add(builder0.build()); - validatingBuilder.add(builder1.build()); - - SessionConfig sessionConfig = validatingBuilder.build(); - - Config config = sessionConfig.getImplementationOptions(); - - assertThat(config.retrieveOption(OPTION)).isEqualTo(1); - assertThat(config.retrieveOption(OPTION_1)).isEqualTo("test"); - } - - @Test - public void combineTwoSessionsMultiValueSetValid() { - Option<FakeMultiValueSet> option = Option.create("multiValueSet", FakeMultiValueSet.class); - - SessionConfig.Builder builder0 = new SessionConfig.Builder(); - builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - MutableOptionsBundle options0 = MutableOptionsBundle.create(); - FakeMultiValueSet multiValueSet0 = new FakeMultiValueSet(); - options0.insertOption(option, multiValueSet0); - builder0.addImplementationOptions(options0); - SessionConfig config0 = builder0.build(); - - SessionConfig.Builder builder1 = new SessionConfig.Builder(); - MutableOptionsBundle options1 = MutableOptionsBundle.create(); - FakeMultiValueSet multiValueSet1 = new FakeMultiValueSet(); - options1.insertOption(option, multiValueSet1); - builder1.addImplementationOptions(options1); - SessionConfig config1 = builder1.build(); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - validatingBuilder.add(config0); - validatingBuilder.add(config1); - - assertThat(validatingBuilder.isValid()).isTrue(); - } - - @Test - public void builderAddMultipleRepeatingCameraCaptureCallbacks() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - CameraCaptureCallback callback0 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - - builder.addRepeatingCameraCaptureCallback(callback0); - builder.addRepeatingCameraCaptureCallback(callback1); - SessionConfig configuration = builder.build(); - - assertThat(configuration.getRepeatingCameraCaptureCallbacks()) - .containsExactly(callback0, callback1); - assertThat(configuration.getSingleCameraCaptureCallbacks()) - .containsNoneOf(callback0, callback1); - } - - @Test - public void builderAddAllRepeatingCameraCaptureCallbacks() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - CameraCaptureCallback callback0 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - List<CameraCaptureCallback> callbacks = Lists.newArrayList(callback0, callback1); - - builder.addAllRepeatingCameraCaptureCallbacks(callbacks); - SessionConfig configuration = builder.build(); - - assertThat(configuration.getRepeatingCameraCaptureCallbacks()) - .containsExactly(callback0, callback1); - assertThat(configuration.getSingleCameraCaptureCallbacks()) - .containsNoneOf(callback0, callback1); - } - - @Test(expected = UnsupportedOperationException.class) - public void repeatingCameraCaptureCallbacks_areImmutable() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - SessionConfig configuration = builder.build(); - - configuration.getRepeatingCameraCaptureCallbacks().add(mock(CameraCaptureCallback.class)); - } - - @Test - public void builderAddMultipleDeviceStateCallbacks() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - CameraDevice.StateCallback callback0 = mock(CameraDevice.StateCallback.class); - CameraDevice.StateCallback callback1 = mock(CameraDevice.StateCallback.class); - - builder.addDeviceStateCallback(callback0); - builder.addDeviceStateCallback(callback1); - SessionConfig configuration = builder.build(); - - assertThat(configuration.getDeviceStateCallbacks()).containsExactly(callback0, callback1); - } - - @Test - public void builderAddAllDeviceStateCallbacks() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - CameraDevice.StateCallback callback0 = mock(CameraDevice.StateCallback.class); - CameraDevice.StateCallback callback1 = mock(CameraDevice.StateCallback.class); - List<CameraDevice.StateCallback> callbacks = Lists.newArrayList(callback0, callback1); - - builder.addAllDeviceStateCallbacks(callbacks); - SessionConfig configuration = builder.build(); - - assertThat(configuration.getDeviceStateCallbacks()).containsExactly(callback0, callback1); - } - - @Test(expected = UnsupportedOperationException.class) - public void deviceStateCallbacks_areImmutable() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - SessionConfig configuration = builder.build(); - - configuration.getDeviceStateCallbacks().add(mock(CameraDevice.StateCallback.class)); - } - - @Test - public void builderAddMultipleSessionStateCallbacks() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - CameraCaptureSession.StateCallback callback0 = - mock(CameraCaptureSession.StateCallback.class); - CameraCaptureSession.StateCallback callback1 = - mock(CameraCaptureSession.StateCallback.class); - - builder.addSessionStateCallback(callback0); - builder.addSessionStateCallback(callback1); - SessionConfig configuration = builder.build(); - - assertThat(configuration.getSessionStateCallbacks()).containsExactly(callback0, callback1); - } - - @Test - public void builderAddAllSessionStateCallbacks() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - CameraCaptureSession.StateCallback callback0 = - mock(CameraCaptureSession.StateCallback.class); - CameraCaptureSession.StateCallback callback1 = - mock(CameraCaptureSession.StateCallback.class); - List<CameraCaptureSession.StateCallback> callbacks = - Lists.newArrayList(callback0, callback1); - - builder.addAllSessionStateCallbacks(callbacks); - SessionConfig configuration = builder.build(); - - assertThat(configuration.getSessionStateCallbacks()).containsExactly(callback0, callback1); - } - - @Test(expected = UnsupportedOperationException.class) - public void sessionStateCallbacks_areImmutable() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - SessionConfig configuration = builder.build(); - - configuration.getSessionStateCallbacks() - .add(mock(CameraCaptureSession.StateCallback.class)); - } - - @Test - public void builderAddMultipleCameraCallbacks() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - CameraCaptureCallback callback0 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - - builder.addCameraCaptureCallback(callback0); - builder.addCameraCaptureCallback(callback1); - SessionConfig configuration = builder.build(); - - assertThat(configuration.getSingleCameraCaptureCallbacks()) - .containsExactly(callback0, callback1); - assertThat(configuration.getRepeatingCameraCaptureCallbacks()) - .containsExactly(callback0, callback1); - } - - @Test - public void builderAddAllCameraCallbacks() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - CameraCaptureCallback callback0 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - List<CameraCaptureCallback> callbacks = Lists.newArrayList(callback0, callback1); - - builder.addAllCameraCaptureCallbacks(callbacks); - SessionConfig configuration = builder.build(); - - assertThat(configuration.getSingleCameraCaptureCallbacks()) - .containsExactly(callback0, callback1); - assertThat(configuration.getRepeatingCameraCaptureCallbacks()) - .containsExactly(callback0, callback1); - } - - @Test - public void removeCameraCaptureCallback_returnsFalseIfNotAdded() { - CameraCaptureCallback mockCallback = mock(CameraCaptureCallback.class); - SessionConfig.Builder builder = new SessionConfig.Builder(); - - assertThat(builder.removeCameraCaptureCallback(mockCallback)).isFalse(); - } - - @Test - public void canAddAndRemoveCameraCaptureCallback_withBuilder() { - // Arrange. - CameraCaptureCallback mockRepeatingCallback = mock(CameraCaptureCallback.class); - CameraCaptureCallback mockSingleCallback = mock(CameraCaptureCallback.class); - SessionConfig.Builder builder = new SessionConfig.Builder(); - - // Act. - builder.addRepeatingCameraCaptureCallback(mockRepeatingCallback); - builder.addCameraCaptureCallback(mockSingleCallback); - SessionConfig sessionConfigWithCallbacks = builder.build(); - - // Assert. - assertThat(sessionConfigWithCallbacks.getSingleCameraCaptureCallbacks()).contains( - mockSingleCallback); - assertThat(sessionConfigWithCallbacks.getSingleCameraCaptureCallbacks()).contains( - mockSingleCallback); - - // Act. - boolean removedSingle = builder.removeCameraCaptureCallback(mockSingleCallback); - SessionConfig sessionConfigWithoutSingleCallback = builder.build(); - - // Assert. - assertThat(removedSingle).isTrue(); - assertThat(sessionConfigWithoutSingleCallback.getSingleCameraCaptureCallbacks()) - .doesNotContain(mockSingleCallback); - - // Act. - boolean removedRepeating = builder.removeCameraCaptureCallback(mockRepeatingCallback); - SessionConfig sessionConfigWithoutCallbacks = builder.build(); - - // Assert. - assertThat(removedRepeating).isTrue(); - assertThat( - sessionConfigWithoutCallbacks.getRepeatingCameraCaptureCallbacks()).doesNotContain( - mockRepeatingCallback); - } - - @Test(expected = UnsupportedOperationException.class) - public void singleCameraCaptureCallbacks_areImmutable() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - SessionConfig configuration = builder.build(); - - configuration.getSingleCameraCaptureCallbacks().add(mock(CameraCaptureCallback.class)); - } - - @Test - public void builderAddErrorListener() { - SessionConfig.Builder builder = new SessionConfig.Builder(); - SessionConfig.ErrorListener callback = mock(SessionConfig.ErrorListener.class); - - builder.addErrorListener(callback); - - SessionConfig config = builder.build(); - - assertThat(config.getErrorListeners()).contains(callback); - } - - @Test - public void combineTwoSessionsCallbacks() { - SessionConfig.Builder builder0 = new SessionConfig.Builder(); - CameraCaptureSession.StateCallback sessionCallback0 = - mock(CameraCaptureSession.StateCallback.class); - CameraDevice.StateCallback deviceCallback0 = mock(CameraDevice.StateCallback.class); - CameraCaptureCallback repeatingCallback0 = mock(CameraCaptureCallback.class); - CameraCaptureCallback cameraCallback0 = mock(CameraCaptureCallback.class); - SessionConfig.ErrorListener errorListener0 = mock(SessionConfig.ErrorListener.class); - builder0.addSessionStateCallback(sessionCallback0); - builder0.addDeviceStateCallback(deviceCallback0); - builder0.addRepeatingCameraCaptureCallback(repeatingCallback0); - builder0.addCameraCaptureCallback(cameraCallback0); - builder0.addErrorListener(errorListener0); - - SessionConfig.Builder builder1 = new SessionConfig.Builder(); - CameraCaptureSession.StateCallback sessionCallback1 = - mock(CameraCaptureSession.StateCallback.class); - CameraDevice.StateCallback deviceCallback1 = mock(CameraDevice.StateCallback.class); - CameraCaptureCallback repeatingCallback1 = mock(CameraCaptureCallback.class); - CameraCaptureCallback cameraCallback1 = mock(CameraCaptureCallback.class); - SessionConfig.ErrorListener errorListener1 = mock(SessionConfig.ErrorListener.class); - builder1.addSessionStateCallback(sessionCallback1); - builder1.addDeviceStateCallback(deviceCallback1); - builder1.addRepeatingCameraCaptureCallback(repeatingCallback1); - builder1.addCameraCaptureCallback(cameraCallback1); - builder1.addErrorListener(errorListener1); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - validatingBuilder.add(builder0.build()); - validatingBuilder.add(builder1.build()); - - SessionConfig sessionConfig = validatingBuilder.build(); - - assertThat(sessionConfig.getSessionStateCallbacks()) - .containsExactly(sessionCallback0, sessionCallback1); - assertThat(sessionConfig.getDeviceStateCallbacks()) - .containsExactly(deviceCallback0, deviceCallback1); - assertThat(sessionConfig.getRepeatingCameraCaptureCallbacks()) - .containsExactly( - repeatingCallback0, cameraCallback0, repeatingCallback1, cameraCallback1); - assertThat(sessionConfig.getSingleCameraCaptureCallbacks()) - .containsExactly(cameraCallback0, cameraCallback1); - assertThat(sessionConfig.getErrorListeners()).containsExactly(errorListener0, - errorListener1); - } - - @Test - public void combineTwoSessionsTagsValid() { - SessionConfig session0 = createSessionConfigWithTag("TEST00", 0); - SessionConfig session1 = createSessionConfigWithTag("TEST01", "String"); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - validatingBuilder.add(session0); - validatingBuilder.add(session1); - - SessionConfig sessionCombined = validatingBuilder.build(); - - assertThat(validatingBuilder.isValid()).isTrue(); - - TagBundle tag = sessionCombined.getRepeatingCaptureConfig().getTagBundle(); - - assertThat(tag.getTag("TEST00")).isEqualTo(0); - assertThat(tag.getTag("TEST01")).isEqualTo("String"); - } - - @Test - public void builderChange_doNotChangeEarlierBuiltInstance() { - // 1. Arrange - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback2 = mock(CameraCaptureCallback.class); - DeferrableSurface deferrableSurface1 = mock(DeferrableSurface.class); - DeferrableSurface deferrableSurface2 = mock(DeferrableSurface.class); - CameraDevice.StateCallback deviceStateCallback1 = mock(CameraDevice.StateCallback.class); - CameraDevice.StateCallback deviceStateCallback2 = mock(CameraDevice.StateCallback.class); - CameraCaptureSession.StateCallback sessionCallback1 = - mock(CameraCaptureSession.StateCallback.class); - CameraCaptureSession.StateCallback sessionCallback2 = - mock(CameraCaptureSession.StateCallback.class); - SessionConfig.ErrorListener errorListener1 = mock(SessionConfig.ErrorListener.class); - SessionConfig.ErrorListener errorListener2 = mock(SessionConfig.ErrorListener.class); - Range<Integer> fpsRange1 = new Range<>(30, 30); - Range<Integer> fpsRange2 = new Range<>(15, 30); - MutableOptionsBundle optionsBundle1 = MutableOptionsBundle.create(); - optionsBundle1.insertOption(OPTION, 1); - MutableOptionsBundle optionsBundle2 = MutableOptionsBundle.create(); - optionsBundle2.insertOption(OPTION, 2); - int template1 = CameraDevice.TEMPLATE_PREVIEW; - int template2 = CameraDevice.TEMPLATE_RECORD; - - SessionConfig.Builder builder = new SessionConfig.Builder(); - builder.addSurface(deferrableSurface1); - builder.setExpectedFrameRateRange(fpsRange1); - builder.addCameraCaptureCallback(callback1); - builder.addRepeatingCameraCaptureCallback(callback1); - builder.addDeviceStateCallback(deviceStateCallback1); - builder.addSessionStateCallback(sessionCallback1); - builder.setTemplateType(template1); - builder.addImplementationOptions(optionsBundle1); - builder.addErrorListener(errorListener1); - SessionConfig sessionConfig = builder.build(); - - // 2. Act - // builder change should not affect the instance built earlier. - builder.addSurface(deferrableSurface2); - builder.setExpectedFrameRateRange(fpsRange2); - builder.addCameraCaptureCallback(callback2); - builder.addRepeatingCameraCaptureCallback(callback2); - builder.addDeviceStateCallback(deviceStateCallback2); - builder.addSessionStateCallback(sessionCallback2); - builder.setTemplateType(template2); - builder.addImplementationOptions(optionsBundle2); - builder.addErrorListener(errorListener2); - - // 3. Verify - assertThat(sessionConfig.getSurfaces()).containsExactly(deferrableSurface1); - assertThat(sessionConfig.getExpectedFrameRateRange()).isEqualTo(fpsRange1); - assertThat(sessionConfig.getSingleCameraCaptureCallbacks()).containsExactly(callback1); - assertThat(sessionConfig.getRepeatingCaptureConfig().getCameraCaptureCallbacks()) - .containsExactly(callback1); - assertThat(sessionConfig.getDeviceStateCallbacks()).containsExactly(deviceStateCallback1); - assertThat(sessionConfig.getSessionStateCallbacks()).containsExactly(sessionCallback1); - assertThat(sessionConfig.getTemplateType()).isEqualTo(template1); - assertThat(sessionConfig.getImplementationOptions().retrieveOption(OPTION)).isEqualTo(1); - assertThat(sessionConfig.getErrorListeners()).containsExactly(errorListener1); - } - - @Test - public void validatingBuilderChange_doNotChangeEarlierBuiltInstance() { - // 1. Arrange - CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class); - CameraCaptureCallback callback2 = mock(CameraCaptureCallback.class); - DeferrableSurface deferrableSurface1 = mock(DeferrableSurface.class); - DeferrableSurface deferrableSurface2 = mock(DeferrableSurface.class); - CameraDevice.StateCallback deviceStateCallback1 = mock(CameraDevice.StateCallback.class); - CameraDevice.StateCallback deviceStateCallback2 = mock(CameraDevice.StateCallback.class); - CameraCaptureSession.StateCallback sessionCallback1 = - mock(CameraCaptureSession.StateCallback.class); - CameraCaptureSession.StateCallback sessionCallback2 = - mock(CameraCaptureSession.StateCallback.class); - SessionConfig.ErrorListener errorListener1 = mock(SessionConfig.ErrorListener.class); - SessionConfig.ErrorListener errorListener2 = mock(SessionConfig.ErrorListener.class); - Range<Integer> fpsRange1 = new Range<>(30, 30); - Range<Integer> fpsRange2 = new Range<>(15, 30); - MutableOptionsBundle optionsBundle1 = MutableOptionsBundle.create(); - optionsBundle1.insertOption(OPTION, 1); - MutableOptionsBundle optionsBundle2 = MutableOptionsBundle.create(); - optionsBundle2.insertOption(OPTION, 2); - int template1 = CameraDevice.TEMPLATE_PREVIEW; - int template2 = CameraDevice.TEMPLATE_RECORD; - - SessionConfig.Builder builder = new SessionConfig.Builder(); - builder.addSurface(deferrableSurface1); - builder.setExpectedFrameRateRange(fpsRange1); - builder.addCameraCaptureCallback(callback1); - builder.addRepeatingCameraCaptureCallback(callback1); - builder.addDeviceStateCallback(deviceStateCallback1); - builder.addSessionStateCallback(sessionCallback1); - builder.setTemplateType(template1); - builder.addImplementationOptions(optionsBundle1); - builder.addErrorListener(errorListener1); - - SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder(); - validatingBuilder.add(builder.build()); - SessionConfig sessionConfig = validatingBuilder.build(); - - // 2. Act - // add another SessionConfig to ValidatingBuilder. This should not affect the - // instance built earlier. - SessionConfig.Builder builder2 = new SessionConfig.Builder(); - builder2.addSurface(deferrableSurface2); - builder2.setExpectedFrameRateRange(fpsRange2); - builder2.addCameraCaptureCallback(callback2); - builder2.addRepeatingCameraCaptureCallback(callback2); - builder2.addDeviceStateCallback(deviceStateCallback2); - builder2.addSessionStateCallback(sessionCallback2); - builder2.setTemplateType(template2); - builder2.addImplementationOptions(optionsBundle2); - builder2.addErrorListener(errorListener2); - validatingBuilder.add(builder2.build()); - - // 3. Verify - assertThat(sessionConfig.getSurfaces()).containsExactly(deferrableSurface1); - assertThat(sessionConfig.getExpectedFrameRateRange()).isEqualTo(fpsRange1); - assertThat(sessionConfig.getSingleCameraCaptureCallbacks()).containsExactly(callback1); - assertThat(sessionConfig.getRepeatingCaptureConfig().getCameraCaptureCallbacks()) - .containsExactly(callback1); - assertThat(sessionConfig.getDeviceStateCallbacks()).containsExactly(deviceStateCallback1); - assertThat(sessionConfig.getSessionStateCallbacks()).containsExactly(sessionCallback1); - assertThat(sessionConfig.getTemplateType()).isEqualTo(template1); - assertThat(sessionConfig.getImplementationOptions().retrieveOption(OPTION)).isEqualTo(1); - assertThat(sessionConfig.getErrorListeners()).containsExactly(errorListener1); - } - - private SessionConfig createSessionConfigWithTag(String key, Object tagValue) { - SessionConfig.Builder builder1 = new SessionConfig.Builder(); - builder1.addSurface(mMockSurface1); - builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW); - builder1.addTag(key, tagValue); - - return builder1.build(); - } -} diff --git a/camera/camera-core/src/test/java/androidx/camera/core/impl/CaptureConfigTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/impl/CaptureConfigTest.kt new file mode 100644 index 00000000000..96db28e3dbd --- /dev/null +++ b/camera/camera-core/src/test/java/androidx/camera/core/impl/CaptureConfigTest.kt @@ -0,0 +1,386 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.camera.core.impl + +import android.hardware.camera2.CameraDevice +import android.os.Build +import android.util.Range +import androidx.camera.core.impl.Config.Option +import androidx.camera.core.impl.Config.OptionPriority +import androidx.camera.testing.impl.DeferrableSurfacesUtil +import com.google.common.collect.Lists +import com.google.common.truth.Truth.assertThat +import java.util.Arrays +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.mock +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.internal.DoNotInstrument + +@RunWith(RobolectricTestRunner::class) +@DoNotInstrument +@Config(minSdk = Build.VERSION_CODES.LOLLIPOP) +class CaptureConfigTest { + private var mMockSurface0: DeferrableSurface? = null + @Before + fun setup() { + mMockSurface0 = mock(DeferrableSurface::class.java) + } + + @Test + fun builderSetTemplate() { + val builder = CaptureConfig.Builder() + + builder.templateType = CameraDevice.TEMPLATE_PREVIEW + val captureConfig = builder.build() + + assertThat(captureConfig.templateType).isEqualTo(CameraDevice.TEMPLATE_PREVIEW) + } + + @Test + fun builderNotSetTemplate() { + val builder = CaptureConfig.Builder() + + val captureConfig = builder.build() + + assertThat(captureConfig.templateType).isEqualTo(CaptureConfig.TEMPLATE_TYPE_NONE) + } + + @Test + fun builderAddSurface() { + val builder = CaptureConfig.Builder() + + builder.addSurface(mMockSurface0!!) + val captureConfig = builder.build() + + val surfaces = captureConfig.surfaces + + assertThat(surfaces).hasSize(1) + assertThat(surfaces).contains(mMockSurface0) + } + + @Test + fun builderRemoveSurface() { + val builder = CaptureConfig.Builder() + + builder.addSurface(mMockSurface0!!) + builder.removeSurface(mMockSurface0!!) + val captureConfig = builder.build() + + val surfaces = DeferrableSurfacesUtil.surfaceList(captureConfig.surfaces) + assertThat(surfaces).isEmpty() + } + + @Test + fun builderClearSurface() { + val builder = CaptureConfig.Builder() + + builder.addSurface(mMockSurface0!!) + builder.clearSurfaces() + val captureConfig = builder.build() + + val surfaces = DeferrableSurfacesUtil.surfaceList(captureConfig.surfaces) + assertThat(surfaces.size).isEqualTo(0) + } + + @Test + fun builderAddOption() { + val builder = CaptureConfig.Builder() + + val options = MutableOptionsBundle.create() + options.insertOption(OPTION, 1) + builder.addImplementationOptions(options) + val captureConfig = builder.build() + + val config = captureConfig.implementationOptions + + assertThat(config.containsOption(OPTION)).isTrue() + assertThat(config.retrieveOption(OPTION)).isEqualTo(1) + } + + @Test + fun addOption_priorityIsKept() { + val builder = CaptureConfig.Builder() + + val options = MutableOptionsBundle.create() + options.insertOption(OPTION, OptionPriority.REQUIRED, 1) + builder.addImplementationOptions(options) + val captureConfig = builder.build() + + val config = captureConfig.implementationOptions + + assertThat(config.containsOption(OPTION)).isTrue() + assertThat(config.retrieveOption(OPTION)).isEqualTo(1) + assertThat(config.getOptionPriority(OPTION)).isEqualTo(OptionPriority.REQUIRED) + } + + @Test + fun builderSetUseTargetedSurface() { + val builder = CaptureConfig.Builder() + + builder.isUseRepeatingSurface = true + val captureConfig = builder.build() + + assertThat(captureConfig.isUseRepeatingSurface).isTrue() + } + + @Test + fun builderAddMultipleCameraCaptureCallbacks() { + val builder = CaptureConfig.Builder() + val callback0 = mock( + CameraCaptureCallback::class.java + ) + val callback1 = mock( + CameraCaptureCallback::class.java + ) + + builder.addCameraCaptureCallback(callback0) + builder.addCameraCaptureCallback(callback1) + val configuration = builder.build() + + assertThat(configuration.cameraCaptureCallbacks).containsExactly(callback0, callback1) + } + + @Test + fun builderAddAllCameraCaptureCallbacks() { + val builder = SessionConfig.Builder() + val callback0 = mock( + CameraCaptureCallback::class.java + ) + val callback1 = mock( + CameraCaptureCallback::class.java + ) + val callbacks: List<CameraCaptureCallback> = Lists.newArrayList(callback0, callback1) + + builder.addAllRepeatingCameraCaptureCallbacks(callbacks) + val configuration = builder.build() + + assertThat(configuration.repeatingCameraCaptureCallbacks) + .containsExactly(callback0, callback1) + } + + @Test + fun builderAddImplementationMultiValue() { + val builder = CaptureConfig.Builder() + + val obj1 = Any() + val fakeMultiValueSet1 = FakeMultiValueSet() + fakeMultiValueSet1.addAll(Arrays.asList(obj1)) + val fakeConfig1 = MutableOptionsBundle.create() + fakeConfig1.insertOption(FAKE_MULTI_VALUE_SET_OPTION, fakeMultiValueSet1) + builder.addImplementationOptions(fakeConfig1) + + val obj2 = Any() + val fakeMultiValueSet2 = FakeMultiValueSet() + fakeMultiValueSet2.addAll(Arrays.asList(obj2)) + val fakeConfig2 = MutableOptionsBundle.create() + fakeConfig2.insertOption(FAKE_MULTI_VALUE_SET_OPTION, fakeMultiValueSet2) + builder.addImplementationOptions(fakeConfig2) + + val captureConfig = builder.build() + + val fakeMultiValueSet = + captureConfig.implementationOptions.retrieveOption( + FAKE_MULTI_VALUE_SET_OPTION + ) + + assertThat(fakeMultiValueSet).isNotNull() + assertThat(fakeMultiValueSet!!.allItems).containsExactly(obj1, obj2) + } + + @Test + fun builderAddSingleImplementationOption() { + val builder = CaptureConfig.Builder() + + builder.addImplementationOption(CaptureConfig.OPTION_ROTATION, 90) + + val captureConfig = builder.build() + + assertThat( + captureConfig.implementationOptions.retrieveOption( + CaptureConfig.OPTION_ROTATION + ) + ).isEqualTo(90) + } + + @Test + fun builderFromPrevious_containsCameraCaptureCallbacks() { + var builder = CaptureConfig.Builder() + val callback0 = mock( + CameraCaptureCallback::class.java + ) + val callback1 = mock( + CameraCaptureCallback::class.java + ) + builder.addCameraCaptureCallback(callback0) + builder.addCameraCaptureCallback(callback1) + builder = CaptureConfig.Builder.from(builder.build()) + val callback2 = mock( + CameraCaptureCallback::class.java + ) + + builder.addCameraCaptureCallback(callback2) + val configuration = builder.build() + + assertThat(configuration.cameraCaptureCallbacks) + .containsExactly(callback0, callback1, callback2) + } + + @Test + fun builderRemoveCameraCaptureCallback_returnsFalseIfNotAdded() { + val mockCallback = mock( + CameraCaptureCallback::class.java + ) + val builder = CaptureConfig.Builder() + + assertThat(builder.removeCameraCaptureCallback(mockCallback)).isFalse() + } + + @Test + fun builderRemoveCameraCaptureCallback_removesAddedCallback() { + // Arrange. + val mockCallback = mock( + CameraCaptureCallback::class.java + ) + val builder = CaptureConfig.Builder() + + // Act. + builder.addCameraCaptureCallback(mockCallback) + val configWithCallback = builder.build() + + // Assert. + assertThat(configWithCallback.cameraCaptureCallbacks).contains(mockCallback) + + // Act. + val removedCallback = builder.removeCameraCaptureCallback(mockCallback) + val configWithoutCallback = builder.build() + + // Assert. + assertThat(removedCallback).isTrue() + assertThat(configWithoutCallback.cameraCaptureCallbacks).doesNotContain(mockCallback) + } + + @Test(expected = UnsupportedOperationException::class) + fun cameraCaptureCallbacks_areImmutable() { + val builder = CaptureConfig.Builder() + val configuration = builder.build() + + configuration.cameraCaptureCallbacks.add( + mock( + CameraCaptureCallback::class.java + ) + ) + } + + @Test + fun postviewEnabledDefaultIsFalse() { + // 1. Arrange / Act + val captureConfig = CaptureConfig.Builder().build() + + // 3. Assert + assertThat(captureConfig.isPostviewEnabled).isFalse() + } + + @Test + fun canSetPostviewEnabled() { + // 1. Arrange + val builder = CaptureConfig.Builder() + + // 2. Act + builder.setPostviewEnabled(true) + val captureConfig = builder.build() + + // 3. Assert + assertThat(captureConfig.isPostviewEnabled).isTrue() + } + + @Test + fun builderChange_doNotChangeEarlierBuiltInstance() { + // 1. Arrange + val callback1 = mock( + CameraCaptureCallback::class.java + ) + val callback2 = mock( + CameraCaptureCallback::class.java + ) + val deferrableSurface1 = mock( + DeferrableSurface::class.java + ) + val deferrableSurface2 = mock( + DeferrableSurface::class.java + ) + val fpsRange1 = Range(30, 30) + val fpsRange2 = Range(15, 30) + val optionValue1 = 1 + val optionValue2 = 2 + val tagValue1 = 1 + val tagValue2 = 2 + val template1 = CameraDevice.TEMPLATE_PREVIEW + val template2 = CameraDevice.TEMPLATE_RECORD + + val builder = CaptureConfig.Builder() + builder.addSurface(deferrableSurface1) + builder.setExpectedFrameRateRange(fpsRange1) + builder.addCameraCaptureCallback(callback1) + builder.templateType = template1 + builder.addTag("KEY", tagValue1) + builder.addImplementationOption(OPTION, optionValue1) + val captureConfig = builder.build() + + // 2. Act + // builder change should not affect the instance built earlier. + builder.addSurface(deferrableSurface2) + builder.setExpectedFrameRateRange(fpsRange2) + builder.addCameraCaptureCallback(callback2) + builder.templateType = template2 + builder.addTag("KEY", tagValue2) + builder.addImplementationOption(OPTION, optionValue2) + + // 3. Verify + assertThat(captureConfig.surfaces).containsExactly(deferrableSurface1) + assertThat(captureConfig.expectedFrameRateRange).isEqualTo(fpsRange1) + assertThat(captureConfig.cameraCaptureCallbacks).containsExactly(callback1) + assertThat(captureConfig.templateType).isEqualTo(template1) + assertThat(captureConfig.tagBundle.getTag("KEY")).isEqualTo(tagValue1) + assertThat(captureConfig.implementationOptions.retrieveOption(OPTION)) + .isEqualTo(optionValue1) + } + + /** + * A fake [MultiValueSet]. + */ + internal class FakeMultiValueSet : MultiValueSet<Any?>() { + override fun clone(): MultiValueSet<Any?> { + val multiValueSet = FakeMultiValueSet() + multiValueSet.addAll(allItems) + return multiValueSet + } + } + + companion object { + private val OPTION = Option.create<Int>( + "camerax.test.option_0", Int::class.java + ) + + private val FAKE_MULTI_VALUE_SET_OPTION: Option<FakeMultiValueSet> = + Option.create( + "option.fakeMultiValueSet.1", + FakeMultiValueSet::class.java + ) + } +} diff --git a/camera/camera-core/src/test/java/androidx/camera/core/impl/SessionConfigTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/impl/SessionConfigTest.kt new file mode 100644 index 00000000000..192922d6c6b --- /dev/null +++ b/camera/camera-core/src/test/java/androidx/camera/core/impl/SessionConfigTest.kt @@ -0,0 +1,1232 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.camera.core.impl + +import android.hardware.camera2.CameraCaptureSession +import android.hardware.camera2.CameraDevice +import android.hardware.camera2.params.SessionConfiguration +import android.os.Build +import android.util.Range +import android.view.Surface +import androidx.camera.camera2.impl.Camera2ImplConfig +import androidx.camera.core.ImageCapture +import androidx.camera.core.Preview +import androidx.camera.core.impl.Config.Option +import androidx.camera.core.impl.SessionConfig.ValidatingBuilder +import androidx.camera.testing.impl.DeferrableSurfacesUtil +import androidx.camera.testing.impl.fakes.FakeMultiValueSet +import com.google.common.collect.Lists +import com.google.common.truth.Truth.assertThat +import java.util.Arrays +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.mock +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.internal.DoNotInstrument + +@RunWith(RobolectricTestRunner::class) +@DoNotInstrument +@Config(minSdk = Build.VERSION_CODES.LOLLIPOP) +class SessionConfigTest { + private var mMockSurface0: DeferrableSurface? = null + private var mMockSurface1: DeferrableSurface? = null + + @Before + fun setup() { + mMockSurface0 = ImmediateSurface(mock(Surface::class.java)) + mMockSurface1 = ImmediateSurface(mock(Surface::class.java)) + } + + @After + fun tearDown() { + mMockSurface0!!.close() + mMockSurface1!!.close() + } + + @Test + fun builderSetTemplate() { + val builder = SessionConfig.Builder() + + builder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val sessionConfig = builder.build() + + assertThat(sessionConfig.templateType).isEqualTo(CameraDevice.TEMPLATE_PREVIEW) + } + + @Test + fun builderAddSurface() { + val builder = SessionConfig.Builder() + + builder.addSurface(mMockSurface0!!) + val sessionConfig = builder.build() + + val surfaces = sessionConfig.surfaces + val outputConfigs = sessionConfig.outputConfigs + + assertThat(surfaces).hasSize(1) + assertThat(surfaces).contains(mMockSurface0) + assertThat(outputConfigs).hasSize(1) + assertThat(outputConfigs[0]!!.surface).isEqualTo(mMockSurface0) + assertThat(outputConfigs[0]!!.sharedSurfaces).isEmpty() + assertThat(outputConfigs[0]!!.physicalCameraId).isNull() + assertThat(outputConfigs[0]!!.surfaceGroupId) + .isEqualTo(SessionConfig.OutputConfig.SURFACE_GROUP_ID_NONE) + } + + @Test + fun builderAddOutputConfig() { + val builder = SessionConfig.Builder() + val sharedSurface1: DeferrableSurface = ImmediateSurface( + mock( + Surface::class.java + ) + ) + val sharedSurface2: DeferrableSurface = ImmediateSurface( + mock( + Surface::class.java + ) + ) + val outputConfig = SessionConfig.OutputConfig.builder( + mMockSurface0!! + ) + .setSurfaceGroupId(1) + .setSharedSurfaces(Arrays.asList(sharedSurface1, sharedSurface2)) + .setPhysicalCameraId("4") + .build() + + builder.addOutputConfig(outputConfig) + val sessionConfig = builder.build() + + val surfaces = sessionConfig.surfaces + val outputConfigs = sessionConfig.outputConfigs + + assertThat(surfaces).containsExactly(mMockSurface0, sharedSurface1, sharedSurface2) + assertThat(outputConfigs).hasSize(1) + assertThat(outputConfigs[0]!!.surface).isEqualTo(mMockSurface0) + assertThat(outputConfigs[0]!!.sharedSurfaces) + .containsExactly(sharedSurface1, sharedSurface2) + assertThat(outputConfigs[0]!!.surfaceGroupId).isEqualTo(1) + assertThat(outputConfigs[0]!!.physicalCameraId).isEqualTo("4") + } + + @Test + fun builderAddNonRepeatingSurface() { + val builder = SessionConfig.Builder() + + builder.addNonRepeatingSurface(mMockSurface0!!) + val sessionConfig = builder.build() + + val surfaces = sessionConfig.surfaces + val outputConfigs = sessionConfig.outputConfigs + val repeatingSurfaces = + sessionConfig.repeatingCaptureConfig.surfaces + + assertThat(surfaces).containsExactly(mMockSurface0) + assertThat(outputConfigs).hasSize(1) + assertThat(outputConfigs[0]!!.surface).isEqualTo(mMockSurface0) + assertThat(repeatingSurfaces).isEmpty() + assertThat(repeatingSurfaces).doesNotContain(mMockSurface0) + } + + @Test + fun builderAddSurfaceContainsRepeatingSurface() { + val builder = SessionConfig.Builder() + + builder.addSurface(mMockSurface0!!) + builder.addNonRepeatingSurface(mMockSurface1!!) + val sessionConfig = builder.build() + + val surfaces = DeferrableSurfacesUtil.surfaceList(sessionConfig.surfaces) + val repeatingSurfaces = DeferrableSurfacesUtil.surfaceList( + sessionConfig.repeatingCaptureConfig.surfaces + ) + + assertThat(surfaces.size).isAtLeast(repeatingSurfaces.size) + assertThat(surfaces).containsAtLeastElementsIn(repeatingSurfaces) + } + + @Test + fun builderRemoveSurface() { + val builder = SessionConfig.Builder() + + builder.addSurface(mMockSurface0!!) + builder.addSurface(mMockSurface1!!) + builder.removeSurface(mMockSurface0!!) + val sessionConfig = builder.build() + + assertThat(sessionConfig.surfaces).containsExactly(mMockSurface1) + assertThat(sessionConfig.outputConfigs).hasSize(1) + assertThat(sessionConfig.outputConfigs[0].surface).isEqualTo(mMockSurface1) + } + + @Test + fun builderClearSurface() { + val builder = SessionConfig.Builder() + + builder.addSurface(mMockSurface0!!) + builder.clearSurfaces() + val sessionConfig = builder.build() + + assertThat(sessionConfig.surfaces).isEmpty() + assertThat(sessionConfig.outputConfigs).isEmpty() + } + + @Test + fun builderAddOption() { + val builder = SessionConfig.Builder() + + val options = MutableOptionsBundle.create() + options.insertOption(OPTION, 1) + builder.addImplementationOptions(options) + val sessionConfig = builder.build() + + val config = sessionConfig.implementationOptions + + assertThat(config.containsOption(OPTION)).isTrue() + assertThat(config.retrieveOption(OPTION)).isEqualTo(1) + } + + @Test + fun builderDefaultSessionTypeIsRegular() { + val builder = SessionConfig.Builder() + val sessionConfig = builder.build() + assertThat(sessionConfig.sessionType == SessionConfiguration.SESSION_REGULAR) + } + + @Test + fun builderSetSessionType() { + val builder = SessionConfig.Builder() + .setSessionType(2) + val sessionConfig = builder.build() + assertThat(sessionConfig.sessionType == 2) + } + + @Test + fun builderSetPostviewSurface() { + val builder = SessionConfig.Builder() + .setPostviewSurface(mMockSurface0!!) + val sessionConfig = builder.build() + assertThat(sessionConfig.postviewOutputConfig!!.surface).isEqualTo(mMockSurface0) + } + + @Test + fun prioritizeTemplateType_previewHigherThanUnsupportedType() { + val builderPreview = SessionConfig.Builder() + builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val sessionConfigPreview = builderPreview.build() + val builderManual = SessionConfig.Builder() + builderManual.setTemplateType(CameraDevice.TEMPLATE_MANUAL) + val sessionConfigManual = builderManual.build() + + val validatingBuilder = ValidatingBuilder() + + validatingBuilder.add(sessionConfigPreview) + validatingBuilder.add(sessionConfigManual) + + assertThat(validatingBuilder.isValid).isTrue() + + assertThat(validatingBuilder.build().templateType).isEqualTo( + CameraDevice.TEMPLATE_PREVIEW + ) + } + + @Test + fun prioritizeTemplateType_recordHigherThanPreview() { + val builderPreview = SessionConfig.Builder() + builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val sessionConfigPreview = builderPreview.build() + val builderRecord = SessionConfig.Builder() + builderRecord.setTemplateType(CameraDevice.TEMPLATE_RECORD) + val sessionConfigRecord = builderRecord.build() + + val validatingBuilder = ValidatingBuilder() + + validatingBuilder.add(sessionConfigPreview) + validatingBuilder.add(sessionConfigRecord) + + assertThat(validatingBuilder.isValid).isTrue() + + assertThat(validatingBuilder.build().templateType).isEqualTo( + CameraDevice.TEMPLATE_RECORD + ) + } + + @Test + fun prioritizeTemplateType_addZslFirst_zslHigherThanPreview() { + val builderZsl = SessionConfig.Builder() + builderZsl.setTemplateType(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG) + val sessionConfigZsl = builderZsl.build() + + val builderPreview = SessionConfig.Builder() + builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val sessionConfigPreview = builderPreview.build() + + val validatingBuilder = ValidatingBuilder() + + validatingBuilder.add(sessionConfigZsl) + validatingBuilder.add(sessionConfigPreview) + + assertThat(validatingBuilder.isValid).isTrue() + + assertThat(validatingBuilder.build().templateType).isEqualTo( + CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG + ) + } + + @Test + fun prioritizeTemplateType_addPreviewFirst_zslHigherThanPreview() { + val builderZsl = SessionConfig.Builder() + builderZsl.setTemplateType(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG) + val sessionConfigZsl = builderZsl.build() + + val builderPreview = SessionConfig.Builder() + builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val sessionConfigPreview = builderPreview.build() + + val validatingBuilder = ValidatingBuilder() + + validatingBuilder.add(sessionConfigPreview) + validatingBuilder.add(sessionConfigZsl) + + assertThat(validatingBuilder.isValid).isTrue() + + assertThat(validatingBuilder.build().templateType).isEqualTo( + CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG + ) + } + + @Test + fun setAndVerifyExpectedFrameRateRange_nullValue() { + val builderPreview = SessionConfig.Builder() + builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val sessionConfigPreview = builderPreview.build() + + val validatingBuilder = ValidatingBuilder() + + validatingBuilder.add(sessionConfigPreview) + + assertThat(validatingBuilder.isValid).isTrue() + + assertThat(validatingBuilder.build().expectedFrameRateRange).isEqualTo( + StreamSpec.FRAME_RATE_RANGE_UNSPECIFIED + ) + } + + @Test + fun setAndVerifyExpectedFrameRateRange_initialValue() { + val fpsRangeLow = Range(30, 45) + val builderPreview = SessionConfig.Builder() + builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + builderPreview.setExpectedFrameRateRange(fpsRangeLow) + val sessionConfigPreview = builderPreview.build() + + val validatingBuilder = ValidatingBuilder() + + validatingBuilder.add(sessionConfigPreview) + + assertThat(validatingBuilder.isValid).isTrue() + + assertThat(validatingBuilder.build().expectedFrameRateRange).isEqualTo( + fpsRangeLow + ) + } + + @Test + fun setAndVerifyExpectedFrameRateRange_sameValues() { + val fpsRangeLow = Range(30, 45) + val builderZsl = SessionConfig.Builder() + builderZsl.setTemplateType(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG) + builderZsl.setExpectedFrameRateRange(fpsRangeLow) + val sessionConfigZsl = builderZsl.build() + + val builderPreview = SessionConfig.Builder() + builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + builderPreview.setExpectedFrameRateRange(fpsRangeLow) + val sessionConfigPreview = builderPreview.build() + + val validatingBuilder = ValidatingBuilder() + + validatingBuilder.add(sessionConfigPreview) + validatingBuilder.add(sessionConfigZsl) + + assertThat(validatingBuilder.isValid).isTrue() + + assertThat(validatingBuilder.build().expectedFrameRateRange).isEqualTo( + fpsRangeLow + ) + } + + @Test + fun setAndVerifyExpectedFrameRateRange_differentValues() { + val fpsRangeLow = Range(30, 45) + val fpsRangeHigh = Range(45, 60) + val builderZsl = SessionConfig.Builder() + builderZsl.setTemplateType(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG) + builderZsl.setExpectedFrameRateRange(fpsRangeLow) + val sessionConfigZsl = builderZsl.build() + + val builderPreview = SessionConfig.Builder() + builderPreview.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + builderPreview.setExpectedFrameRateRange(fpsRangeHigh) + val sessionConfigPreview = builderPreview.build() + + val validatingBuilder = ValidatingBuilder() + + validatingBuilder.add(sessionConfigPreview) + validatingBuilder.add(sessionConfigZsl) + + assertThat(validatingBuilder.isValid).isFalse() + } + + @Test + fun addImplementationOptionForStreamUseCase() { + val validatingBuilder = ValidatingBuilder() + assertThat( + !validatingBuilder.build().implementationOptions.containsOption( + Camera2ImplConfig.STREAM_USE_CASE_OPTION + ) + ) + validatingBuilder.addImplementationOption(Camera2ImplConfig.STREAM_USE_CASE_OPTION, 1L) + assertThat( + validatingBuilder.build().implementationOptions.retrieveOption( + Camera2ImplConfig.STREAM_USE_CASE_OPTION + ) == 1L + ) + } + + @Test + fun addDifferentNonDefaultSessionType() { + // 1. Arrange. + val validatingBuilder = ValidatingBuilder() + val sessionConfig1 = SessionConfig.Builder() + .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + .setSessionType(1).build() + val sessionConfig2 = SessionConfig.Builder() + .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + .setSessionType(2).build() + + // 2. Act. + validatingBuilder.add(sessionConfig1) + validatingBuilder.add(sessionConfig2) + + // 3. Assert. + assertThat(validatingBuilder.isValid).isFalse() + } + + @Test + fun addDefaultAndThenNonDefaultSessionType() { + // 1. Arrange. + val sessionTypeToVerify = 2 + val validatingBuilder = ValidatingBuilder() + val sessionConfig1 = SessionConfig.Builder() + .setTemplateType(CameraDevice.TEMPLATE_PREVIEW).build() + val sessionConfig2 = SessionConfig.Builder() + .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + .setSessionType(sessionTypeToVerify).build() + + // 2. Act. + validatingBuilder.add(sessionConfig1) + validatingBuilder.add(sessionConfig2) + + // 3. Assert. + assertThat(validatingBuilder.build().sessionType).isEqualTo(sessionTypeToVerify) + assertThat(validatingBuilder.isValid).isTrue() + } + + @Test + fun addNonDefaultAndThenDefaultSessionType() { + // 1. Arrange. + val sessionTypeToVerify = 2 + val validatingBuilder = ValidatingBuilder() + val sessionConfig1 = SessionConfig.Builder() + .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + .setSessionType(sessionTypeToVerify).build() + val sessionConfig2 = SessionConfig.Builder() + .setTemplateType(CameraDevice.TEMPLATE_PREVIEW).build() + + // 2. Act. + validatingBuilder.add(sessionConfig1) + validatingBuilder.add(sessionConfig2) + + // 3. Assert. + assertThat(validatingBuilder.build().sessionType).isEqualTo(sessionTypeToVerify) + assertThat(validatingBuilder.isValid).isTrue() + } + + @Test + fun addPostviewSurfaceTo_validatingBuilder() { + // 1. Arrange. + val validatingBuilder = ValidatingBuilder() + val sessionConfig1 = SessionConfig.Builder() + .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + .setPostviewSurface(mMockSurface0!!) + .build() + + // 2. Act. + validatingBuilder.add(sessionConfig1) + + // 3. Assert. + assertThat(validatingBuilder.build().postviewOutputConfig!!.surface) + .isEqualTo(mMockSurface0) + assertThat(validatingBuilder.isValid).isTrue() + } + + @Test + fun addDifferentPostviewSurfacesTo_validatingBuilder() { + // 1. Arrange. + val validatingBuilder = ValidatingBuilder() + val sessionConfig1 = SessionConfig.Builder() + .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + .setPostviewSurface(mMockSurface0!!) + .build() + val sessionConfig2 = SessionConfig.Builder() + .setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + .setPostviewSurface(mMockSurface1!!) + .build() + + // 2. Act. + validatingBuilder.add(sessionConfig1) + validatingBuilder.add(sessionConfig2) + + // 3. Assert. + assertThat(validatingBuilder.isValid).isFalse() + } + + @Test + fun conflictingOptions() { + val builder0 = SessionConfig.Builder() + val options0 = MutableOptionsBundle.create() + options0.insertOption(OPTION, 1) + builder0.addImplementationOptions(options0) + val config0 = builder0.build() + + val builder1 = SessionConfig.Builder() + val options1 = MutableOptionsBundle.create() + options1.insertOption(OPTION, 2) + builder1.addImplementationOptions(options1) + val config1 = builder1.build() + + val validatingBuilder = ValidatingBuilder() + + validatingBuilder.add(config0) + validatingBuilder.add(config1) + + assertThat(validatingBuilder.isValid).isFalse() + } + + @Test + fun combineTwoSessionsValid() { + val builder0 = SessionConfig.Builder() + builder0.addSurface(mMockSurface0!!) + builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val options0 = MutableOptionsBundle.create() + options0.insertOption(OPTION, 1) + builder0.addImplementationOptions(options0) + + val builder1 = SessionConfig.Builder() + builder1.addSurface(mMockSurface1!!) + builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val options1 = MutableOptionsBundle.create() + options1.insertOption(OPTION_1, "test") + builder1.addImplementationOptions(options1) + + val validatingBuilder = ValidatingBuilder() + validatingBuilder.add(builder0.build()) + validatingBuilder.add(builder1.build()) + + assertThat(validatingBuilder.isValid).isTrue() + } + + @Test + fun combineTwoSessionsTemplate() { + val builder0 = SessionConfig.Builder() + builder0.addSurface(mMockSurface0!!) + builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val options0 = MutableOptionsBundle.create() + options0.insertOption(OPTION, 1) + builder0.addImplementationOptions(options0) + + val builder1 = SessionConfig.Builder() + builder1.addSurface(mMockSurface1!!) + builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val options1 = MutableOptionsBundle.create() + options1.insertOption(OPTION_1, "test") + builder1.addImplementationOptions(options1) + + val validatingBuilder = ValidatingBuilder() + validatingBuilder.add(builder0.build()) + validatingBuilder.add(builder1.build()) + + val sessionConfig = validatingBuilder.build() + + assertThat(sessionConfig.templateType).isEqualTo(CameraDevice.TEMPLATE_PREVIEW) + } + + private fun createSurface(containerClass: Class<*>): DeferrableSurface { + val deferrableSurface: DeferrableSurface = ImmediateSurface( + mock( + Surface::class.java + ) + ) + deferrableSurface.setContainerClass(containerClass) + return deferrableSurface + } + + @Test + fun combineTwoSessionsSurfaces() { + val previewSurface = createSurface(Preview::class.java) + val imageCaptureSurface = createSurface(ImageCapture::class.java) + + val builder1 = SessionConfig.Builder() + builder1.addSurface(previewSurface) + builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + + val builder2 = SessionConfig.Builder() + builder2.addSurface(imageCaptureSurface) + builder2.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + + val validatingBuilder = ValidatingBuilder() + validatingBuilder.add(builder1.build()) + validatingBuilder.add(builder2.build()) + + val sessionConfig = validatingBuilder.build() + + val surfaces = sessionConfig.surfaces + // Ensures the surfaces are all added and sorted correctly. + assertThat(surfaces).containsExactly(previewSurface, imageCaptureSurface).inOrder() + } + + @Test + fun combineTwoSessionsOutputConfigs() { + val nonRepeatingSurface = mock( + DeferrableSurface::class.java + ) + + val builder0 = SessionConfig.Builder() + val outputConfig0 = + SessionConfig.OutputConfig.builder(mMockSurface0!!).build() + builder0.addOutputConfig(outputConfig0) + builder0.addNonRepeatingSurface(nonRepeatingSurface) + builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + + val builder1 = SessionConfig.Builder() + val outputConfig1 = + SessionConfig.OutputConfig.builder(mMockSurface1!!).build() + builder1.addOutputConfig(outputConfig1) + builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + + val validatingBuilder = ValidatingBuilder() + validatingBuilder.add(builder0.build()) + validatingBuilder.add(builder1.build()) + + val sessionConfig = validatingBuilder.build() + + val surfaces = sessionConfig.surfaces + assertThat(surfaces) + .containsExactly(mMockSurface0, mMockSurface1, nonRepeatingSurface) + assertThat(sessionConfig.outputConfigs).hasSize(3) + assertThat(sessionConfig.outputConfigs[0]).isEqualTo(outputConfig0) + assertThat(sessionConfig.outputConfigs[1].surface) + .isEqualTo(nonRepeatingSurface) + assertThat(sessionConfig.outputConfigs[2]).isEqualTo(outputConfig1) + // Should not contain the nonRepeatingSurface. + assertThat(sessionConfig.repeatingCaptureConfig.surfaces) + .containsExactly(mMockSurface0, mMockSurface1) + } + + @Test + fun combineTwoSessionsOptions() { + val builder0 = SessionConfig.Builder() + builder0.addSurface(mMockSurface0!!) + builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val options0 = MutableOptionsBundle.create() + options0.insertOption(OPTION, 1) + builder0.addImplementationOptions(options0) + + val builder1 = SessionConfig.Builder() + builder1.addSurface(mMockSurface1!!) + builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val options1 = MutableOptionsBundle.create() + options1.insertOption(OPTION_1, "test") + builder1.addImplementationOptions(options1) + + val validatingBuilder = ValidatingBuilder() + validatingBuilder.add(builder0.build()) + validatingBuilder.add(builder1.build()) + + val sessionConfig = validatingBuilder.build() + + val config = sessionConfig.implementationOptions + + assertThat(config.retrieveOption(OPTION)).isEqualTo(1) + assertThat(config.retrieveOption(OPTION_1)).isEqualTo("test") + } + + @Test + fun combineTwoSessionsMultiValueSetValid() { + val option = Option.create<FakeMultiValueSet>( + "multiValueSet", + FakeMultiValueSet::class.java + ) + + val builder0 = SessionConfig.Builder() + builder0.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + val options0 = MutableOptionsBundle.create() + val multiValueSet0 = FakeMultiValueSet() + options0.insertOption(option, multiValueSet0) + builder0.addImplementationOptions(options0) + val config0 = builder0.build() + + val builder1 = SessionConfig.Builder() + val options1 = MutableOptionsBundle.create() + val multiValueSet1 = FakeMultiValueSet() + options1.insertOption(option, multiValueSet1) + builder1.addImplementationOptions(options1) + val config1 = builder1.build() + + val validatingBuilder = ValidatingBuilder() + validatingBuilder.add(config0) + validatingBuilder.add(config1) + + assertThat(validatingBuilder.isValid).isTrue() + } + + @Test + fun builderAddMultipleRepeatingCameraCaptureCallbacks() { + val builder = SessionConfig.Builder() + val callback0 = mock( + CameraCaptureCallback::class.java + ) + val callback1 = mock( + CameraCaptureCallback::class.java + ) + + builder.addRepeatingCameraCaptureCallback(callback0) + builder.addRepeatingCameraCaptureCallback(callback1) + val configuration = builder.build() + + assertThat(configuration.repeatingCameraCaptureCallbacks) + .containsExactly(callback0, callback1) + assertThat(configuration.singleCameraCaptureCallbacks) + .containsNoneOf(callback0, callback1) + } + + @Test + fun builderAddAllRepeatingCameraCaptureCallbacks() { + val builder = SessionConfig.Builder() + val callback0 = mock( + CameraCaptureCallback::class.java + ) + val callback1 = mock( + CameraCaptureCallback::class.java + ) + val callbacks: List<CameraCaptureCallback> = Lists.newArrayList(callback0, callback1) + + builder.addAllRepeatingCameraCaptureCallbacks(callbacks) + val configuration = builder.build() + + assertThat(configuration.repeatingCameraCaptureCallbacks) + .containsExactly(callback0, callback1) + assertThat(configuration.singleCameraCaptureCallbacks) + .containsNoneOf(callback0, callback1) + } + + @Test(expected = UnsupportedOperationException::class) + fun repeatingCameraCaptureCallbacks_areImmutable() { + val builder = SessionConfig.Builder() + val configuration = builder.build() + + configuration.repeatingCameraCaptureCallbacks.add( + mock( + CameraCaptureCallback::class.java + ) + ) + } + + @Test + fun builderAddMultipleDeviceStateCallbacks() { + val builder = SessionConfig.Builder() + val callback0 = mock( + CameraDevice.StateCallback::class.java + ) + val callback1 = mock( + CameraDevice.StateCallback::class.java + ) + + builder.addDeviceStateCallback(callback0) + builder.addDeviceStateCallback(callback1) + val configuration = builder.build() + + assertThat(configuration.deviceStateCallbacks).containsExactly(callback0, callback1) + } + + @Test + fun builderAddAllDeviceStateCallbacks() { + val builder = SessionConfig.Builder() + val callback0 = mock( + CameraDevice.StateCallback::class.java + ) + val callback1 = mock( + CameraDevice.StateCallback::class.java + ) + val callbacks: List<CameraDevice.StateCallback> = Lists.newArrayList(callback0, callback1) + + builder.addAllDeviceStateCallbacks(callbacks) + val configuration = builder.build() + + assertThat(configuration.deviceStateCallbacks).containsExactly(callback0, callback1) + } + + @Test(expected = UnsupportedOperationException::class) + fun deviceStateCallbacks_areImmutable() { + val builder = SessionConfig.Builder() + val configuration = builder.build() + + configuration.deviceStateCallbacks.add( + mock( + CameraDevice.StateCallback::class.java + ) + ) + } + + @Test + fun builderAddMultipleSessionStateCallbacks() { + val builder = SessionConfig.Builder() + val callback0 = + mock(CameraCaptureSession.StateCallback::class.java) + val callback1 = + mock(CameraCaptureSession.StateCallback::class.java) + + builder.addSessionStateCallback(callback0) + builder.addSessionStateCallback(callback1) + val configuration = builder.build() + + assertThat(configuration.sessionStateCallbacks).containsExactly(callback0, callback1) + } + + @Test + fun builderAddAllSessionStateCallbacks() { + val builder = SessionConfig.Builder() + val callback0 = + mock(CameraCaptureSession.StateCallback::class.java) + val callback1 = + mock(CameraCaptureSession.StateCallback::class.java) + val callbacks: List<CameraCaptureSession.StateCallback> = + Lists.newArrayList(callback0, callback1) + + builder.addAllSessionStateCallbacks(callbacks) + val configuration = builder.build() + + assertThat(configuration.sessionStateCallbacks).containsExactly(callback0, callback1) + } + + @Test(expected = UnsupportedOperationException::class) + fun sessionStateCallbacks_areImmutable() { + val builder = SessionConfig.Builder() + val configuration = builder.build() + + configuration.sessionStateCallbacks + .add(mock(CameraCaptureSession.StateCallback::class.java)) + } + + @Test + fun builderAddMultipleCameraCallbacks() { + val builder = SessionConfig.Builder() + val callback0 = mock( + CameraCaptureCallback::class.java + ) + val callback1 = mock( + CameraCaptureCallback::class.java + ) + + builder.addCameraCaptureCallback(callback0) + builder.addCameraCaptureCallback(callback1) + val configuration = builder.build() + + assertThat(configuration.singleCameraCaptureCallbacks) + .containsExactly(callback0, callback1) + assertThat(configuration.repeatingCameraCaptureCallbacks) + .containsExactly(callback0, callback1) + } + + @Test + fun builderAddAllCameraCallbacks() { + val builder = SessionConfig.Builder() + val callback0 = mock( + CameraCaptureCallback::class.java + ) + val callback1 = mock( + CameraCaptureCallback::class.java + ) + val callbacks: List<CameraCaptureCallback> = Lists.newArrayList(callback0, callback1) + + builder.addAllCameraCaptureCallbacks(callbacks) + val configuration = builder.build() + + assertThat(configuration.singleCameraCaptureCallbacks) + .containsExactly(callback0, callback1) + assertThat(configuration.repeatingCameraCaptureCallbacks) + .containsExactly(callback0, callback1) + } + + @Test + fun removeCameraCaptureCallback_returnsFalseIfNotAdded() { + val mockCallback = mock( + CameraCaptureCallback::class.java + ) + val builder = SessionConfig.Builder() + + assertThat(builder.removeCameraCaptureCallback(mockCallback)).isFalse() + } + + @Test + fun canAddAndRemoveCameraCaptureCallback_withBuilder() { + // Arrange. + val mockRepeatingCallback = mock( + CameraCaptureCallback::class.java + ) + val mockSingleCallback = mock( + CameraCaptureCallback::class.java + ) + val builder = SessionConfig.Builder() + + // Act. + builder.addRepeatingCameraCaptureCallback(mockRepeatingCallback) + builder.addCameraCaptureCallback(mockSingleCallback) + val sessionConfigWithCallbacks = builder.build() + + // Assert. + assertThat(sessionConfigWithCallbacks.singleCameraCaptureCallbacks).contains( + mockSingleCallback + ) + assertThat(sessionConfigWithCallbacks.singleCameraCaptureCallbacks).contains( + mockSingleCallback + ) + + // Act. + val removedSingle = builder.removeCameraCaptureCallback(mockSingleCallback) + val sessionConfigWithoutSingleCallback = builder.build() + + // Assert. + assertThat(removedSingle).isTrue() + assertThat(sessionConfigWithoutSingleCallback.singleCameraCaptureCallbacks) + .doesNotContain(mockSingleCallback) + + // Act. + val removedRepeating = builder.removeCameraCaptureCallback(mockRepeatingCallback) + val sessionConfigWithoutCallbacks = builder.build() + + // Assert. + assertThat(removedRepeating).isTrue() + assertThat( + sessionConfigWithoutCallbacks.repeatingCameraCaptureCallbacks + ).doesNotContain( + mockRepeatingCallback + ) + } + + @Test(expected = UnsupportedOperationException::class) + fun singleCameraCaptureCallbacks_areImmutable() { + val builder = SessionConfig.Builder() + val configuration = builder.build() + + configuration.singleCameraCaptureCallbacks.add( + mock( + CameraCaptureCallback::class.java + ) + ) + } + + @Test + fun builderAddErrorListener() { + val builder = SessionConfig.Builder() + val callback = mock( + SessionConfig.ErrorListener::class.java + ) + + builder.addErrorListener(callback) + + val config = builder.build() + + assertThat(config.errorListeners).contains(callback) + } + + @Test + fun combineTwoSessionsCallbacks() { + val builder0 = SessionConfig.Builder() + val sessionCallback0 = + mock(CameraCaptureSession.StateCallback::class.java) + val deviceCallback0 = mock( + CameraDevice.StateCallback::class.java + ) + val repeatingCallback0 = mock( + CameraCaptureCallback::class.java + ) + val cameraCallback0 = mock( + CameraCaptureCallback::class.java + ) + val errorListener0 = mock( + SessionConfig.ErrorListener::class.java + ) + builder0.addSessionStateCallback(sessionCallback0) + builder0.addDeviceStateCallback(deviceCallback0) + builder0.addRepeatingCameraCaptureCallback(repeatingCallback0) + builder0.addCameraCaptureCallback(cameraCallback0) + builder0.addErrorListener(errorListener0) + + val builder1 = SessionConfig.Builder() + val sessionCallback1 = + mock(CameraCaptureSession.StateCallback::class.java) + val deviceCallback1 = mock( + CameraDevice.StateCallback::class.java + ) + val repeatingCallback1 = mock( + CameraCaptureCallback::class.java + ) + val cameraCallback1 = mock( + CameraCaptureCallback::class.java + ) + val errorListener1 = mock( + SessionConfig.ErrorListener::class.java + ) + builder1.addSessionStateCallback(sessionCallback1) + builder1.addDeviceStateCallback(deviceCallback1) + builder1.addRepeatingCameraCaptureCallback(repeatingCallback1) + builder1.addCameraCaptureCallback(cameraCallback1) + builder1.addErrorListener(errorListener1) + + val validatingBuilder = ValidatingBuilder() + validatingBuilder.add(builder0.build()) + validatingBuilder.add(builder1.build()) + + val sessionConfig = validatingBuilder.build() + + assertThat(sessionConfig.sessionStateCallbacks) + .containsExactly(sessionCallback0, sessionCallback1) + assertThat(sessionConfig.deviceStateCallbacks) + .containsExactly(deviceCallback0, deviceCallback1) + assertThat(sessionConfig.repeatingCameraCaptureCallbacks) + .containsExactly( + repeatingCallback0, cameraCallback0, repeatingCallback1, cameraCallback1 + ) + assertThat(sessionConfig.singleCameraCaptureCallbacks) + .containsExactly(cameraCallback0, cameraCallback1) + assertThat(sessionConfig.errorListeners).containsExactly( + errorListener0, + errorListener1 + ) + } + + @Test + fun combineTwoSessionsTagsValid() { + val session0 = createSessionConfigWithTag("TEST00", 0) + val session1 = createSessionConfigWithTag("TEST01", "String") + + val validatingBuilder = ValidatingBuilder() + validatingBuilder.add(session0) + validatingBuilder.add(session1) + + val sessionCombined = validatingBuilder.build() + + assertThat(validatingBuilder.isValid).isTrue() + + val tag = sessionCombined.repeatingCaptureConfig.tagBundle + + assertThat(tag.getTag("TEST00")).isEqualTo(0) + assertThat(tag.getTag("TEST01")).isEqualTo("String") + } + + @Test + fun builderChange_doNotChangeEarlierBuiltInstance() { + // 1. Arrange + val callback1 = mock( + CameraCaptureCallback::class.java + ) + val callback2 = mock( + CameraCaptureCallback::class.java + ) + val deferrableSurface1 = mock( + DeferrableSurface::class.java + ) + val deferrableSurface2 = mock( + DeferrableSurface::class.java + ) + val deviceStateCallback1 = mock( + CameraDevice.StateCallback::class.java + ) + val deviceStateCallback2 = mock( + CameraDevice.StateCallback::class.java + ) + val sessionCallback1 = + mock(CameraCaptureSession.StateCallback::class.java) + val sessionCallback2 = + mock(CameraCaptureSession.StateCallback::class.java) + val errorListener1 = mock( + SessionConfig.ErrorListener::class.java + ) + val errorListener2 = mock( + SessionConfig.ErrorListener::class.java + ) + val fpsRange1 = Range(30, 30) + val fpsRange2 = Range(15, 30) + val optionsBundle1 = MutableOptionsBundle.create() + optionsBundle1.insertOption(OPTION, 1) + val optionsBundle2 = MutableOptionsBundle.create() + optionsBundle2.insertOption(OPTION, 2) + val template1 = CameraDevice.TEMPLATE_PREVIEW + val template2 = CameraDevice.TEMPLATE_RECORD + + val builder = SessionConfig.Builder() + builder.addSurface(deferrableSurface1) + builder.setExpectedFrameRateRange(fpsRange1) + builder.addCameraCaptureCallback(callback1) + builder.addRepeatingCameraCaptureCallback(callback1) + builder.addDeviceStateCallback(deviceStateCallback1) + builder.addSessionStateCallback(sessionCallback1) + builder.setTemplateType(template1) + builder.addImplementationOptions(optionsBundle1) + builder.addErrorListener(errorListener1) + val sessionConfig = builder.build() + + // 2. Act + // builder change should not affect the instance built earlier. + builder.addSurface(deferrableSurface2) + builder.setExpectedFrameRateRange(fpsRange2) + builder.addCameraCaptureCallback(callback2) + builder.addRepeatingCameraCaptureCallback(callback2) + builder.addDeviceStateCallback(deviceStateCallback2) + builder.addSessionStateCallback(sessionCallback2) + builder.setTemplateType(template2) + builder.addImplementationOptions(optionsBundle2) + builder.addErrorListener(errorListener2) + + // 3. Verify + assertThat(sessionConfig.surfaces).containsExactly(deferrableSurface1) + assertThat(sessionConfig.expectedFrameRateRange).isEqualTo(fpsRange1) + assertThat(sessionConfig.singleCameraCaptureCallbacks).containsExactly(callback1) + assertThat(sessionConfig.repeatingCaptureConfig.cameraCaptureCallbacks) + .containsExactly(callback1) + assertThat(sessionConfig.deviceStateCallbacks).containsExactly(deviceStateCallback1) + assertThat(sessionConfig.sessionStateCallbacks).containsExactly(sessionCallback1) + assertThat(sessionConfig.templateType).isEqualTo(template1) + assertThat(sessionConfig.implementationOptions.retrieveOption(OPTION)).isEqualTo(1) + assertThat(sessionConfig.errorListeners).containsExactly(errorListener1) + } + + @Test + fun validatingBuilderChange_doNotChangeEarlierBuiltInstance() { + // 1. Arrange + val callback1 = mock( + CameraCaptureCallback::class.java + ) + val callback2 = mock( + CameraCaptureCallback::class.java + ) + val deferrableSurface1 = mock( + DeferrableSurface::class.java + ) + val deferrableSurface2 = mock( + DeferrableSurface::class.java + ) + val deviceStateCallback1 = mock( + CameraDevice.StateCallback::class.java + ) + val deviceStateCallback2 = mock( + CameraDevice.StateCallback::class.java + ) + val sessionCallback1 = + mock(CameraCaptureSession.StateCallback::class.java) + val sessionCallback2 = + mock(CameraCaptureSession.StateCallback::class.java) + val errorListener1 = mock( + SessionConfig.ErrorListener::class.java + ) + val errorListener2 = mock( + SessionConfig.ErrorListener::class.java + ) + val fpsRange1 = Range(30, 30) + val fpsRange2 = Range(15, 30) + val optionsBundle1 = MutableOptionsBundle.create() + optionsBundle1.insertOption(OPTION, 1) + val optionsBundle2 = MutableOptionsBundle.create() + optionsBundle2.insertOption(OPTION, 2) + val template1 = CameraDevice.TEMPLATE_PREVIEW + val template2 = CameraDevice.TEMPLATE_RECORD + + val builder = SessionConfig.Builder() + builder.addSurface(deferrableSurface1) + builder.setExpectedFrameRateRange(fpsRange1) + builder.addCameraCaptureCallback(callback1) + builder.addRepeatingCameraCaptureCallback(callback1) + builder.addDeviceStateCallback(deviceStateCallback1) + builder.addSessionStateCallback(sessionCallback1) + builder.setTemplateType(template1) + builder.addImplementationOptions(optionsBundle1) + builder.addErrorListener(errorListener1) + + val validatingBuilder = ValidatingBuilder() + validatingBuilder.add(builder.build()) + val sessionConfig = validatingBuilder.build() + + // 2. Act + // add another SessionConfig to ValidatingBuilder. This should not affect the + // instance built earlier. + val builder2 = SessionConfig.Builder() + builder2.addSurface(deferrableSurface2) + builder2.setExpectedFrameRateRange(fpsRange2) + builder2.addCameraCaptureCallback(callback2) + builder2.addRepeatingCameraCaptureCallback(callback2) + builder2.addDeviceStateCallback(deviceStateCallback2) + builder2.addSessionStateCallback(sessionCallback2) + builder2.setTemplateType(template2) + builder2.addImplementationOptions(optionsBundle2) + builder2.addErrorListener(errorListener2) + validatingBuilder.add(builder2.build()) + + // 3. Verify + assertThat(sessionConfig.surfaces).containsExactly(deferrableSurface1) + assertThat(sessionConfig.expectedFrameRateRange).isEqualTo(fpsRange1) + assertThat(sessionConfig.singleCameraCaptureCallbacks).containsExactly(callback1) + assertThat(sessionConfig.repeatingCaptureConfig.cameraCaptureCallbacks) + .containsExactly(callback1) + assertThat(sessionConfig.deviceStateCallbacks).containsExactly(deviceStateCallback1) + assertThat(sessionConfig.sessionStateCallbacks).containsExactly(sessionCallback1) + assertThat(sessionConfig.templateType).isEqualTo(template1) + assertThat(sessionConfig.implementationOptions.retrieveOption(OPTION)).isEqualTo(1) + assertThat(sessionConfig.errorListeners).containsExactly(errorListener1) + } + + private fun createSessionConfigWithTag(key: String, tagValue: Any): SessionConfig { + val builder1 = SessionConfig.Builder() + builder1.addSurface(mMockSurface1!!) + builder1.setTemplateType(CameraDevice.TEMPLATE_PREVIEW) + builder1.addTag(key, tagValue) + + return builder1.build() + } + + companion object { + private val OPTION = Option.create<Int>( + "camerax.test.option_0", Int::class.java + ) + private val OPTION_1 = Option.create<String>( + "camerax.test.option_1", String::class.java + ) + } +} |