|  |  |  | @ -28,14 +28,20 @@ import com.otaliastudios.cameraview.controls.WhiteBalance; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.engine.orchestrator.CameraState; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.frame.Frame; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.frame.FrameProcessor; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.size.SizeSelectors; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.tools.Emulator; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.tools.Op; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.internal.utils.WorkerHandler; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.overlay.Overlay; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.size.Size; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.tools.Retry; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.tools.RetryRule; | 
			
		
	
		
			
				
					|  |  |  |  | import com.otaliastudios.cameraview.tools.SdkExclude; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | import androidx.annotation.NonNull; | 
			
		
	
		
			
				
					|  |  |  |  | import androidx.annotation.Nullable; | 
			
		
	
		
			
				
					|  |  |  |  | import androidx.test.rule.ActivityTestRule; | 
			
		
	
		
			
				
					|  |  |  |  | import androidx.test.rule.GrantPermissionRule; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | import org.junit.After; | 
			
		
	
		
			
				
					|  |  |  |  | import org.junit.Before; | 
			
		
	
	
		
			
				
					|  |  |  | @ -64,89 +70,102 @@ import static org.mockito.Mockito.times; | 
			
		
	
		
			
				
					|  |  |  |  | import static org.mockito.Mockito.verify; | 
			
		
	
		
			
				
					|  |  |  |  | import static org.mockito.Mockito.when; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  | public abstract class CameraIntegrationTest<E extends CameraEngine> extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private final static CameraLogger LOG = CameraLogger.create(CameraIntegrationTest.class.getSimpleName()); | 
			
		
	
		
			
				
					|  |  |  |  |     private final static long DELAY = 8000; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Rule | 
			
		
	
		
			
				
					|  |  |  |  |     public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class); | 
			
		
	
		
			
				
					|  |  |  |  |     public ActivityTestRule<TestActivity> activityRule = new ActivityTestRule<>(TestActivity.class); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private CameraView camera; | 
			
		
	
		
			
				
					|  |  |  |  |     protected CameraEngine controller; | 
			
		
	
		
			
				
					|  |  |  |  |     private CameraListener listener; | 
			
		
	
		
			
				
					|  |  |  |  |     private Op<Throwable> uiExceptionOp; | 
			
		
	
		
			
				
					|  |  |  |  |     @Rule | 
			
		
	
		
			
				
					|  |  |  |  |     public RetryRule retryRule = new RetryRule(3); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @BeforeClass | 
			
		
	
		
			
				
					|  |  |  |  |     public static void grant() { | 
			
		
	
		
			
				
					|  |  |  |  |         grantAllPermissions(); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     @Rule | 
			
		
	
		
			
				
					|  |  |  |  |     public GrantPermissionRule permissionRule = GrantPermissionRule.grant( | 
			
		
	
		
			
				
					|  |  |  |  |             "android.permission.CAMERA", | 
			
		
	
		
			
				
					|  |  |  |  |             "android.permission.RECORD_AUDIO", | 
			
		
	
		
			
				
					|  |  |  |  |             "android.permission.WRITE_EXTERNAL_STORAGE" | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     protected CameraView camera; | 
			
		
	
		
			
				
					|  |  |  |  |     protected E controller; | 
			
		
	
		
			
				
					|  |  |  |  |     private CameraListener listener; | 
			
		
	
		
			
				
					|  |  |  |  |     private Op<Throwable> error; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @NonNull | 
			
		
	
		
			
				
					|  |  |  |  |     protected abstract Engine getEngine(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Before | 
			
		
	
		
			
				
					|  |  |  |  |     public void setUp() { | 
			
		
	
		
			
				
					|  |  |  |  |         LOG.e("Test started. Setting up camera."); | 
			
		
	
		
			
				
					|  |  |  |  |         LOG.w("[TEST STARTED]", "Setting up camera."); | 
			
		
	
		
			
				
					|  |  |  |  |         WorkerHandler.destroyAll(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         uiSync(new Runnable() { | 
			
		
	
		
			
				
					|  |  |  |  |             @Override | 
			
		
	
		
			
				
					|  |  |  |  |             public void run() { | 
			
		
	
		
			
				
					|  |  |  |  |                 camera = new CameraView(rule.getActivity()) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 camera = new CameraView(activityRule.getActivity()) { | 
			
		
	
		
			
				
					|  |  |  |  |                     @NonNull | 
			
		
	
		
			
				
					|  |  |  |  |                     @Override | 
			
		
	
		
			
				
					|  |  |  |  |                     protected CameraEngine instantiateCameraEngine(@NonNull Engine engine, @NonNull CameraEngine.Callback callback) { | 
			
		
	
		
			
				
					|  |  |  |  |                         controller = super.instantiateCameraEngine(getEngine(), callback); | 
			
		
	
		
			
				
					|  |  |  |  |                     protected CameraEngine instantiateCameraEngine( | 
			
		
	
		
			
				
					|  |  |  |  |                             @NonNull Engine engine, | 
			
		
	
		
			
				
					|  |  |  |  |                             @NonNull CameraEngine.Callback callback) { | 
			
		
	
		
			
				
					|  |  |  |  |                         //noinspection unchecked
 | 
			
		
	
		
			
				
					|  |  |  |  |                         controller = (E) super.instantiateCameraEngine(getEngine(), callback); | 
			
		
	
		
			
				
					|  |  |  |  |                         return controller; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                 }; | 
			
		
	
		
			
				
					|  |  |  |  |                 listener = mock(CameraListener.class); | 
			
		
	
		
			
				
					|  |  |  |  |                 camera.setExperimental(true); | 
			
		
	
		
			
				
					|  |  |  |  |                 camera.setEngine(getEngine()); | 
			
		
	
		
			
				
					|  |  |  |  |                 camera.addCameraListener(listener); | 
			
		
	
		
			
				
					|  |  |  |  |                 rule.getActivity().inflate(camera); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 // Ensure that controller exceptions are thrown on this thread (not on the UI thread).
 | 
			
		
	
		
			
				
					|  |  |  |  |                 // TODO this makes debugging for wrong tests very hard, as we don't get the exception
 | 
			
		
	
		
			
				
					|  |  |  |  |                 // unless waitForUiException() is called.
 | 
			
		
	
		
			
				
					|  |  |  |  |                 uiExceptionOp = new Op<>(); | 
			
		
	
		
			
				
					|  |  |  |  |                 WorkerHandler crashThread = WorkerHandler.get("CrashThread"); | 
			
		
	
		
			
				
					|  |  |  |  |                 crashThread.getThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { | 
			
		
	
		
			
				
					|  |  |  |  |                     @Override | 
			
		
	
		
			
				
					|  |  |  |  |                     public void uncaughtException(Thread t, Throwable e) { | 
			
		
	
		
			
				
					|  |  |  |  |                         uiExceptionOp.controller().end(e); | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                 }); | 
			
		
	
		
			
				
					|  |  |  |  |                 controller.mCrashHandler = crashThread.getHandler(); | 
			
		
	
		
			
				
					|  |  |  |  |                 activityRule.getActivity().inflate(camera); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         }); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         listener = mock(CameraListener.class); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.addCameraListener(listener); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         error = new Op<>(); | 
			
		
	
		
			
				
					|  |  |  |  |         WorkerHandler crashThread = WorkerHandler.get("CrashThread"); | 
			
		
	
		
			
				
					|  |  |  |  |         crashThread.getThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { | 
			
		
	
		
			
				
					|  |  |  |  |             @Override | 
			
		
	
		
			
				
					|  |  |  |  |             public void uncaughtException(@NonNull Thread thread, @NonNull Throwable exception) { | 
			
		
	
		
			
				
					|  |  |  |  |                 error.controller().end(exception); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         }); | 
			
		
	
		
			
				
					|  |  |  |  |         controller.mCrashHandler = crashThread.getHandler(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         camera.addCameraListener(new CameraListener() { | 
			
		
	
		
			
				
					|  |  |  |  |             @Override | 
			
		
	
		
			
				
					|  |  |  |  |             public void onCameraError(@NonNull CameraException exception) { | 
			
		
	
		
			
				
					|  |  |  |  |                 super.onCameraError(exception); | 
			
		
	
		
			
				
					|  |  |  |  |                 if (exception.isUnrecoverable()) { | 
			
		
	
		
			
				
					|  |  |  |  |                     LOG.e("[UNRECOVERABLE CAMERAEXCEPTION]", | 
			
		
	
		
			
				
					|  |  |  |  |                             "Got unrecoverable exception, not clear what to do in a test."); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         }); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @After | 
			
		
	
		
			
				
					|  |  |  |  |     public void tearDown() { | 
			
		
	
		
			
				
					|  |  |  |  |         LOG.e("Test ended. Tearing down camera."); | 
			
		
	
		
			
				
					|  |  |  |  |         LOG.w("[TEST ENDED]", "Tearing down camera."); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.destroy(); | 
			
		
	
		
			
				
					|  |  |  |  |         WorkerHandler.destroyAll(); | 
			
		
	
		
			
				
					|  |  |  |  |         LOG.w("[TEST ENDED]", "Torn down camera."); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private void waitForUiException() throws Throwable { | 
			
		
	
		
			
				
					|  |  |  |  |         Throwable throwable = uiExceptionOp.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         if (throwable != null) { | 
			
		
	
		
			
				
					|  |  |  |  |             throw throwable; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private CameraOptions openSync(boolean expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.open(); | 
			
		
	
		
			
				
					|  |  |  |  |     protected final CameraOptions openSync(boolean expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |         final Op<CameraOptions> open = new Op<>(); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(open, 0).when(listener).onCameraOpened(any(CameraOptions.class)); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.open(); | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions result = open.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         if (expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[OPEN SYNC]", "Expecting success."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull("Can open", result); | 
			
		
	
		
			
				
					|  |  |  |  |             onOpenSync(); | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[OPEN SYNC]", "Expecting failure."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNull("Should not open", result); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         return result; | 
			
		
	
	
		
			
				
					|  |  |  | @ -160,14 +179,16 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |         while (controller.getState() != CameraState.PREVIEW) {} | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private void closeSync(boolean expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.close(); | 
			
		
	
		
			
				
					|  |  |  |  |     protected final void closeSync(boolean expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |         final Op<Boolean> close = new Op<>(); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(close, true).when(listener).onCameraClosed(); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.close(); | 
			
		
	
		
			
				
					|  |  |  |  |         Boolean result = close.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         if (expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[CLOSE SYNC]", "Expecting success."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull("Can close", result); | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[CLOSE SYNC]", "Expecting failure."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNull("Should not close", result); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  |  | @ -175,45 +196,64 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     @SuppressWarnings("UnusedReturnValue") | 
			
		
	
		
			
				
					|  |  |  |  |     @Nullable | 
			
		
	
		
			
				
					|  |  |  |  |     private VideoResult waitForVideoResult(boolean expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |         // CountDownLatch for onVideoRecordingEnd.
 | 
			
		
	
		
			
				
					|  |  |  |  |         CountDownLatch onVideoRecordingEnd = new CountDownLatch(1); | 
			
		
	
		
			
				
					|  |  |  |  |         doCountDown(onVideoRecordingEnd).when(listener).onVideoRecordingEnd(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // Op for onVideoTaken.
 | 
			
		
	
		
			
				
					|  |  |  |  |         final Op<VideoResult> video = new Op<>(); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(video, 0).when(listener).onVideoTaken(any(VideoResult.class)); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(video, null).when(listener).onCameraError(argThat(new ArgumentMatcher<CameraException>() { | 
			
		
	
		
			
				
					|  |  |  |  |         Op<Boolean> wait1 = new Op<>(); | 
			
		
	
		
			
				
					|  |  |  |  |         Op<VideoResult> wait2 = new Op<>(); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(wait1, true).when(listener).onVideoRecordingEnd(); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(wait1, false).when(listener).onCameraError(argThat(new ArgumentMatcher<CameraException>() { | 
			
		
	
		
			
				
					|  |  |  |  |             @Override | 
			
		
	
		
			
				
					|  |  |  |  |             public boolean matches(CameraException argument) { | 
			
		
	
		
			
				
					|  |  |  |  |                 return argument.getReason() == CameraException.REASON_VIDEO_FAILED; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         })); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(wait2, 0).when(listener).onVideoTaken(any(VideoResult.class)); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(wait2, null).when(listener).onCameraError(argThat(new ArgumentMatcher<CameraException>() { | 
			
		
	
		
			
				
					|  |  |  |  |             @Override | 
			
		
	
		
			
				
					|  |  |  |  |             public boolean matches(CameraException argument) { | 
			
		
	
		
			
				
					|  |  |  |  |                 return argument.getReason() == CameraException.REASON_VIDEO_FAILED; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         })); | 
			
		
	
		
			
				
					|  |  |  |  |         int maxLoops = 10; | 
			
		
	
		
			
				
					|  |  |  |  |         int loops = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // Wait for onVideoTaken and check.
 | 
			
		
	
		
			
				
					|  |  |  |  |         VideoResult result = video.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // First wait for onVideoRecordingEnd().
 | 
			
		
	
		
			
				
					|  |  |  |  |         // It seems that when running all the tests together, the device can go in some
 | 
			
		
	
		
			
				
					|  |  |  |  |         // power saving mode which makes the CPU extremely slow. This is especially problematic
 | 
			
		
	
		
			
				
					|  |  |  |  |         // with video snapshots where we do lots of processing. The videoEnd callback can return
 | 
			
		
	
		
			
				
					|  |  |  |  |         // long after the actual stop() call, so if we're still processing, let's wait more.
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (expectSuccess && camera.isTakingVideo()) { | 
			
		
	
		
			
				
					|  |  |  |  |             while (camera.isTakingVideo()) { | 
			
		
	
		
			
				
					|  |  |  |  |                 video.listen(); | 
			
		
	
		
			
				
					|  |  |  |  |                 result = video.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         LOG.i("[WAIT VIDEO]", "Waiting for onVideoRecordingEnd()..."); | 
			
		
	
		
			
				
					|  |  |  |  |         Boolean wait1Result = wait1.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         if (expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |             while (wait1Result == null && loops <= maxLoops) { | 
			
		
	
		
			
				
					|  |  |  |  |                 LOG.w("[WAIT VIDEO]", "Waiting extra", DELAY, "milliseconds..."); | 
			
		
	
		
			
				
					|  |  |  |  |                 wait1.listen(); | 
			
		
	
		
			
				
					|  |  |  |  |                 wait1Result = wait1.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |                 loops++; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // Now wait for onVideoResult(). One cycle should be enough.
 | 
			
		
	
		
			
				
					|  |  |  |  |         LOG.i("[WAIT VIDEO]", "Waiting for onVideoTaken()..."); | 
			
		
	
		
			
				
					|  |  |  |  |         VideoResult wait2Result = wait2.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         if (expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |             while (wait2Result == null && loops <= maxLoops) { | 
			
		
	
		
			
				
					|  |  |  |  |                 LOG.w("[WAIT VIDEO]", "Waiting extra", DELAY, "milliseconds..."); | 
			
		
	
		
			
				
					|  |  |  |  |                 wait2.listen(); | 
			
		
	
		
			
				
					|  |  |  |  |                 wait2Result = wait2.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |                 loops++; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             // Sleep another 1000, because camera.isTakingVideo() might return false even
 | 
			
		
	
		
			
				
					|  |  |  |  |             // if the result still has to be dispatched. Rare but could happen.
 | 
			
		
	
		
			
				
					|  |  |  |  |             try { Thread.sleep(1000); } catch (InterruptedException ignore) {} | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // Now we should be OK.
 | 
			
		
	
		
			
				
					|  |  |  |  |         // Assert.
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |             assertEquals("Should call onVideoRecordingEnd", 0, onVideoRecordingEnd.getCount()); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull("Should end video", result); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull("Should call onVideoRecordingEnd", wait1Result); | 
			
		
	
		
			
				
					|  |  |  |  |             assertTrue("Should call onVideoRecordingEnd", wait1Result); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull("Should call onVideoTaken", wait2Result); | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             assertNull("Should not end video", result); | 
			
		
	
		
			
				
					|  |  |  |  |             assertTrue("Should not call onVideoRecordingEnd", | 
			
		
	
		
			
				
					|  |  |  |  |                     wait1Result == null || !wait1Result); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNull("Should not call onVideoTaken", wait2Result); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         return result; | 
			
		
	
		
			
				
					|  |  |  |  |         return wait2Result; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Nullable | 
			
		
	
	
		
			
				
					|  |  |  | @ -228,18 +268,29 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |         })); | 
			
		
	
		
			
				
					|  |  |  |  |         PictureResult result = pic.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         if (expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[WAIT PICTURE]", "Expecting success."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull("Can take picture", result); | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[WAIT PICTURE]", "Expecting failure."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNull("Should not take picture", result); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         return result; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private void takeVideoSync(boolean expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |     /** | 
			
		
	
		
			
				
					|  |  |  |  |      * Emulators do not respond well to setVideoMaxDuration() with full videos. | 
			
		
	
		
			
				
					|  |  |  |  |      * The mediaRecorder.stop() call can hang forever. | 
			
		
	
		
			
				
					|  |  |  |  |      * @return true if possible | 
			
		
	
		
			
				
					|  |  |  |  |      */ | 
			
		
	
		
			
				
					|  |  |  |  |     protected boolean canSetVideoMaxDuration() { | 
			
		
	
		
			
				
					|  |  |  |  |         return !Emulator.isEmulator(); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     protected void takeVideoSync(boolean expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |         takeVideoSync(expectSuccess,0); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private void takeVideoSync(boolean expectSuccess, int duration) { | 
			
		
	
		
			
				
					|  |  |  |  |     protected void takeVideoSync(boolean expectSuccess, int duration) { | 
			
		
	
		
			
				
					|  |  |  |  |         final Op<Boolean> op = new Op<>(); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(op, true).when(listener).onVideoRecordingStart(); | 
			
		
	
		
			
				
					|  |  |  |  |         doEndOp(op, false).when(listener).onCameraError(argThat(new ArgumentMatcher<CameraException>() { | 
			
		
	
	
		
			
				
					|  |  |  | @ -250,15 +301,33 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |         })); | 
			
		
	
		
			
				
					|  |  |  |  |         File file = new File(getContext().getFilesDir(), "video.mp4"); | 
			
		
	
		
			
				
					|  |  |  |  |         if (duration > 0) { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.takeVideo(file, duration); | 
			
		
	
		
			
				
					|  |  |  |  |             if (canSetVideoMaxDuration()) { | 
			
		
	
		
			
				
					|  |  |  |  |                 camera.takeVideo(file, duration); | 
			
		
	
		
			
				
					|  |  |  |  |             } else { | 
			
		
	
		
			
				
					|  |  |  |  |                 final int delay = Math.round(duration * 1.2F); // Compensate for thread jumps, ...
 | 
			
		
	
		
			
				
					|  |  |  |  |                 uiSync(new Runnable() { | 
			
		
	
		
			
				
					|  |  |  |  |                     @Override | 
			
		
	
		
			
				
					|  |  |  |  |                     public void run() { | 
			
		
	
		
			
				
					|  |  |  |  |                         new Handler().postDelayed(new Runnable() { | 
			
		
	
		
			
				
					|  |  |  |  |                             @Override | 
			
		
	
		
			
				
					|  |  |  |  |                             public void run() { | 
			
		
	
		
			
				
					|  |  |  |  |                                 camera.stopVideo(); | 
			
		
	
		
			
				
					|  |  |  |  |                             } | 
			
		
	
		
			
				
					|  |  |  |  |                         }, delay); | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                 }); | 
			
		
	
		
			
				
					|  |  |  |  |                 camera.takeVideo(file); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.takeVideo(file); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Boolean result = op.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         if (expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[WAIT VIDEO START]", "Expecting success."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull("should start video recording or get CameraError", result); | 
			
		
	
		
			
				
					|  |  |  |  |             assertTrue("should start video recording successfully", result); | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[WAIT VIDEO START]", "Expecting failure."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertTrue("should not start video recording", result == null || !result); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  |  | @ -285,36 +354,53 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         Boolean result = op.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         if (expectSuccess) { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[WAIT VIDEO SNAP START]", "Expecting success."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull("should start video recording or get CameraError", result); | 
			
		
	
		
			
				
					|  |  |  |  |             assertTrue("should start video recording successfully", result); | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             LOG.i("[WAIT VIDEO SNAP START]", "Expecting failure."); | 
			
		
	
		
			
				
					|  |  |  |  |             assertTrue("should not start video recording", result == null || !result); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private void waitForError() throws Throwable { | 
			
		
	
		
			
				
					|  |  |  |  |         Throwable throwable = error.await(DELAY); | 
			
		
	
		
			
				
					|  |  |  |  |         if (throwable != null) { | 
			
		
	
		
			
				
					|  |  |  |  |             throw throwable; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     //region test open/close
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testOpenClose() { | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(controller.getState(), CameraState.OFF); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(CameraState.OFF, controller.getState()); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         assertTrue(controller.getState().isAtLeast(CameraState.ENGINE)); | 
			
		
	
		
			
				
					|  |  |  |  |         closeSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(controller.getState(), CameraState.OFF); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(CameraState.OFF, controller.getState()); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testOpenTwice() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(false); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCloseTwice() { | 
			
		
	
		
			
				
					|  |  |  |  |         closeSync(false); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     // This works great on the device but crashes often on the emulator.
 | 
			
		
	
		
			
				
					|  |  |  |  |     // There must be something wrong with the emulated camera...
 | 
			
		
	
		
			
				
					|  |  |  |  |     // Like stopPreview() and release() are not really sync calls?
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -333,6 +419,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testStartInitializesOptions() { | 
			
		
	
		
			
				
					|  |  |  |  |         assertNull(camera.getCameraOptions()); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -345,6 +433,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     // Test things that should reset the camera.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetFacing() throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions o = openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         int size = o.getSupportedFacing().size(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -362,6 +452,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetMode() throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setMode(Mode.PICTURE); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -384,6 +476,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     // When camera is open, parameters will be set only if supported.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetZoom() { | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions options = openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         float oldValue = camera.getZoom(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -400,6 +494,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetExposureCorrection() { | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions options = openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         float oldValue = camera.getExposureCorrection(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -416,6 +512,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetFlash() { | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions options = openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         Flash[] values = Flash.values(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -435,6 +533,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetWhiteBalance() { | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions options = openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         WhiteBalance[] values = WhiteBalance.values(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -453,6 +553,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetHdr() { | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions options = openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         Hdr[] values = Hdr.values(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -471,6 +573,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetAudio() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         Audio[] values = Audio.values(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -481,6 +585,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetLocation() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setLocation(10d, 2d); | 
			
		
	
	
		
			
				
					|  |  |  | @ -493,15 +599,22 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetPreviewFrameRate() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions options = openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setPreviewFrameRate(30); | 
			
		
	
		
			
				
					|  |  |  |  |         Op<Void> op = new Op<>(controller.mPreviewFrameRateTask); | 
			
		
	
		
			
				
					|  |  |  |  |         op.await(300); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(camera.getPreviewFrameRate(), 30, 0); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(camera.getPreviewFrameRate(), | 
			
		
	
		
			
				
					|  |  |  |  |                 Math.min(options.getPreviewFrameRateMaxValue(), | 
			
		
	
		
			
				
					|  |  |  |  |                         Math.max(options.getPreviewFrameRateMinValue(), 30)), | 
			
		
	
		
			
				
					|  |  |  |  |                 0); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testSetPlaySounds() { | 
			
		
	
		
			
				
					|  |  |  |  |         boolean oldValue = camera.getPlaySounds(); | 
			
		
	
		
			
				
					|  |  |  |  |         boolean newValue = !oldValue; | 
			
		
	
	
		
			
				
					|  |  |  | @ -530,17 +643,18 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     //region test takeVideo
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test(expected = RuntimeException.class) | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testStartVideo_whileInPictureMode() throws Throwable { | 
			
		
	
		
			
				
					|  |  |  |  |         // Fails on Travis. Some emulators can't deal with MediaRecorder
 | 
			
		
	
		
			
				
					|  |  |  |  |         // Error while starting MediaRecorder. java.lang.RuntimeException: start failed.
 | 
			
		
	
		
			
				
					|  |  |  |  |         // as documented. This works locally though.
 | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setMode(Mode.PICTURE); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         takeVideoSync(false); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForUiException(); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForError(); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 25, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testStartEndVideo() { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setMode(Mode.VIDEO); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -549,6 +663,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testStartEndVideoSnapshot() { | 
			
		
	
		
			
				
					|  |  |  |  |         // TODO should check api level for snapshot?
 | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -557,6 +673,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 25, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testStartEndVideo_withManualStop() { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setMode(Mode.VIDEO); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -576,6 +694,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testStartEndVideoSnapshot_withManualStop() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         takeVideoSnapshotSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -594,6 +714,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testEndVideo_withoutStarting() { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setMode(Mode.VIDEO); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -602,32 +724,54 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 25, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testEndVideo_withMaxSize() { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setMode(Mode.VIDEO); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setVideoMaxSize(3000*1000); // Less is risky
 | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setVideoSize(SizeSelectors.maxArea(480 * 360)); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         // Assuming video frame rate is 20...
 | 
			
		
	
		
			
				
					|  |  |  |  |         //noinspection ConstantConditions
 | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setVideoBitRate((int) estimateVideoBitRate(camera.getVideoSize(), 20)); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setVideoMaxSize(estimateVideoBytes(camera.getVideoBitRate(), 5000)); | 
			
		
	
		
			
				
					|  |  |  |  |         takeVideoSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForVideoResult(true); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testEndVideoSnapshot_withMaxSize() { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setVideoMaxSize(3000*1000); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setSnapshotMaxWidth(480); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setSnapshotMaxHeight(480); | 
			
		
	
		
			
				
					|  |  |  |  |         // We don't want a very low FPS or the video frames are too sparse and recording
 | 
			
		
	
		
			
				
					|  |  |  |  |         // can fail (e.g. audio reaching completion while video still struggling to start)
 | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setPreviewFrameRate(30F); | 
			
		
	
		
			
				
					|  |  |  |  |         //noinspection ConstantConditions
 | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setVideoBitRate((int) estimateVideoBitRate(camera.getSnapshotSize(), | 
			
		
	
		
			
				
					|  |  |  |  |                 (int) camera.getPreviewFrameRate())); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setVideoMaxSize(estimateVideoBytes(camera.getVideoBitRate(), 5000)); | 
			
		
	
		
			
				
					|  |  |  |  |         takeVideoSnapshotSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForVideoResult(true); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 25, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testEndVideo_withMaxDuration() { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setMode(Mode.VIDEO); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setVideoMaxDuration(4000); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         takeVideoSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForVideoResult(true); | 
			
		
	
		
			
				
					|  |  |  |  |         if (canSetVideoMaxDuration()) { | 
			
		
	
		
			
				
					|  |  |  |  |             camera.setMode(Mode.VIDEO); | 
			
		
	
		
			
				
					|  |  |  |  |             camera.setVideoMaxDuration(4000); | 
			
		
	
		
			
				
					|  |  |  |  |             openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |             takeVideoSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |             waitForVideoResult(true); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testEndVideoSnapshot_withMaxDuration() { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setVideoMaxDuration(4000); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -640,6 +784,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     //region startAutoFocus
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testStartAutoFocus() { | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions o = openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -657,6 +803,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testStopAutoFocus() { | 
			
		
	
		
			
				
					|  |  |  |  |         CameraOptions o = openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -681,12 +829,16 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     //region capture
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCapturePicture_beforeStarted() { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.takePicture(); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForPictureResult(false); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCapturePicture_concurrentCalls() throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         // Second take should fail.
 | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -702,34 +854,57 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCapturePicture_size() { | 
			
		
	
		
			
				
					|  |  |  |  |         // Decoding can fail for large bitmaps. set a small size.
 | 
			
		
	
		
			
				
					|  |  |  |  |         // camera.setPictureSize(SizeSelectors.smallest());
 | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         Size size = camera.getPictureSize(); | 
			
		
	
		
			
				
					|  |  |  |  |         assertNotNull(size); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.takePicture(); | 
			
		
	
		
			
				
					|  |  |  |  |         PictureResult result = waitForPictureResult(true); | 
			
		
	
		
			
				
					|  |  |  |  |         assertNotNull(result); | 
			
		
	
		
			
				
					|  |  |  |  |         Bitmap bitmap = CameraUtils.decodeBitmap(result.getData(), Integer.MAX_VALUE, Integer.MAX_VALUE); | 
			
		
	
		
			
				
					|  |  |  |  |         assertNotNull(bitmap); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(result.getSize(), size); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(bitmap.getWidth(), size.getWidth()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(bitmap.getHeight(), size.getHeight()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertNotNull(result.getData()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertNull(result.getLocation()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertFalse(result.isSnapshot()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(result.getSize(), size); | 
			
		
	
		
			
				
					|  |  |  |  |         Bitmap bitmap = CameraUtils.decodeBitmap(result.getData(), | 
			
		
	
		
			
				
					|  |  |  |  |                 Integer.MAX_VALUE, Integer.MAX_VALUE); | 
			
		
	
		
			
				
					|  |  |  |  |         if (bitmap != null) { | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull(bitmap); | 
			
		
	
		
			
				
					|  |  |  |  |             String message = LOG.i("[PICTURE SIZE]", "Desired:", size, "Bitmap:", | 
			
		
	
		
			
				
					|  |  |  |  |                     new Size(bitmap.getWidth(), bitmap.getHeight())); | 
			
		
	
		
			
				
					|  |  |  |  |             if (!Emulator.isEmulator()) { | 
			
		
	
		
			
				
					|  |  |  |  |                 assertEquals(message, bitmap.getWidth(), size.getWidth()); | 
			
		
	
		
			
				
					|  |  |  |  |                 assertEquals(message, bitmap.getHeight(), size.getHeight()); | 
			
		
	
		
			
				
					|  |  |  |  |             } else { | 
			
		
	
		
			
				
					|  |  |  |  |                 // Emulator implementation sometimes does not rotate the image correctly.
 | 
			
		
	
		
			
				
					|  |  |  |  |                 assertTrue(message, bitmap.getWidth() == size.getWidth() | 
			
		
	
		
			
				
					|  |  |  |  |                         || bitmap.getWidth() == size.getHeight()); | 
			
		
	
		
			
				
					|  |  |  |  |                 assertTrue(message, bitmap.getHeight() == size.getWidth() | 
			
		
	
		
			
				
					|  |  |  |  |                         || bitmap.getHeight() == size.getHeight()); | 
			
		
	
		
			
				
					|  |  |  |  |                 assertEquals(message, size.getWidth() * size.getHeight(), | 
			
		
	
		
			
				
					|  |  |  |  |                         bitmap.getWidth() * bitmap.getHeight()); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test(expected = RuntimeException.class) | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCapturePicture_whileInVideoMode() throws Throwable { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setMode(Mode.VIDEO); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.takePicture(); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForUiException(); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForError(); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.takePicture(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCapturePicture_withMetering() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setPictureMetering(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -738,6 +913,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCapturePicture_withoutMetering() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setPictureMetering(false); | 
			
		
	
	
		
			
				
					|  |  |  | @ -746,12 +923,16 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCaptureSnapshot_beforeStarted() { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.takePictureSnapshot(); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForPictureResult(false); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCaptureSnapshot_concurrentCalls() throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         // Second take should fail.
 | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -767,6 +948,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCaptureSnapshot_size() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         Size size = camera.getSnapshotSize(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -775,17 +958,24 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         PictureResult result = waitForPictureResult(true); | 
			
		
	
		
			
				
					|  |  |  |  |         assertNotNull(result); | 
			
		
	
		
			
				
					|  |  |  |  |         Bitmap bitmap = CameraUtils.decodeBitmap(result.getData(), Integer.MAX_VALUE, Integer.MAX_VALUE); | 
			
		
	
		
			
				
					|  |  |  |  |         assertNotNull(bitmap); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(result.getSize(), size); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(bitmap.getWidth(), size.getWidth()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(bitmap.getHeight(), size.getHeight()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertNotNull(result.getData()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertNull(result.getLocation()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertTrue(result.isSnapshot()); | 
			
		
	
		
			
				
					|  |  |  |  |         assertEquals(result.getSize(), size); | 
			
		
	
		
			
				
					|  |  |  |  |         Bitmap bitmap = CameraUtils.decodeBitmap(result.getData(), | 
			
		
	
		
			
				
					|  |  |  |  |                 Integer.MAX_VALUE, Integer.MAX_VALUE); | 
			
		
	
		
			
				
					|  |  |  |  |         if (bitmap != null) { | 
			
		
	
		
			
				
					|  |  |  |  |             String message = LOG.i("[PICTURE SIZE]", "Desired:", size, "Bitmap:", | 
			
		
	
		
			
				
					|  |  |  |  |                     new Size(bitmap.getWidth(), bitmap.getHeight())); | 
			
		
	
		
			
				
					|  |  |  |  |             assertNotNull(bitmap); | 
			
		
	
		
			
				
					|  |  |  |  |             assertEquals(message, bitmap.getWidth(), size.getWidth()); | 
			
		
	
		
			
				
					|  |  |  |  |             assertEquals(message, bitmap.getHeight(), size.getHeight()); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCaptureSnapshot_withMetering() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setPictureSnapshotMetering(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -794,6 +984,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testCaptureSnapshot_withoutMetering() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.setPictureSnapshotMetering(false); | 
			
		
	
	
		
			
				
					|  |  |  | @ -807,6 +999,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @SuppressWarnings("ConstantConditions") | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testPictureFormat_DNG() { | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         if (camera.getCameraOptions().supports(PictureFormat.DNG)) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -830,24 +1024,28 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     //region Frame Processing
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private void assert30Frames(FrameProcessor mock) throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         // Expect 30 frames
 | 
			
		
	
		
			
				
					|  |  |  |  |         CountDownLatch latch = new CountDownLatch(30); | 
			
		
	
		
			
				
					|  |  |  |  |     private void assert15Frames(@NonNull FrameProcessor mock) throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         // Expect 15 frames. Time is very high because currently Camera2 keeps a very low FPS.
 | 
			
		
	
		
			
				
					|  |  |  |  |         CountDownLatch latch = new CountDownLatch(15); | 
			
		
	
		
			
				
					|  |  |  |  |         doCountDown(latch).when(mock).process(any(Frame.class)); | 
			
		
	
		
			
				
					|  |  |  |  |         boolean did = latch.await(15, TimeUnit.SECONDS); | 
			
		
	
		
			
				
					|  |  |  |  |         boolean did = latch.await(30, TimeUnit.SECONDS); | 
			
		
	
		
			
				
					|  |  |  |  |         assertTrue("Latch count should be 0: " + latch.getCount(), did); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testFrameProcessing_simple() throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         FrameProcessor processor = mock(FrameProcessor.class); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.addFrameProcessor(processor); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         assert30Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |         assert15Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testFrameProcessing_afterSnapshot() throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         FrameProcessor processor = mock(FrameProcessor.class); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.addFrameProcessor(processor); | 
			
		
	
	
		
			
				
					|  |  |  | @ -858,10 +1056,12 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.takePictureSnapshot(); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForPictureResult(true); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         assert30Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |         assert15Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testFrameProcessing_afterRestart() throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         FrameProcessor processor = mock(FrameProcessor.class); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.addFrameProcessor(processor); | 
			
		
	
	
		
			
				
					|  |  |  | @ -869,11 +1069,13 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |         closeSync(true); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         assert30Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |         assert15Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 25, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testFrameProcessing_afterVideo() throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         FrameProcessor processor = mock(FrameProcessor.class); | 
			
		
	
		
			
				
					|  |  |  |  |         camera.addFrameProcessor(processor); | 
			
		
	
	
		
			
				
					|  |  |  | @ -882,10 +1084,12 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |         takeVideoSync(true,4000); | 
			
		
	
		
			
				
					|  |  |  |  |         waitForVideoResult(true); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         assert30Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |         assert15Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testFrameProcessing_freezeRelease() throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  |         // Ensure that freeze/release cycles do not cause OOMs.
 | 
			
		
	
		
			
				
					|  |  |  |  |         // There was a bug doing this and it might resurface for any improper
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -895,7 +1099,7 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |         camera.addFrameProcessor(processor); | 
			
		
	
		
			
				
					|  |  |  |  |         openSync(true); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         assert30Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |         assert15Frames(processor); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public class FreezeReleaseFrameProcessor implements FrameProcessor { | 
			
		
	
	
		
			
				
					|  |  |  | @ -910,6 +1114,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     //region Overlays
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testOverlay_forPictureSnapshot() { | 
			
		
	
		
			
				
					|  |  |  |  |         Overlay overlay = mock(Overlay.class); | 
			
		
	
		
			
				
					|  |  |  |  |         when(overlay.drawsOn(any(Overlay.Target.class))).thenReturn(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -922,6 +1128,8 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Test | 
			
		
	
		
			
				
					|  |  |  |  |     @Retry(emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     @SdkExclude(maxSdkVersion = 22, emulatorOnly = true) | 
			
		
	
		
			
				
					|  |  |  |  |     public void testOverlay_forVideoSnapshot() { | 
			
		
	
		
			
				
					|  |  |  |  |         Overlay overlay = mock(Overlay.class); | 
			
		
	
		
			
				
					|  |  |  |  |         when(overlay.drawsOn(any(Overlay.Target.class))).thenReturn(true); | 
			
		
	
	
		
			
				
					|  |  |  | @ -934,4 +1142,16 @@ public abstract class CameraIntegrationTest extends BaseTest { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     //endregion
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @SuppressWarnings("SameParameterValue") | 
			
		
	
		
			
				
					|  |  |  |  |     private static long estimateVideoBitRate(@NonNull Size size, int frameRate) { | 
			
		
	
		
			
				
					|  |  |  |  |         // Nasty estimate for a LQ video
 | 
			
		
	
		
			
				
					|  |  |  |  |         return Math.round(0.05D * size.getWidth() * size.getHeight() * frameRate); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @SuppressWarnings("SameParameterValue") | 
			
		
	
		
			
				
					|  |  |  |  |     private static long estimateVideoBytes(long videoBitRate, long millis) { | 
			
		
	
		
			
				
					|  |  |  |  |         // 1.3F accounts for audio.
 | 
			
		
	
		
			
				
					|  |  |  |  |         return Math.round((videoBitRate * 1.3F) * (millis / 1000D) / 8D); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |