pull/696/head
Mattia Iavarone 6 years ago
parent 1ed22b02ac
commit 893af4bc85
  1. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/Camera1IntegrationTest.java
  2. 33
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/Camera2IntegrationTest.java
  3. 15
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/CameraIntegrationTest.java
  4. 9
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java

@ -19,7 +19,7 @@ import androidx.test.filters.RequiresDevice;
@RunWith(AndroidJUnit4.class)
@LargeTest
// @RequiresDevice
public class Camera1IntegrationTest extends CameraIntegrationTest {
public class Camera1IntegrationTest extends CameraIntegrationTest<Camera1Engine> {
@NonNull
@Override

@ -1,7 +1,9 @@
package com.otaliastudios.cameraview.engine;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.os.Handler;
import com.otaliastudios.cameraview.controls.Engine;
import com.otaliastudios.cameraview.engine.action.ActionHolder;
@ -25,7 +27,7 @@ import java.util.concurrent.CountDownLatch;
@RunWith(AndroidJUnit4.class)
@LargeTest
// @RequiresDevice
public class Camera2IntegrationTest extends CameraIntegrationTest {
public class Camera2IntegrationTest extends CameraIntegrationTest<Camera2Engine> {
@NonNull
@Override
@ -39,7 +41,6 @@ public class Camera2IntegrationTest extends CameraIntegrationTest {
// Extra wait for the first frame to be dispatched.
// This is because various classes require getLastResult to be non-null
// and that's typically the case in a real app.
Camera2Engine engine = (Camera2Engine) controller;
final CountDownLatch latch = new CountDownLatch(1);
new BaseAction() {
@Override
@ -50,7 +51,7 @@ public class Camera2IntegrationTest extends CameraIntegrationTest {
latch.countDown();
setState(STATE_COMPLETED);
}
}.start(engine);
}.start(controller);
try { latch.await(); } catch (InterruptedException ignore) {}
}
@ -58,4 +59,30 @@ public class Camera2IntegrationTest extends CameraIntegrationTest {
protected long getMeteringTimeoutMillis() {
return Camera2Engine.METER_TIMEOUT;
}
@Override
protected void takeVideoSync(boolean expectSuccess, final int duration) {
if (duration > 0 && (controller.readCharacteristic(
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL, -1)
== CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)) {
// setMaxDuration can crash on legacy devices (most emulator are), and I don't see
// any way to fix this in code. They shouldn't use Camera2 at all.
// For tests, use a handler to trigger the stop.
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);
}
});
super.takeVideoSync(expectSuccess, 0);
} else {
super.takeVideoSync(expectSuccess, duration);
}
}
}

@ -64,7 +64,7 @@ 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;
@ -72,8 +72,8 @@ public abstract class CameraIntegrationTest extends BaseTest {
@Rule
public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class);
private CameraView camera;
protected CameraEngine controller;
protected CameraView camera;
protected E controller;
private CameraListener listener;
private Op<Throwable> uiExceptionOp;
@ -98,7 +98,8 @@ public abstract class CameraIntegrationTest extends BaseTest {
@NonNull
@Override
protected CameraEngine instantiateCameraEngine(@NonNull Engine engine, @NonNull CameraEngine.Callback callback) {
controller = super.instantiateCameraEngine(getEngine(), callback);
//noinspection unchecked
controller = (E) super.instantiateCameraEngine(getEngine(), callback);
return controller;
}
};
@ -246,11 +247,11 @@ public abstract class CameraIntegrationTest extends BaseTest {
return result;
}
private void takeVideoSync(boolean expectSuccess) {
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>() {
@ -261,6 +262,8 @@ public abstract class CameraIntegrationTest extends BaseTest {
}));
File file = new File(getContext().getFilesDir(), "video.mp4");
if (duration > 0) {
// On Camera2, on Legacy sensors, this call can crash (see FullVideoRecorder).
// For this reasons, tests that call this should not be run on such devices.
camera.takeVideo(file, duration);
} else {
camera.takeVideo(file);

@ -125,16 +125,17 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
//region Utilities
@VisibleForTesting
@NonNull
private <T> T readCharacteristic(@NonNull CameraCharacteristics.Key<T> key,
@NonNull T fallback) {
<T> T readCharacteristic(@NonNull CameraCharacteristics.Key<T> key,
@NonNull T fallback) {
return readCharacteristic(mCameraCharacteristics, key, fallback);
}
@NonNull
private <T> T readCharacteristic(@NonNull CameraCharacteristics characteristics,
@NonNull CameraCharacteristics.Key<T> key,
@NonNull T fallback) {
@NonNull CameraCharacteristics.Key<T> key,
@NonNull T fallback) {
T value = characteristics.get(key);
return value == null ? fallback : value;
}

Loading…
Cancel
Save