1 /* 2 * Copyright 2020 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.camera2.internal; 18 19 import static org.mockito.ArgumentMatchers.any; 20 import static org.mockito.Mockito.mock; 21 import static org.mockito.Mockito.times; 22 import static org.mockito.Mockito.verify; 23 24 import android.hardware.camera2.CameraAccessException; 25 import android.hardware.camera2.CameraCaptureSession; 26 import android.hardware.camera2.CameraDevice; 27 import android.hardware.camera2.CaptureRequest; 28 import android.os.Build; 29 import android.os.Handler; 30 import android.view.Surface; 31 32 import androidx.camera.camera2.internal.compat.params.OutputConfigurationCompat; 33 import androidx.camera.camera2.internal.compat.params.SessionConfigurationCompat; 34 import androidx.camera.core.impl.ImmediateSurface; 35 import androidx.camera.core.impl.utils.executor.CameraXExecutors; 36 37 import org.junit.Before; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 import org.robolectric.RobolectricTestRunner; 41 import org.robolectric.annotation.Config; 42 import org.robolectric.annotation.internal.DoNotInstrument; 43 44 import java.util.ArrayList; 45 import java.util.Arrays; 46 import java.util.List; 47 import java.util.concurrent.Executors; 48 import java.util.concurrent.ScheduledExecutorService; 49 50 @SuppressWarnings({"deprecation", "unchecked"}) 51 @RunWith(RobolectricTestRunner.class) 52 @DoNotInstrument 53 @Config(minSdk = Build.VERSION_CODES.LOLLIPOP, 54 instrumentedPackages = { "androidx.camera.camera2.internal.compat.params" }) 55 public class SynchronizedCaptureSessionBaseTest { 56 57 private static final int NUM_OUTPUTS = 3; 58 59 private CameraCaptureSession mMockCaptureSession; 60 private SynchronizedCaptureSession.StateCallback mMockStateCallback; 61 private List<OutputConfigurationCompat> mOutputs; 62 private SynchronizedCaptureSessionBaseImpl mSyncCaptureSessionBaseImpl; 63 private CaptureSessionRepository mMockCaptureSessionRepository; 64 private ScheduledExecutorService mScheduledExecutorService = 65 Executors.newSingleThreadScheduledExecutor(); 66 67 @Before setUp()68 public void setUp() { 69 mMockCaptureSessionRepository = mock(CaptureSessionRepository.class); 70 71 mSyncCaptureSessionBaseImpl = 72 new SynchronizedCaptureSessionBaseImpl(mMockCaptureSessionRepository, 73 CameraXExecutors.directExecutor(), mScheduledExecutorService, 74 mock(Handler.class)); 75 76 mMockCaptureSession = mock(CameraCaptureSession.class); 77 mMockStateCallback = mock(SynchronizedCaptureSession.StateCallback.class); 78 mOutputs = new ArrayList<>(NUM_OUTPUTS); 79 for (int i = 0; i < NUM_OUTPUTS; ++i) { 80 mOutputs.add(mock(OutputConfigurationCompat.class)); 81 } 82 } 83 84 @Test callbackShouldWork_onReady()85 public void callbackShouldWork_onReady() { 86 SessionConfigurationCompat sessionConfigurationCompat = 87 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 88 SessionConfigurationCompat.SESSION_REGULAR, 89 mOutputs, 90 mMockStateCallback); 91 92 sessionConfigurationCompat.getStateCallback().onReady(mMockCaptureSession); 93 94 verify(mMockStateCallback).onReady(any(SynchronizedCaptureSession.class)); 95 } 96 97 @Test callbackShouldWork_onActive()98 public void callbackShouldWork_onActive() { 99 SessionConfigurationCompat sessionConfigurationCompat = 100 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 101 SessionConfigurationCompat.SESSION_REGULAR, 102 mOutputs, 103 mMockStateCallback); 104 105 sessionConfigurationCompat.getStateCallback().onActive(mMockCaptureSession); 106 107 verify(mMockStateCallback).onActive(any(SynchronizedCaptureSession.class)); 108 } 109 110 @Test 111 @Config(minSdk = Build.VERSION_CODES.O) callbackShouldWork_onCaptureQueueEmpty()112 public void callbackShouldWork_onCaptureQueueEmpty() { 113 SessionConfigurationCompat sessionConfigurationCompat = 114 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 115 SessionConfigurationCompat.SESSION_REGULAR, 116 mOutputs, 117 mMockStateCallback); 118 119 sessionConfigurationCompat.getStateCallback().onCaptureQueueEmpty(mMockCaptureSession); 120 121 verify(mMockStateCallback).onCaptureQueueEmpty(any(SynchronizedCaptureSession.class)); 122 } 123 124 @Test 125 @Config(minSdk = Build.VERSION_CODES.M) callbackShouldWork_onSurfacePrepared()126 public void callbackShouldWork_onSurfacePrepared() { 127 SessionConfigurationCompat sessionConfigurationCompat = 128 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 129 SessionConfigurationCompat.SESSION_REGULAR, 130 mOutputs, 131 mMockStateCallback); 132 133 sessionConfigurationCompat.getStateCallback().onSurfacePrepared(mMockCaptureSession, 134 mock(Surface.class)); 135 136 verify(mMockStateCallback).onSurfacePrepared(any(SynchronizedCaptureSession.class), 137 any(Surface.class)); 138 } 139 140 @Test callbackShouldWork_onConfigured()141 public void callbackShouldWork_onConfigured() { 142 SessionConfigurationCompat sessionConfigurationCompat = 143 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 144 SessionConfigurationCompat.SESSION_REGULAR, 145 mOutputs, 146 mMockStateCallback); 147 148 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 149 sessionConfigurationCompat, 150 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 151 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 152 153 verify(mMockStateCallback).onConfigured(any(SynchronizedCaptureSession.class)); 154 verify(mMockCaptureSessionRepository, times(1)).onCaptureSessionCreated( 155 any(SynchronizedCaptureSession.class)); 156 } 157 158 @Test callbackShouldWork_onConfigureFailed()159 public void callbackShouldWork_onConfigureFailed() { 160 SessionConfigurationCompat sessionConfigurationCompat = 161 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 162 SessionConfigurationCompat.SESSION_REGULAR, 163 mOutputs, 164 mMockStateCallback); 165 166 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 167 sessionConfigurationCompat, 168 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 169 sessionConfigurationCompat.getStateCallback().onConfigureFailed(mMockCaptureSession); 170 171 verify(mMockStateCallback).onConfigureFailed(any(SynchronizedCaptureSession.class)); 172 } 173 174 @Test callbackShouldWork_onClosed()175 public void callbackShouldWork_onClosed() { 176 SessionConfigurationCompat sessionConfigurationCompat = 177 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 178 SessionConfigurationCompat.SESSION_REGULAR, 179 mOutputs, 180 mMockStateCallback); 181 182 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 183 sessionConfigurationCompat, 184 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 185 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 186 sessionConfigurationCompat.getStateCallback().onClosed(mMockCaptureSession); 187 188 verify(mMockStateCallback).onClosed(any(SynchronizedCaptureSession.class)); 189 verify(mMockCaptureSessionRepository, times(1)).onCaptureSessionClosed( 190 any(SynchronizedCaptureSession.class)); 191 } 192 193 @Test callClose_onSessionFinished_shouldBeCalled()194 public void callClose_onSessionFinished_shouldBeCalled() { 195 SessionConfigurationCompat sessionConfigurationCompat = 196 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 197 SessionConfigurationCompat.SESSION_REGULAR, 198 mOutputs, 199 mMockStateCallback); 200 201 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 202 sessionConfigurationCompat, 203 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 204 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 205 mSyncCaptureSessionBaseImpl.close(); 206 207 verify(mMockStateCallback).onSessionFinished( 208 any(SynchronizedCaptureSession.class)); 209 } 210 211 @Test callbackShouldWork_onSessionFinished()212 public void callbackShouldWork_onSessionFinished() { 213 SessionConfigurationCompat sessionConfigurationCompat = 214 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 215 SessionConfigurationCompat.SESSION_REGULAR, 216 mOutputs, 217 mMockStateCallback); 218 219 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 220 sessionConfigurationCompat, 221 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 222 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 223 sessionConfigurationCompat.getStateCallback().onClosed(mMockCaptureSession); 224 225 verify(mMockStateCallback).onSessionFinished( 226 any(SynchronizedCaptureSession.class)); 227 } 228 229 @Test shouldForwardAfterOnConfigured()230 public void shouldForwardAfterOnConfigured() throws CameraAccessException { 231 SessionConfigurationCompat sessionConfigurationCompat = 232 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 233 SessionConfigurationCompat.SESSION_REGULAR, 234 mOutputs, 235 mMockStateCallback); 236 237 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 238 sessionConfigurationCompat, 239 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 240 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 241 242 mSyncCaptureSessionBaseImpl.captureSingleRequest(mock(CaptureRequest.class), 243 mock(CameraCaptureSession.CaptureCallback.class)); 244 } 245 246 @Test forwardBeforeOnConfigured_captureBurstRequests()247 public void forwardBeforeOnConfigured_captureBurstRequests() throws CameraAccessException { 248 SessionConfigurationCompat sessionConfigurationCompat = 249 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 250 SessionConfigurationCompat.SESSION_REGULAR, 251 mOutputs, 252 mMockStateCallback); 253 254 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 255 sessionConfigurationCompat, 256 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 257 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 258 259 mSyncCaptureSessionBaseImpl.captureBurstRequests(mock(List.class), 260 mock(CameraCaptureSession.CaptureCallback.class)); 261 } 262 263 @Test forwardBeforeOnConfigured_setRepeatingBurstRequests()264 public void forwardBeforeOnConfigured_setRepeatingBurstRequests() 265 throws CameraAccessException { 266 SessionConfigurationCompat sessionConfigurationCompat = 267 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 268 SessionConfigurationCompat.SESSION_REGULAR, 269 mOutputs, 270 mMockStateCallback); 271 272 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 273 sessionConfigurationCompat, 274 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 275 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 276 277 mSyncCaptureSessionBaseImpl.setRepeatingBurstRequests(mock(List.class), 278 mock(CameraCaptureSession.CaptureCallback.class)); 279 } 280 281 @Test forwardBeforeOnConfigured_setSingleRepeatingRequest()282 public void forwardBeforeOnConfigured_setSingleRepeatingRequest() 283 throws CameraAccessException { 284 SessionConfigurationCompat sessionConfigurationCompat = 285 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 286 SessionConfigurationCompat.SESSION_REGULAR, 287 mOutputs, 288 mMockStateCallback); 289 290 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 291 sessionConfigurationCompat, 292 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 293 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 294 295 mSyncCaptureSessionBaseImpl.setSingleRepeatingRequest(mock(CaptureRequest.class), 296 mock(CameraCaptureSession.CaptureCallback.class)); 297 } 298 299 @Test forwardBeforeOnConfigured_abortCaptures()300 public void forwardBeforeOnConfigured_abortCaptures() 301 throws CameraAccessException { 302 SessionConfigurationCompat sessionConfigurationCompat = 303 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 304 SessionConfigurationCompat.SESSION_REGULAR, 305 mOutputs, 306 mMockStateCallback); 307 308 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 309 sessionConfigurationCompat, 310 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 311 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 312 313 mSyncCaptureSessionBaseImpl.abortCaptures(); 314 } 315 316 @Test forwardBeforeOnConfigured_stopRepeating()317 public void forwardBeforeOnConfigured_stopRepeating() 318 throws CameraAccessException { 319 SessionConfigurationCompat sessionConfigurationCompat = 320 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 321 SessionConfigurationCompat.SESSION_REGULAR, 322 mOutputs, 323 mMockStateCallback); 324 325 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 326 sessionConfigurationCompat, 327 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 328 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 329 330 mSyncCaptureSessionBaseImpl.stopRepeating(); 331 } 332 333 @Test forwardBeforeOnConfigured_getDevice()334 public void forwardBeforeOnConfigured_getDevice() { 335 SessionConfigurationCompat sessionConfigurationCompat = 336 mSyncCaptureSessionBaseImpl.createSessionConfigurationCompat( 337 SessionConfigurationCompat.SESSION_REGULAR, 338 mOutputs, 339 mMockStateCallback); 340 341 mSyncCaptureSessionBaseImpl.openCaptureSession(mock(CameraDevice.class), 342 sessionConfigurationCompat, 343 Arrays.asList(new ImmediateSurface(mock(Surface.class)))); 344 sessionConfigurationCompat.getStateCallback().onConfigured(mMockCaptureSession); 345 346 mSyncCaptureSessionBaseImpl.getDevice(); 347 } 348 349 @Test(expected = NullPointerException.class) notForwardBeforeOnConfigured_captureSingleRequest()350 public void notForwardBeforeOnConfigured_captureSingleRequest() throws CameraAccessException { 351 mSyncCaptureSessionBaseImpl.captureSingleRequest(mock(CaptureRequest.class), 352 mock(CameraCaptureSession.CaptureCallback.class)); 353 } 354 355 @Test(expected = NullPointerException.class) notForwardBeforeOnConfigured_captureBurstRequests()356 public void notForwardBeforeOnConfigured_captureBurstRequests() throws CameraAccessException { 357 mSyncCaptureSessionBaseImpl.captureBurstRequests(mock(List.class), 358 mock(CameraCaptureSession.CaptureCallback.class)); 359 } 360 361 @Test(expected = NullPointerException.class) notForwardBeforeOnConfigured_setRepeatingBurstRequests()362 public void notForwardBeforeOnConfigured_setRepeatingBurstRequests() 363 throws CameraAccessException { 364 mSyncCaptureSessionBaseImpl.setRepeatingBurstRequests(mock(List.class), 365 mock(CameraCaptureSession.CaptureCallback.class)); 366 } 367 368 @Test(expected = NullPointerException.class) notForwardBeforeOnConfigured_setSingleRepeatingRequest()369 public void notForwardBeforeOnConfigured_setSingleRepeatingRequest() 370 throws CameraAccessException { 371 mSyncCaptureSessionBaseImpl.setSingleRepeatingRequest(mock(CaptureRequest.class), 372 mock(CameraCaptureSession.CaptureCallback.class)); 373 } 374 375 @Test(expected = NullPointerException.class) notForwardBeforeOnConfigured_abortCaptures()376 public void notForwardBeforeOnConfigured_abortCaptures() 377 throws CameraAccessException { 378 mSyncCaptureSessionBaseImpl.abortCaptures(); 379 } 380 381 @Test(expected = NullPointerException.class) notForwardBeforeOnConfigured_stopRepeating()382 public void notForwardBeforeOnConfigured_stopRepeating() 383 throws CameraAccessException { 384 mSyncCaptureSessionBaseImpl.stopRepeating(); 385 } 386 387 @Test(expected = NullPointerException.class) notForwardBeforeOnConfigured_getDevice()388 public void notForwardBeforeOnConfigured_getDevice() { 389 mSyncCaptureSessionBaseImpl.getDevice(); 390 } 391 392 } 393