1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.camera.testing.fakes; 18 19 import static android.graphics.ImageFormat.YUV_420_888; 20 21 import static androidx.camera.core.impl.StreamSpec.FRAME_RATE_RANGE_UNSPECIFIED; 22 import static androidx.camera.core.impl.SurfaceConfig.ConfigSize.PREVIEW; 23 import static androidx.camera.core.impl.SurfaceConfig.ConfigType.YUV; 24 25 import static com.google.common.truth.Truth.assertThat; 26 27 import static java.util.Collections.emptyList; 28 import static java.util.Collections.singletonList; 29 30 import android.os.Build; 31 import android.util.Range; 32 import android.util.Size; 33 34 import androidx.camera.core.DynamicRange; 35 import androidx.camera.core.ImageAnalysis; 36 import androidx.camera.core.impl.AttachedSurfaceInfo; 37 import androidx.camera.core.impl.CameraMode; 38 import androidx.camera.core.impl.StreamSpec; 39 import androidx.camera.core.impl.SurfaceConfig; 40 import androidx.camera.core.impl.UseCaseConfig; 41 import androidx.camera.core.impl.UseCaseConfigFactory; 42 import androidx.camera.testing.impl.fakes.FakeCameraDeviceSurfaceManager; 43 import androidx.camera.testing.impl.fakes.FakeUseCaseConfig; 44 45 import org.jspecify.annotations.NonNull; 46 import org.junit.Before; 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 import org.robolectric.RobolectricTestRunner; 50 import org.robolectric.annotation.Config; 51 import org.robolectric.annotation.internal.DoNotInstrument; 52 53 import java.util.Collections; 54 import java.util.HashMap; 55 import java.util.List; 56 import java.util.Map; 57 58 /** 59 * Unit tests for {@link FakeCameraDeviceSurfaceManager}. 60 */ 61 @RunWith(RobolectricTestRunner.class) 62 @DoNotInstrument 63 @Config(minSdk = Build.VERSION_CODES.LOLLIPOP) 64 public class FakeCameraDeviceSurfaceManagerTest { 65 66 private static final int FAKE_WIDTH0 = 400; 67 private static final int FAKE_HEIGHT0 = 300; 68 69 private static final int FAKE_WIDTH1 = 800; 70 private static final int FAKE_HEIGHT1 = 600; 71 72 private static final String FAKE_CAMERA_ID0 = "0"; 73 private static final String FAKE_CAMERA_ID1 = "1"; 74 75 private FakeCameraDeviceSurfaceManager mFakeCameraDeviceSurfaceManager; 76 77 private FakeUseCaseConfig mFakeUseCaseConfig; 78 79 @Before setUp()80 public void setUp() { 81 mFakeCameraDeviceSurfaceManager = new FakeCameraDeviceSurfaceManager(); 82 mFakeUseCaseConfig = new FakeUseCaseConfig.Builder().getUseCaseConfig(); 83 84 mFakeCameraDeviceSurfaceManager.setSuggestedStreamSpec(FAKE_CAMERA_ID0, 85 mFakeUseCaseConfig.getClass(), 86 StreamSpec.builder(new Size(FAKE_WIDTH0, FAKE_HEIGHT0)).build()); 87 mFakeCameraDeviceSurfaceManager.setSuggestedStreamSpec(FAKE_CAMERA_ID1, 88 mFakeUseCaseConfig.getClass(), 89 StreamSpec.builder(new Size(FAKE_WIDTH1, FAKE_HEIGHT1)).build()); 90 } 91 92 @Test validSurfaceCombination_noException()93 public void validSurfaceCombination_noException() { 94 UseCaseConfig<?> preview = new FakeUseCaseConfig.Builder().getUseCaseConfig(); 95 UseCaseConfig<?> analysis = new ImageAnalysis.Builder().getUseCaseConfig(); 96 mFakeCameraDeviceSurfaceManager.getSuggestedStreamSpecs( 97 CameraMode.DEFAULT, 98 FAKE_CAMERA_ID0, 99 emptyList(), 100 createConfigOutputSizesMap(preview, analysis), 101 false, 102 false); 103 } 104 105 @Test(expected = IllegalArgumentException.class) invalidSurfaceAndConfigCombination_throwException()106 public void invalidSurfaceAndConfigCombination_throwException() { 107 UseCaseConfig<?> preview = new FakeUseCaseConfig.Builder().getUseCaseConfig(); 108 UseCaseConfig<?> video = new FakeUseCaseConfig.Builder().getUseCaseConfig(); 109 AttachedSurfaceInfo analysis = AttachedSurfaceInfo.create( 110 SurfaceConfig.create(YUV, PREVIEW), 111 YUV_420_888, 112 new Size(1, 1), 113 DynamicRange.SDR, 114 singletonList(UseCaseConfigFactory.CaptureType.IMAGE_ANALYSIS), 115 preview, 116 new Range<>(30, 30), 117 FRAME_RATE_RANGE_UNSPECIFIED); 118 mFakeCameraDeviceSurfaceManager.getSuggestedStreamSpecs( 119 CameraMode.DEFAULT, 120 FAKE_CAMERA_ID0, 121 singletonList(analysis), createConfigOutputSizesMap(preview, video), 122 false, 123 false); 124 } 125 126 @Test(expected = IllegalArgumentException.class) invalidConfigCombination_throwException()127 public void invalidConfigCombination_throwException() { 128 UseCaseConfig<?> preview = new FakeUseCaseConfig.Builder().getUseCaseConfig(); 129 UseCaseConfig<?> video = new FakeUseCaseConfig.Builder().getUseCaseConfig(); 130 UseCaseConfig<?> analysis = new ImageAnalysis.Builder().getUseCaseConfig(); 131 mFakeCameraDeviceSurfaceManager.getSuggestedStreamSpecs( 132 CameraMode.DEFAULT, 133 FAKE_CAMERA_ID0, 134 Collections.emptyList(), createConfigOutputSizesMap(preview, video, analysis), 135 false, 136 false); 137 } 138 139 @Test canRetrieveInsertedSuggestedStreamSpecs()140 public void canRetrieveInsertedSuggestedStreamSpecs() { 141 Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecsCamera0 = 142 mFakeCameraDeviceSurfaceManager.getSuggestedStreamSpecs( 143 CameraMode.DEFAULT, 144 FAKE_CAMERA_ID0, 145 emptyList(), createConfigOutputSizesMap(mFakeUseCaseConfig), 146 false, 147 false).first; 148 Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecCamera1 = 149 mFakeCameraDeviceSurfaceManager.getSuggestedStreamSpecs( 150 CameraMode.DEFAULT, 151 FAKE_CAMERA_ID1, 152 emptyList(), createConfigOutputSizesMap(mFakeUseCaseConfig), 153 false, 154 false).first; 155 156 assertThat(suggestedStreamSpecsCamera0.get(mFakeUseCaseConfig)).isEqualTo( 157 StreamSpec.builder(new Size(FAKE_WIDTH0, FAKE_HEIGHT0)).build()); 158 assertThat(suggestedStreamSpecCamera1.get(mFakeUseCaseConfig)).isEqualTo( 159 StreamSpec.builder(new Size(FAKE_WIDTH1, FAKE_HEIGHT1)).build()); 160 } 161 createConfigOutputSizesMap( UseCaseConfig<?> @onNull .... useCaseConfigs)162 private Map<UseCaseConfig<?>, List<Size>> createConfigOutputSizesMap( 163 UseCaseConfig<?> @NonNull ... useCaseConfigs) { 164 Map<UseCaseConfig<?>, List<Size>> configOutputSizesMap = new HashMap<>(); 165 for (UseCaseConfig<?> useCaseConfig : useCaseConfigs) { 166 configOutputSizesMap.put(useCaseConfig, Collections.emptyList()); 167 } 168 return configOutputSizesMap; 169 } 170 } 171