v2
Mattia Iavarone 6 years ago
parent a8d88937fa
commit d3469f7b7e
  1. 3
      cameraview/build.gradle
  2. 42
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseTest.java
  3. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraLoggerTest.java
  4. 4
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraOptions1Test.java
  5. 38
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraPreviewTest.java
  6. 11
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraUtilsTest.java
  7. 7
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewCallbacksTest.java
  8. 8
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  9. 3
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CropHelperTest.java
  10. 3
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/GestureLayoutTest.java
  11. 3
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/GlCameraPreviewTest.java
  12. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/GridLinesLayoutTest.java
  13. 6
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java
  14. 3
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/Mapper1Test.java
  15. 26
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MapperTest.java
  16. 17
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraPreview.java
  17. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/OrientationHelperTest.java
  18. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/PictureRecorderTest.java
  19. 5
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/PictureResultTest.java
  20. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/PinchGestureLayoutTest.java
  21. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/ScrollGestureLayoutTest.java
  22. 4
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/SurfaceCameraPreviewTest.java
  23. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/TapGestureLayoutTest.java
  24. 3
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/TextureCameraPreviewTest.java
  25. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/VideoRecorderTest.java
  26. 3
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/VideoResultTest.java
  27. 6
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/WorkerHandlerTest.java
  28. 51
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/YuvHelperTest.java
  29. 6
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java
  30. 6
      cameraview/src/main/utils/com/otaliastudios/cameraview/CameraLogger.java
  31. 13
      cameraview/src/main/views/com/otaliastudios/cameraview/CameraPreview.java
  32. 16
      cameraview/src/main/views/com/otaliastudios/cameraview/GlCameraPreview.java
  33. 8
      cameraview/src/main/views/com/otaliastudios/cameraview/SurfaceCameraPreview.java
  34. 9
      cameraview/src/main/views/com/otaliastudios/cameraview/TextureCameraPreview.java
  35. 7
      cameraview/src/test/java/com/otaliastudios/cameraview/AspectRatioTest.java
  36. 11
      cameraview/src/test/java/com/otaliastudios/cameraview/SizeTest.java

@ -41,10 +41,11 @@ android {
dependencies { dependencies {
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:1.10.19' testImplementation 'org.mockito:mockito-core:2.23.0'
androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test:rules:1.1.1' androidTestImplementation 'androidx.test:rules:1.1.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'com.google.dexmaker:dexmaker:1.2' androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2' androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

@ -10,14 +10,16 @@ import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.PowerManager; import android.os.PowerManager;
import androidx.test.InstrumentationRegistry;
import androidx.test.annotation.UiThreadTest; import androidx.test.annotation.UiThreadTest;
import androidx.test.espresso.core.internal.deps.guava.collect.ObjectArrays; import androidx.test.espresso.core.internal.deps.guava.collect.ObjectArrays;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule; import androidx.test.rule.ActivityTestRule;
import android.view.View; import android.view.View;
import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.mockito.stubbing.Stubber; import org.mockito.stubbing.Stubber;
@ -67,6 +69,19 @@ public class BaseTest {
keyguardLock.reenableKeyguard(); keyguardLock.reenableKeyguard();
} }
/**
* This will make mockito report the error when it should.
* Mockito reports failure on the next mockito invocation, which is terrible
* since it might be on the next test or even never happen.
*
* Calling this
*/
@After
public void syncMockito() {
Object object = Mockito.mock(Object.class);
object.toString();
}
public static void ui(Runnable runnable) { public static void ui(Runnable runnable) {
InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable); InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
} }
@ -112,33 +127,10 @@ public class BaseTest {
InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(command); InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(command);
} }
public static byte[] mockJpeg(int width, int height) {
Bitmap source = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
ByteArrayOutputStream os = new ByteArrayOutputStream();
source.compress(Bitmap.CompressFormat.JPEG, 100, os);
return os.toByteArray();
}
public static YuvImage mockYuv(int width, int height) {
YuvImage y = mock(YuvImage.class);
when(y.getWidth()).thenReturn(width);
when(y.getHeight()).thenReturn(height);
when(y.compressToJpeg(any(Rect.class), anyInt(), any(OutputStream.class))).thenAnswer(new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
Rect rect = (Rect) invocation.getArguments()[0];
OutputStream stream = (OutputStream) invocation.getArguments()[2];
stream.write(mockJpeg(rect.width(), rect.height()));
return true;
}
});
return y;
}
public static Stubber doCountDown(final CountDownLatch latch) { public static Stubber doCountDown(final CountDownLatch latch) {
return doAnswer(new Answer<Object>() { return doAnswer(new Answer<Object>() {
@Override @Override
public Object answer(InvocationOnMock invocation) throws Throwable { public Object answer(InvocationOnMock invocation) {
latch.countDown(); latch.countDown();
return null; return null;
} }

@ -1,8 +1,8 @@
package com.otaliastudios.cameraview; package com.otaliastudios.cameraview;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;

@ -2,8 +2,9 @@ package com.otaliastudios.cameraview;
import android.hardware.Camera; import android.hardware.Camera;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -283,6 +284,7 @@ public class CameraOptions1Test extends BaseTest {
Camera.Parameters params = mock(Camera.Parameters.class); Camera.Parameters params = mock(Camera.Parameters.class);
when(params.isVideoSnapshotSupported()).thenReturn(true); when(params.isVideoSnapshotSupported()).thenReturn(true);
when(params.isZoomSupported()).thenReturn(true); when(params.isZoomSupported()).thenReturn(true);
//noinspection ArraysAsListWithZeroOrOneArgument
when(params.getSupportedFocusModes()).thenReturn(Arrays.asList(Camera.Parameters.FOCUS_MODE_AUTO)); when(params.getSupportedFocusModes()).thenReturn(Arrays.asList(Camera.Parameters.FOCUS_MODE_AUTO));
CameraOptions o = new CameraOptions(params, false); CameraOptions o = new CameraOptions(params, false);
assertTrue(o.isZoomSupported()); assertTrue(o.isZoomSupported());

@ -24,29 +24,43 @@ public abstract class CameraPreviewTest extends BaseTest {
@Rule @Rule
public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class); public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class);
@SuppressWarnings("WeakerAccess")
protected CameraPreview preview; protected CameraPreview preview;
@SuppressWarnings("WeakerAccess")
protected Size surfaceSize; protected Size surfaceSize;
private CameraPreview.SurfaceCallback callback; private CameraPreview.SurfaceCallback callback;
private Task<Boolean> availability;
private Task<Boolean> available;
private Task<Boolean> destroyed;
@Before @Before
public void setUp() { public void setUp() {
availability = new Task<>(true); available = new Task<>(true);
destroyed = new Task<>(true);
ui(new Runnable() { ui(new Runnable() {
@Override @Override
public void run() { public void run() {
TestActivity a = rule.getActivity(); TestActivity a = rule.getActivity();
surfaceSize = a.getContentSize(); surfaceSize = a.getContentSize();
callback = mock(CameraPreview.SurfaceCallback.class); callback = mock(CameraPreview.SurfaceCallback.class);
doAnswer(new Answer() { doAnswer(new Answer() {
@Override @Override
public Object answer(InvocationOnMock invocation) throws Throwable { public Object answer(InvocationOnMock invocation) {
if (availability != null) availability.end(true); if (available != null) available.end(true);
return null; return null;
} }
}).when(callback).onSurfaceAvailable(); }).when(callback).onSurfaceAvailable();
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) {
if (destroyed != null) destroyed.end(true);
return null;
}
}).when(callback).onSurfaceDestroyed();
preview = createPreview(a, a.getContentView(), callback); preview = createPreview(a, a.getContentView(), callback);
} }
}); });
@ -54,7 +68,7 @@ public abstract class CameraPreviewTest extends BaseTest {
// Wait for surface to be available. // Wait for surface to be available.
protected void ensureAvailable() { protected void ensureAvailable() {
assertNotNull(availability.await(2000)); assertNotNull(available.await(2000));
} }
// Trigger a destroy. // Trigger a destroy.
@ -62,10 +76,10 @@ public abstract class CameraPreviewTest extends BaseTest {
ui(new Runnable() { ui(new Runnable() {
@Override @Override
public void run() { public void run() {
rule.getActivity().getContentView().removeView(preview.getView()); rule.getActivity().getContentView().removeView(preview.getRootView());
} }
}); });
idle(); assertNotNull(destroyed.await(2000));
} }
@After @After
@ -73,7 +87,8 @@ public abstract class CameraPreviewTest extends BaseTest {
preview = null; preview = null;
callback = null; callback = null;
surfaceSize = null; surfaceSize = null;
availability = null; available = null;
destroyed = null;
} }
@Test @Test
@ -81,6 +96,7 @@ public abstract class CameraPreviewTest extends BaseTest {
ensureAvailable(); ensureAvailable();
assertTrue(preview.hasSurface()); assertTrue(preview.hasSurface());
assertNotNull(preview.getView()); assertNotNull(preview.getView());
assertNotNull(preview.getRootView());
assertNotNull(preview.getOutputClass()); assertNotNull(preview.getOutputClass());
} }
@ -103,12 +119,14 @@ public abstract class CameraPreviewTest extends BaseTest {
public void testSurfaceDestroyed() { public void testSurfaceDestroyed() {
ensureAvailable(); ensureAvailable();
ensureDestroyed(); ensureDestroyed();
// This might be called twice in Texture because it overrides ensureDestroyed method
verify(callback, atLeastOnce()).onSurfaceDestroyed();
assertEquals(0, preview.getOutputSurfaceSize().getWidth()); assertEquals(0, preview.getOutputSurfaceSize().getWidth());
assertEquals(0, preview.getOutputSurfaceSize().getHeight()); assertEquals(0, preview.getOutputSurfaceSize().getHeight());
} }
@Test @Test
public void testCropCenter() throws Exception { public void testCropCenter() {
ensureAvailable(); ensureAvailable();
// This is given by the activity, it's the fixed size. // This is given by the activity, it's the fixed size.

@ -5,8 +5,9 @@ import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -102,13 +103,13 @@ public class CameraUtilsTest extends BaseTest {
task = encodeDecodeTask(source, Integer.MAX_VALUE, Integer.MAX_VALUE); task = encodeDecodeTask(source, Integer.MAX_VALUE, Integer.MAX_VALUE);
other = task.await(800); other = task.await(800);
assertNotNull(other); assertNotNull(other);
assertTrue(other.getWidth() == width); assertEquals(other.getWidth(), width);
assertTrue(other.getHeight() == height); assertEquals(other.getHeight(), height);
task = encodeDecodeTask(source, 6000, 6000); task = encodeDecodeTask(source, 6000, 6000);
other = task.await(800); other = task.await(800);
assertNotNull(other); assertNotNull(other);
assertTrue(other.getWidth() == width); assertEquals(other.getWidth(), width);
assertTrue(other.getHeight() == height); assertEquals(other.getHeight(), height);
} }
} }

@ -3,8 +3,10 @@ package com.otaliastudios.cameraview;
import android.content.Context; import android.content.Context;
import android.graphics.PointF; import android.graphics.PointF;
import androidx.annotation.NonNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest; import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import android.view.ViewGroup; import android.view.ViewGroup;
import org.junit.After; import org.junit.After;
@ -38,7 +40,6 @@ public class CameraViewCallbacksTest extends BaseTest {
private MockCameraPreview mockPreview; private MockCameraPreview mockPreview;
private Task<Boolean> task; private Task<Boolean> task;
@Before @Before
public void setUp() { public void setUp() {
ui(new Runnable() { ui(new Runnable() {
@ -61,7 +62,7 @@ public class CameraViewCallbacksTest extends BaseTest {
} }
@Override @Override
protected boolean checkPermissions(Mode mode, Audio audio) { protected boolean checkPermissions(@NonNull Mode mode, @NonNull Audio audio) {
return true; return true;
} }
}; };

@ -4,8 +4,8 @@ package com.otaliastudios.cameraview;
import android.content.Context; import android.content.Context;
import android.location.Location; import android.location.Location;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest; import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -39,18 +39,18 @@ public class CameraViewTest extends BaseTest {
cameraView = new CameraView(context) { cameraView = new CameraView(context) {
@Override @Override
protected CameraController instantiateCameraController(CameraCallbacks callbacks) { protected CameraController instantiateCameraController(CameraCallbacks callbacks) {
mockController = new MockCameraController(callbacks); mockController = spy(new MockCameraController(callbacks));
return mockController; return mockController;
} }
@Override @Override
protected CameraPreview instantiatePreview(Context context, ViewGroup container) { protected CameraPreview instantiatePreview(Context context, ViewGroup container) {
mockPreview = new MockCameraPreview(context, container); mockPreview = spy(new MockCameraPreview(context, container));
return mockPreview; return mockPreview;
} }
@Override @Override
protected boolean checkPermissions(Mode mode, Audio audio) { protected boolean checkPermissions(@NonNull Mode mode, @NonNull Audio audio) {
return hasPermissions; return hasPermissions;
} }
}; };

@ -2,8 +2,9 @@ package com.otaliastudios.cameraview;
import android.graphics.Rect; import android.graphics.Rect;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

@ -28,7 +28,9 @@ public abstract class GestureLayoutTest<T extends GestureLayout> extends BaseTes
@Rule @Rule
public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class); public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class);
@SuppressWarnings("WeakerAccess")
protected T layout; protected T layout;
@SuppressWarnings("WeakerAccess")
protected Task<Gesture> touch; protected Task<Gesture> touch;
@Before @Before
@ -54,6 +56,7 @@ public abstract class GestureLayoutTest<T extends GestureLayout> extends BaseTes
}); });
} }
@SuppressWarnings("WeakerAccess")
protected final ViewInteraction onLayout() { protected final ViewInteraction onLayout() {
return onView(Matchers.<View>is(layout)) return onView(Matchers.<View>is(layout))
.inRoot(RootMatchers.withDecorView( .inRoot(RootMatchers.withDecorView(

@ -2,8 +2,9 @@ package com.otaliastudios.cameraview;
import android.content.Context; import android.content.Context;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import android.view.ViewGroup; import android.view.ViewGroup;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

@ -1,9 +1,9 @@
package com.otaliastudios.cameraview; package com.otaliastudios.cameraview;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest; import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule; import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;

@ -5,13 +5,15 @@ import android.graphics.Bitmap;
import android.graphics.PointF; import android.graphics.PointF;
import android.hardware.Camera; import android.hardware.Camera;
import android.os.Build; import android.os.Build;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest; import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule; import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -36,7 +38,7 @@ import static org.mockito.Mockito.mock;
*/ */
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@MediumTest @MediumTest
// @Ignore @Ignore
public class IntegrationTest extends BaseTest { public class IntegrationTest extends BaseTest {
@Rule @Rule

@ -2,8 +2,9 @@ package com.otaliastudios.cameraview;
import android.hardware.Camera; import android.hardware.Camera;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

@ -1,26 +0,0 @@
package com.otaliastudios.cameraview;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class MapperTest extends BaseTest {
private Mapper mapper = new Mapper() {
<T> T map(Flash flash) { return null; }
<T> T map(Facing facing) { return null; }
<T> T map(WhiteBalance whiteBalance) { return null; }
<T> T map(Hdr hdr) { return null; }
<T> Flash unmapFlash(T cameraConstant) { return null; }
<T> Facing unmapFacing(T cameraConstant) { return null; }
<T> WhiteBalance unmapWhiteBalance(T cameraConstant) { return null; }
<T> Hdr unmapHdr(T cameraConstant) { return null; }
};
}

@ -13,20 +13,14 @@ public class MockCameraPreview extends CameraPreview<View, Void> {
super(context, parent, null); super(context, parent, null);
} }
private boolean mCropping = false;
public void setIsCropping(boolean crop) {
mCropping = crop;
}
@Override @Override
boolean isCropping() { boolean supportsCropping() {
return mCropping; return true;
} }
@NonNull @NonNull
@Override @Override
protected View onCreateView(Context context, ViewGroup parent) { protected View onCreateView(@NonNull Context context, @NonNull ViewGroup parent) {
return new View(context); return new View(context);
} }
@ -42,4 +36,9 @@ public class MockCameraPreview extends CameraPreview<View, Void> {
return null; return null;
} }
@NonNull
@Override
View getRootView() {
return null;
}
} }

@ -1,8 +1,8 @@
package com.otaliastudios.cameraview; package com.otaliastudios.cameraview;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import android.view.OrientationEventListener; import android.view.OrientationEventListener;
import org.junit.After; import org.junit.After;

@ -1,8 +1,8 @@
package com.otaliastudios.cameraview; package com.otaliastudios.cameraview;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

@ -2,8 +2,9 @@ package com.otaliastudios.cameraview;
import android.location.Location; import android.location.Location;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -32,6 +33,7 @@ public class PictureResultTest extends BaseTest {
result.size = size; result.size = size;
result.data = jpeg; result.data = jpeg;
result.location = location; result.location = location;
//noinspection ConstantConditions
result.isSnapshot = isSnapshot; result.isSnapshot = isSnapshot;
assertEquals(result.getFormat(), format); assertEquals(result.getFormat(), format);
@ -39,6 +41,7 @@ public class PictureResultTest extends BaseTest {
assertEquals(result.getSize(), size); assertEquals(result.getSize(), size);
assertEquals(result.getData(), jpeg); assertEquals(result.getData(), jpeg);
assertEquals(result.getLocation(), location); assertEquals(result.getLocation(), location);
//noinspection ConstantConditions
assertEquals(result.isSnapshot(), isSnapshot); assertEquals(result.isSnapshot(), isSnapshot);
} }
} }

@ -3,8 +3,8 @@ package com.otaliastudios.cameraview;
import android.content.Context; import android.content.Context;
import androidx.test.espresso.ViewAction; import androidx.test.espresso.ViewAction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

@ -3,8 +3,8 @@ package com.otaliastudios.cameraview;
import android.content.Context; import android.content.Context;
import androidx.test.espresso.ViewAction; import androidx.test.espresso.ViewAction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

@ -2,10 +2,12 @@ package com.otaliastudios.cameraview;
import android.content.Context; import android.content.Context;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import android.view.ViewGroup; import android.view.ViewGroup;
import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)

@ -6,8 +6,8 @@ import androidx.test.espresso.action.GeneralClickAction;
import androidx.test.espresso.action.GeneralLocation; import androidx.test.espresso.action.GeneralLocation;
import androidx.test.espresso.action.Press; import androidx.test.espresso.action.Press;
import androidx.test.espresso.action.Tap; import androidx.test.espresso.action.Tap;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import android.view.InputDevice; import android.view.InputDevice;
import android.view.MotionEvent; import android.view.MotionEvent;

@ -2,8 +2,9 @@ package com.otaliastudios.cameraview;
import android.content.Context; import android.content.Context;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import android.view.ViewGroup; import android.view.ViewGroup;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

@ -1,8 +1,8 @@
package com.otaliastudios.cameraview; package com.otaliastudios.cameraview;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

@ -2,8 +2,9 @@ package com.otaliastudios.cameraview;
import android.location.Location; import android.location.Location;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

@ -1,8 +1,8 @@
package com.otaliastudios.cameraview; package com.otaliastudios.cameraview;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -18,8 +18,8 @@ public class WorkerHandlerTest extends BaseTest {
WorkerHandler w1 = WorkerHandler.get("handler1"); WorkerHandler w1 = WorkerHandler.get("handler1");
WorkerHandler w1a = WorkerHandler.get("handler1"); WorkerHandler w1a = WorkerHandler.get("handler1");
WorkerHandler w2 = WorkerHandler.get("handler2"); WorkerHandler w2 = WorkerHandler.get("handler2");
assertTrue(w1 == w1a); assertSame(w1, w1a);
assertFalse(w1 == w2); assertNotSame(w1, w2);
} }
@Test @Test

@ -1,51 +0,0 @@
package com.otaliastudios.cameraview;
import android.graphics.Rect;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class YuvHelperTest extends BaseTest {
@Test
public void testCrop() {
testCrop(new Size(1600, 1600), AspectRatio.of(16, 16));
testCrop(new Size(1600, 1600), AspectRatio.of(16, 9));
testCrop(new Size(1600, 1600), AspectRatio.of(9, 16));
}
private void testCrop(final Size inSize, final AspectRatio outRatio) {
AspectRatio inRatio = AspectRatio.of(inSize.getWidth(), inSize.getHeight());
Rect out = YuvHelper.computeCrop(inSize, outRatio);
Size outSize = new Size(out.width(), out.height());
assertTrue(outRatio.matches(outSize));
if (outRatio.matches(inSize)) {
// They are equal.
assertEquals(outSize.getWidth(), inSize.getWidth());
assertEquals(outSize.getHeight(), inSize.getHeight());
} else if (outRatio.toFloat() > inRatio.toFloat()) {
// Width must match.
assertEquals(outSize.getWidth(), inSize.getWidth());
assertNotEquals(outSize.getHeight(), inSize.getHeight());
} else {
// Height must match.
assertEquals(outSize.getHeight(), inSize.getHeight());
assertNotEquals(outSize.getWidth(), inSize.getWidth());
}
}
}

@ -145,7 +145,8 @@ abstract class CameraController implements
} }
} }
final void destroy() { // Public & not final so we can verify with mockito in CameraViewTest
public void destroy() {
LOG.i("destroy:", "state:", ss()); LOG.i("destroy:", "state:", ss());
// Prevent CameraController leaks. Don't set to null, or exceptions // Prevent CameraController leaks. Don't set to null, or exceptions
// inside the standard stop() method might crash the main thread. // inside the standard stop() method might crash the main thread.
@ -188,7 +189,8 @@ abstract class CameraController implements
} }
// Stops the preview asynchronously. // Stops the preview asynchronously.
final void stop() { // Public & not final so we can verify with mockito in CameraViewTest
public void stop() {
LOG.i("Stop:", "posting runnable. State:", ss()); LOG.i("Stop:", "posting runnable. State:", ss());
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
@Override @Override

@ -149,11 +149,11 @@ public final class CameraLogger {
message.append(String.valueOf(object)); message.append(String.valueOf(object));
message.append(" "); message.append(" ");
} }
String string = message.toString().trim();
for (Logger logger : sLoggers) { for (Logger logger : sLoggers) {
logger.log(level, mTag, message.toString().trim(), throwable); logger.log(level, mTag, string, throwable);
} }
lastMessage = string;
lastMessage = message.toString();
lastTag = mTag; lastTag = mTag;
} }
} }

@ -47,6 +47,10 @@ abstract class CameraPreview<T extends View, Output> {
return mView; return mView;
} }
// Only used in tests
@NonNull
abstract View getRootView();
@NonNull @NonNull
abstract Class<Output> getOutputClass(); abstract Class<Output> getOutputClass();
@ -119,11 +123,14 @@ abstract class CameraPreview<T extends View, Output> {
mSurfaceCallback.onSurfaceDestroyed(); mSurfaceCallback.onSurfaceDestroyed();
} }
void onResume() {} // Public for mockito (CameraViewTest)
public void onResume() {}
void onPause() {} // Public for mockito (CameraViewTest)
public void onPause() {}
void onDestroy() {} // Public for mockito (CameraViewTest)
public void onDestroy() {}
final boolean hasSurface() { final boolean hasSurface() {
return mOutputSurfaceWidth > 0 && mOutputSurfaceHeight > 0; return mOutputSurfaceWidth > 0 && mOutputSurfaceHeight > 0;

@ -9,6 +9,7 @@ import androidx.annotation.Nullable;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import java.util.Collections; import java.util.Collections;
@ -62,6 +63,8 @@ class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture> imple
/* for tests */ float mScaleY = 1F; /* for tests */ float mScaleY = 1F;
private float[] mScaleXY = new float[] { mScaleX, mScaleY }; private float[] mScaleXY = new float[] { mScaleX, mScaleY };
private View mRootView;
GlCameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) { GlCameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) {
super(context, parent, callback); super(context, parent, callback);
} }
@ -88,23 +91,30 @@ class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture> imple
} }
}); });
parent.addView(root, 0); parent.addView(root, 0);
mRootView = root;
return glView; return glView;
} }
@NonNull
@Override
View getRootView() {
return mRootView;
}
@Override @Override
void onResume() { public void onResume() {
super.onResume(); super.onResume();
getView().onResume(); getView().onResume();
} }
@Override @Override
void onPause() { public void onPause() {
super.onPause(); super.onPause();
getView().onPause(); getView().onPause();
} }
@Override @Override
void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
// View is gone, so EGL context is gone: callbacks make no sense anymore. // View is gone, so EGL context is gone: callbacks make no sense anymore.
mRendererFrameCallbacks.clear(); mRendererFrameCallbacks.clear();

@ -18,6 +18,7 @@ class SurfaceCameraPreview extends CameraPreview<SurfaceView, SurfaceHolder> {
private final static CameraLogger LOG = CameraLogger.create(SurfaceCameraPreview.class.getSimpleName()); private final static CameraLogger LOG = CameraLogger.create(SurfaceCameraPreview.class.getSimpleName());
private boolean mDispatched; private boolean mDispatched;
private View mRootView;
SurfaceCameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) { SurfaceCameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) {
super(context, parent, callback); super(context, parent, callback);
@ -57,9 +58,16 @@ class SurfaceCameraPreview extends CameraPreview<SurfaceView, SurfaceHolder> {
mDispatched = false; mDispatched = false;
} }
}); });
mRootView = root;
return surfaceView; return surfaceView;
} }
@NonNull
@Override
View getRootView() {
return mRootView;
}
@NonNull @NonNull
@Override @Override
SurfaceHolder getOutput() { SurfaceHolder getOutput() {

@ -12,6 +12,8 @@ import android.view.ViewGroup;
class TextureCameraPreview extends CameraPreview<TextureView, SurfaceTexture> { class TextureCameraPreview extends CameraPreview<TextureView, SurfaceTexture> {
private View mRootView;
TextureCameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) { TextureCameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) {
super(context, parent, callback); super(context, parent, callback);
} }
@ -44,9 +46,16 @@ class TextureCameraPreview extends CameraPreview<TextureView, SurfaceTexture> {
public void onSurfaceTextureUpdated(SurfaceTexture surface) { public void onSurfaceTextureUpdated(SurfaceTexture surface) {
} }
}); });
mRootView = root;
return texture; return texture;
} }
@NonNull
@Override
View getRootView() {
return mRootView;
}
@NonNull @NonNull
@Override @Override
Class<SurfaceTexture> getOutputClass() { Class<SurfaceTexture> getOutputClass() {

@ -19,14 +19,14 @@ public class AspectRatioTest {
public void testEquals() { public void testEquals() {
AspectRatio ratio = AspectRatio.of(50, 10); AspectRatio ratio = AspectRatio.of(50, 10);
assertNotNull(ratio); assertNotNull(ratio);
assertTrue(ratio.equals(ratio)); assertEquals(ratio, ratio);
AspectRatio ratio1 = AspectRatio.of(5, 1); AspectRatio ratio1 = AspectRatio.of(5, 1);
assertTrue(ratio.equals(ratio1)); assertEquals(ratio, ratio1);
AspectRatio.sCache.clear(); AspectRatio.sCache.clear();
AspectRatio ratio2 = AspectRatio.of(500, 100); AspectRatio ratio2 = AspectRatio.of(500, 100);
assertTrue(ratio.equals(ratio2)); assertEquals(ratio, ratio2);
Size size = new Size(500, 100); Size size = new Size(500, 100);
assertTrue(ratio.matches(size)); assertTrue(ratio.matches(size));
@ -39,6 +39,7 @@ public class AspectRatioTest {
AspectRatio ratio3 = AspectRatio.of(2, 10); AspectRatio ratio3 = AspectRatio.of(2, 10);
assertTrue(ratio1.compareTo(ratio2) < 0); assertTrue(ratio1.compareTo(ratio2) < 0);
assertTrue(ratio1.compareTo(ratio3) > 0); assertTrue(ratio1.compareTo(ratio3) > 0);
//noinspection EqualsWithItself,SimplifiableJUnitAssertion
assertTrue(ratio1.compareTo(ratio1) == 0); assertTrue(ratio1.compareTo(ratio1) == 0);
assertNotEquals(ratio1.hashCode(), ratio2.hashCode()); assertNotEquals(ratio1.hashCode(), ratio2.hashCode());
} }

@ -27,14 +27,14 @@ public class SizeTest {
@Test @Test
public void testEquals() { public void testEquals() {
Size s1 = new Size(10, 20); Size s1 = new Size(10, 20);
assertTrue(s1.equals(s1)); assertEquals(s1, s1);
assertFalse(s1.equals(null)); assertNotEquals(s1, null);
assertFalse(s1.equals("")); assertNotEquals(s1, "");
Size s2 = new Size(10, 0); Size s2 = new Size(10, 0);
Size s3 = new Size(10, 20); Size s3 = new Size(10, 20);
assertTrue(s1.equals(s3)); assertEquals(s1, s3);
assertFalse(s1.equals(s2)); assertNotEquals(s1, s2);
} }
@Test @Test
@ -49,6 +49,7 @@ public class SizeTest {
Size s1 = new Size(10, 20); Size s1 = new Size(10, 20);
Size s2 = new Size(10, 0); Size s2 = new Size(10, 0);
Size s3 = new Size(10, 20); Size s3 = new Size(10, 20);
//noinspection SimplifiableJUnitAssertion
assertTrue(s1.compareTo(s3) == 0); assertTrue(s1.compareTo(s3) == 0);
assertTrue(s1.compareTo(s2) > 0); assertTrue(s1.compareTo(s2) > 0);
assertTrue(s2.compareTo(s1) < 0); assertTrue(s2.compareTo(s1) < 0);

Loading…
Cancel
Save