Gesture tests

pull/22/head
Mattia Iavarone 8 years ago
parent 1db8d74111
commit b9f36aa327
  1. 1
      cameraview/build.gradle
  2. 39
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseTest.java
  3. 15
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  4. 47
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/GestureLayoutTest.java
  5. 78
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/GridLinesLayoutTest.java
  6. 12
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/OrientationHelperTest.java
  7. 86
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/PinchGestureLayoutTest.java
  8. 95
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/PreviewTest.java
  9. 94
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/ScrollGestureLayoutTest.java
  10. 73
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/TapGestureLayoutTest.java
  11. 46
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/TestActivity.java
  12. 10
      cameraview/src/main/views/com/otaliastudios/cameraview/GridLinesLayout.java
  13. 2
      cameraview/src/main/views/com/otaliastudios/cameraview/PinchGestureLayout.java
  14. 4
      cameraview/src/main/views/com/otaliastudios/cameraview/TapGestureLayout.java

@ -46,6 +46,7 @@ dependencies {
androidTestCompile 'com.android.support.test:rules:1.0.1' androidTestCompile 'com.android.support.test:rules:1.0.1'
androidTestCompile 'com.google.dexmaker:dexmaker:1.2' androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2' androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1'
compile "com.android.support:exifinterface:$supportLibVersion" compile "com.android.support:exifinterface:$supportLibVersion"
compile "com.android.support:support-annotations:$supportLibVersion" compile "com.android.support:support-annotations:$supportLibVersion"

@ -0,0 +1,39 @@
package com.otaliastudios.cameraview;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.view.View;
import org.junit.Rule;
public class BaseTest {
public static void ui(Runnable runnable) {
InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
}
public static void uiAsync(Runnable runnable) {
new Handler(Looper.getMainLooper()).post(runnable);
}
public static Context context() {
return InstrumentationRegistry.getInstrumentation().getContext();
}
public static void uiRequestLayout(final View view) {
ui(new Runnable() {
@Override
public void run() {
view.requestLayout();
}
});
}
public static void waitUi() {
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
}

@ -27,20 +27,17 @@ import static android.view.ViewGroup.LayoutParams.*;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@MediumTest @MediumTest
public class CameraViewTest { public class CameraViewTest extends BaseTest {
private CameraView cameraView; private CameraView cameraView;
private MockCameraController mockController; private MockCameraController mockController;
private Preview mockPreview; private Preview mockPreview;
private boolean hasPermissions; private boolean hasPermissions;
private void postOnUiSync(Runnable runnable) {
InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
}
@Before @Before
public void setUp() { public void setUp() {
postOnUiSync(new Runnable() { ui(new Runnable() {
@Override @Override
public void run() { public void run() {
Context context = InstrumentationRegistry.getContext(); Context context = InstrumentationRegistry.getContext();
@ -180,7 +177,7 @@ public class CameraViewTest {
@Test @Test
public void testGestureAction_capture() { public void testGestureAction_capture() {
MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0); MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0);
postOnUiSync(new Runnable() { ui(new Runnable() {
@Override @Override
public void run() { public void run() {
cameraView.mTapGestureLayout = new TapGestureLayout(cameraView.getContext()) { cameraView.mTapGestureLayout = new TapGestureLayout(cameraView.getContext()) {
@ -198,7 +195,7 @@ public class CameraViewTest {
@Test @Test
public void testGestureAction_focus() { public void testGestureAction_focus() {
MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0); MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0);
postOnUiSync(new Runnable() { ui(new Runnable() {
@Override @Override
public void run() { public void run() {
cameraView.mTapGestureLayout = new TapGestureLayout(cameraView.getContext()) { cameraView.mTapGestureLayout = new TapGestureLayout(cameraView.getContext()) {
@ -222,7 +219,7 @@ public class CameraViewTest {
@Test @Test
public void testGestureAction_zoom() { public void testGestureAction_zoom() {
MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0); MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0);
postOnUiSync(new Runnable() { ui(new Runnable() {
@Override @Override
public void run() { public void run() {
cameraView.mPinchGestureLayout = new PinchGestureLayout(cameraView.getContext()) { cameraView.mPinchGestureLayout = new PinchGestureLayout(cameraView.getContext()) {
@ -246,7 +243,7 @@ public class CameraViewTest {
mockController.setMockCameraOptions(o); mockController.setMockCameraOptions(o);
MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0); MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0);
postOnUiSync(new Runnable() { ui(new Runnable() {
@Override @Override
public void run() { public void run() {
cameraView.mScrollGestureLayout = new ScrollGestureLayout(cameraView.getContext()) { cameraView.mScrollGestureLayout = new ScrollGestureLayout(cameraView.getContext()) {

@ -0,0 +1,47 @@
package com.otaliastudios.cameraview;
import android.annotation.TargetApi;
import android.content.Context;
import android.support.test.rule.ActivityTestRule;
import android.view.MotionEvent;
import android.view.View;
import org.junit.Before;
import org.junit.Rule;
@TargetApi(17)
public abstract class GestureLayoutTest<T extends GestureLayout> extends BaseTest {
protected abstract T create(Context context);
@Rule
public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class);
protected T layout;
protected Task<Gesture> touch;
@Before
public void setUp() {
ui(new Runnable() {
@Override
public void run() {
TestActivity a = rule.getActivity();
layout = create(a);
layout.enable(true);
a.inflate(layout);
touch = new Task<>();
layout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
boolean found = layout.onTouchEvent(motionEvent);
if (found) touch.end(layout.getGestureType());
return true;
}
});
layout.setId(View.generateViewId());
}
});
}
}

@ -0,0 +1,78 @@
package com.otaliastudios.cameraview;
import android.graphics.Canvas;
import android.graphics.drawable.ColorDrawable;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.Mockito.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class GridLinesLayoutTest extends BaseTest {
@Rule
public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class);
private GridLinesLayout layout;
@Before
public void setUp() {
ui(new Runnable() {
@Override
public void run() {
TestActivity a = rule.getActivity();
layout = new GridLinesLayout(a);
layout.setGridMode(Grid.OFF);
a.getContentView().addView(layout);
layout.vert = mock(ColorDrawable.class);
layout.horiz = mock(ColorDrawable.class);
}
});
}
@Test
public void testOff() {
layout.drawTask.listen();
layout.setGridMode(Grid.OFF);
layout.drawTask.await();
verify(layout.vert, never()).draw(any(Canvas.class));
verify(layout.horiz, never()).draw(any(Canvas.class));
}
@Test
public void test3x3() {
layout.drawTask.listen();
layout.setGridMode(Grid.DRAW_3X3);
layout.drawTask.await();
verify(layout.vert, times(2)).draw(any(Canvas.class));
verify(layout.horiz, times(2)).draw(any(Canvas.class));
}
@Test
public void testPhi() {
layout.drawTask.listen();
layout.setGridMode(Grid.DRAW_PHI);
layout.drawTask.await();
verify(layout.vert, times(2)).draw(any(Canvas.class));
verify(layout.horiz, times(2)).draw(any(Canvas.class));
}
@Test
public void test4x4() {
layout.drawTask.listen();
layout.setGridMode(Grid.DRAW_4X4);
layout.drawTask.await();
verify(layout.vert, times(3)).draw(any(Canvas.class));
verify(layout.horiz, times(3)).draw(any(Canvas.class));
}
}

@ -19,18 +19,18 @@ import static org.mockito.Mockito.*;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@SmallTest @SmallTest
public class OrientationHelperTest { public class OrientationHelperTest extends BaseTest {
private OrientationHelper helper; private OrientationHelper helper;
private OrientationHelper.Callbacks callbacks; private OrientationHelper.Callbacks callbacks;
@Before @Before
public void setUp() { public void setUp() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { ui(new Runnable() {
@Override @Override
public void run() { public void run() {
callbacks = mock(OrientationHelper.Callbacks.class); callbacks = mock(OrientationHelper.Callbacks.class);
helper = new OrientationHelper(InstrumentationRegistry.getContext(), callbacks); helper = new OrientationHelper(context(), callbacks);
} }
}); });
} }
@ -46,12 +46,12 @@ public class OrientationHelperTest {
assertNotNull(helper.mListener); assertNotNull(helper.mListener);
assertNull(helper.mDisplay); assertNull(helper.mDisplay);
helper.enable(InstrumentationRegistry.getContext()); helper.enable(context());
assertNotNull(helper.mListener); assertNotNull(helper.mListener);
assertNotNull(helper.mDisplay); assertNotNull(helper.mDisplay);
// Ensure nothing bad if called twice. // Ensure nothing bad if called twice.
helper.enable(InstrumentationRegistry.getContext()); helper.enable(context());
assertNotNull(helper.mListener); assertNotNull(helper.mListener);
assertNotNull(helper.mDisplay); assertNotNull(helper.mDisplay);
@ -64,7 +64,7 @@ public class OrientationHelperTest {
@Test @Test
public void testRotation() { public void testRotation() {
helper.enable(InstrumentationRegistry.getContext()); helper.enable(context());
reset(callbacks); // Reset counts. reset(callbacks); // Reset counts.
helper.mListener.onOrientationChanged(OrientationEventListener.ORIENTATION_UNKNOWN); helper.mListener.onOrientationChanged(OrientationEventListener.ORIENTATION_UNKNOWN);

@ -0,0 +1,86 @@
package com.otaliastudios.cameraview;
import android.content.Context;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.CoordinatesProvider;
import android.support.test.espresso.action.GeneralLocation;
import android.support.test.espresso.action.GeneralSwipeAction;
import android.support.test.espresso.action.MotionEvents;
import android.support.test.espresso.action.PrecisionDescriber;
import android.support.test.espresso.action.Press;
import android.support.test.espresso.action.Swipe;
import android.support.test.espresso.action.ViewActions;
import android.support.test.espresso.assertion.ViewAssertions;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.TimeUnit;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class PinchGestureLayoutTest extends GestureLayoutTest<PinchGestureLayout> {
@Override
protected PinchGestureLayout create(Context context) {
return new PinchGestureLayout(context);
}
@Test
public void testDefaults() {
assertEquals(layout.getGestureType(), Gesture.PINCH);
assertEquals(layout.getPoints().length, 2);
assertEquals(layout.getPoints()[0].x, 0, 0);
assertEquals(layout.getPoints()[0].y, 0, 0);
assertEquals(layout.getPoints()[1].x, 0, 0);
assertEquals(layout.getPoints()[1].y, 0, 0);
}
// TODO: test pinch open
// TODO: test pinch close
// TODO: test pinch disabled
// Possible approach: mimic pinch gesture and let espresso test.
// Too lazy to do this now, but it's possible.
// https://stackoverflow.com/questions/11523423/how-to-generate-zoom-pinch-gesture-for-testing-for-android
public abstract class PinchViewAction implements ViewAction {
}
private void testPinch(ViewAction action, boolean increasing) {
touch.listen();
touch.start();
onView(withId(layout.getId())).perform(action);
Gesture found = touch.await(10000, TimeUnit.MILLISECONDS);
assertNotNull(found);
// How will this move our parameter?
float curr = 0.5f, min = 0f, max = 1f;
float newValue = layout.scaleValue(curr, min, max);
if (increasing) {
assertTrue(newValue > curr);
assertTrue(newValue <= max);
} else {
assertTrue(newValue < curr);
assertTrue(newValue >= min);
}
}
}

@ -2,58 +2,61 @@ package com.otaliastudios.cameraview;
import android.content.Context; import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule; import android.support.test.rule.ActivityTestRule;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.concurrent.Semaphore;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
public abstract class PreviewTest { public abstract class PreviewTest extends BaseTest {
protected abstract Preview createPreview(Context context, ViewGroup parent); protected abstract Preview createPreview(Context context, ViewGroup parent);
private Preview preview;
private ViewGroup parent;
private Preview.SurfaceCallback callback;
private Size surfaceSize = new Size(1000, 1000);
@Rule @Rule
public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class); public ActivityTestRule<TestActivity> rule = new ActivityTestRule<>(TestActivity.class);
private Preview preview;
private Preview.SurfaceCallback callback;
private Size surfaceSize;
private Task<Void> surfaceAvailability;
@Before @Before
public void setUp() { public void setUp() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { ui(new Runnable() {
@Override @Override
public void run() { public void run() {
Context context = rule.getActivity(); TestActivity a = rule.getActivity();
preview = createPreview(a, a.getContentView());
surfaceSize = a.getContentSize();
// Using a parent so we know its size.
parent = new FrameLayout(context);
parent.setLayoutParams(new ViewGroup.LayoutParams(
surfaceSize.getWidth(), surfaceSize.getHeight()));
preview = createPreview(context, parent);
callback = mock(Preview.SurfaceCallback.class); callback = mock(Preview.SurfaceCallback.class);
preview.setSurfaceCallback(callback); preview.setSurfaceCallback(callback);
// Add all to a decor view and to the activity. surfaceAvailability = new Task<>();
FrameLayout decor = new FrameLayout(context); surfaceAvailability.listen();
decor.addView(parent); surfaceAvailability.start();
rule.getActivity().setContentView(decor); doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
surfaceAvailability.end(null);
return null;
}
}).when(callback).onSurfaceAvailable();
} }
}); });
} }
@Test @Test
public void testDefaults() { public void testDefaults() {
ViewGroup parent = rule.getActivity().getContentView();
assertNotNull(preview.getView()); assertNotNull(preview.getView());
assertEquals(parent.getChildAt(0), preview.getView()); assertEquals(parent.getChildAt(0), preview.getView());
assertNotNull(preview.getOutputClass()); assertNotNull(preview.getOutputClass());
@ -67,56 +70,52 @@ public abstract class PreviewTest {
} }
@Test @Test
public void testSurfaceSize() { public void testSurfaceAvailable() {
preview.onSurfaceAvailable(500, 1000); surfaceAvailability.await();
assertEquals(500, preview.getSurfaceSize().getWidth());
assertEquals(1000, preview.getSurfaceSize().getHeight());
preview.onSurfaceSizeChanged(50, 100);
assertEquals(50, preview.getSurfaceSize().getWidth());
assertEquals(100, preview.getSurfaceSize().getHeight());
preview.onSurfaceDestroyed(); // Wait for surface to be available.
assertEquals(0, preview.getSurfaceSize().getWidth()); verify(callback, times(1)).onSurfaceAvailable();
assertEquals(0, preview.getSurfaceSize().getHeight()); assertEquals(surfaceSize.getWidth(), preview.getSurfaceSize().getWidth());
assertEquals(surfaceSize.getHeight(), preview.getSurfaceSize().getHeight());
} }
@Test @Test
public void testCallbacks() { public void testSurfaceDestroyed() {
preview.onSurfaceAvailable(500, 1000); surfaceAvailability.await();
verify(callback, times(1)).onSurfaceAvailable();
preview.onSurfaceSizeChanged(50, 100); // Trigger a destroy.
verify(callback, times(1)).onSurfaceChanged(); ui(new Runnable() {
@Override
public void run() {
rule.getActivity().getContentView().removeAllViews();
}
});
assertEquals(0, preview.getSurfaceSize().getWidth());
assertEquals(0, preview.getSurfaceSize().getHeight());
} }
@Test @Test
public void testCropCenter() throws Exception { public void testCropCenter() throws Exception {
Task cropTask = preview.mCropTask; surfaceAvailability.await();
// If aspect ratio is different, there should be a crop.
preview.onSurfaceAvailable(
surfaceSize.getWidth(),
surfaceSize.getHeight());
// Not cropping. // Not cropping.
cropTask.listen(); preview.mCropTask.listen();
preview.setDesiredSize(100, 100); // Wait... preview.setDesiredSize(100, 100); // Wait...
cropTask.await(); preview.mCropTask.await();
assertEquals(100f / 100f, getScaledAspectRatio(), 0.01f); assertEquals(100f / 100f, getScaledAspectRatio(), 0.01f);
assertFalse(preview.isCropping()); assertFalse(preview.isCropping());
// Cropping. // Cropping.
cropTask.listen(); preview.mCropTask.listen();
preview.setDesiredSize(160, 50); // Wait... preview.setDesiredSize(160, 50); // Wait...
cropTask.await(); preview.mCropTask.await();
assertEquals(160f / 50f, getScaledAspectRatio(), 0.01f); assertEquals(160f / 50f, getScaledAspectRatio(), 0.01f);
assertTrue(preview.isCropping()); assertTrue(preview.isCropping());
// Not cropping. // Not cropping.
cropTask.listen(); preview.mCropTask.listen();
preview.onSurfaceSizeChanged(1600, 500); // Wait... preview.onSurfaceSizeChanged(1600, 500); // Wait...
cropTask.await(); preview.mCropTask.await();
assertEquals(160f / 50f, getScaledAspectRatio(), 0.01f); assertEquals(160f / 50f, getScaledAspectRatio(), 0.01f);
assertFalse(preview.isCropping()); assertFalse(preview.isCropping());
} }

@ -0,0 +1,94 @@
package com.otaliastudios.cameraview;
import android.content.Context;
import android.support.test.espresso.ViewAction;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.TimeUnit;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.swipeDown;
import static android.support.test.espresso.action.ViewActions.swipeLeft;
import static android.support.test.espresso.action.ViewActions.swipeRight;
import static android.support.test.espresso.action.ViewActions.swipeUp;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class ScrollGestureLayoutTest extends GestureLayoutTest<ScrollGestureLayout> {
@Override
protected ScrollGestureLayout create(Context context) {
return new ScrollGestureLayout(context);
}
@Test
public void testDefaults() {
assertNull(layout.getGestureType());
assertEquals(layout.getPoints().length, 2);
assertEquals(layout.getPoints()[0].x, 0, 0);
assertEquals(layout.getPoints()[0].y, 0, 0);
assertEquals(layout.getPoints()[1].x, 0, 0);
assertEquals(layout.getPoints()[1].y, 0, 0);
}
@Test
public void testScrollDisabled() {
layout.enable(false);
touch.listen();
touch.start();
onView(withId(layout.getId())).perform(swipeUp());
Gesture found = touch.await(500, TimeUnit.MILLISECONDS);
assertNull(found);
}
private void testScroll(ViewAction scroll, Gesture expected, boolean increasing) {
touch.listen();
touch.start();
onView(withId(layout.getId())).perform(scroll);
Gesture found = touch.await(500, TimeUnit.MILLISECONDS);
assertEquals(found, expected);
// How will this move our parameter?
float curr = 0.5f, min = 0f, max = 1f;
float newValue = layout.scaleValue(curr, min, max);
if (increasing) {
assertTrue(newValue > curr);
assertTrue(newValue <= max);
} else {
assertTrue(newValue < curr);
assertTrue(newValue >= min);
}
}
@Test
public void testScrollLeft() {
testScroll(swipeLeft(), Gesture.SCROLL_HORIZONTAL, false);
}
@Test
public void testScrollRight() {
testScroll(swipeRight(), Gesture.SCROLL_HORIZONTAL, true);
}
@Test
public void testScrollUp() {
testScroll(swipeUp(), Gesture.SCROLL_VERTICAL, true);
}
@Test
public void testScrollDown() {
testScroll(swipeDown(), Gesture.SCROLL_VERTICAL, false);
}
}

@ -0,0 +1,73 @@
package com.otaliastudios.cameraview;
import android.content.Context;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.TimeUnit;
import static android.support.test.espresso.Espresso.*;
import static android.support.test.espresso.matcher.ViewMatchers.*;
import static android.support.test.espresso.action.ViewActions.*;
import static org.junit.Assert.*;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class TapGestureLayoutTest extends GestureLayoutTest<TapGestureLayout> {
@Override
protected TapGestureLayout create(Context context) {
return new TapGestureLayout(context);
}
@Test
public void testDefaults() {
assertNull(layout.getGestureType());
assertEquals(layout.getPoints().length, 1);
assertEquals(layout.getPoints()[0].x, 0, 0);
assertEquals(layout.getPoints()[0].y, 0, 0);
}
@Test
public void testTap() {
touch.listen();
touch.start();
Size size = rule.getActivity().getContentSize();
int x = (int) (size.getWidth() / 2f);
int y = (int) (size.getHeight() / 2f);
onView(withId(layout.getId())).perform(click(x, y));
Gesture found = touch.await(500, TimeUnit.MILLISECONDS);
assertEquals(found, Gesture.TAP);
assertEquals(layout.getPoints()[0].x, x, 1);
assertEquals(layout.getPoints()[0].y, y, 1);
}
@Test
public void testTapWhileDisabled() {
layout.enable(false);
touch.listen();
touch.start();
Size size = rule.getActivity().getContentSize();
int x = (int) (size.getWidth() / 2f);
int y = (int) (size.getHeight() / 2f);
onView(withId(layout.getId())).perform(click(x, y));
Gesture found = touch.await(500, TimeUnit.MILLISECONDS);
assertNull(found);
}
@Test
public void testLongTap() {
touch.listen();
touch.start();
Size size = rule.getActivity().getContentSize();
int x = (int) (size.getWidth() / 2f);
int y = (int) (size.getHeight() / 2f);
onView(withId(layout.getId())).perform(longClick());
Gesture found = touch.await(500, TimeUnit.MILLISECONDS);
assertEquals(found, Gesture.LONG_TAP);
}
}

@ -2,6 +2,52 @@ package com.otaliastudios.cameraview;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import static android.view.ViewGroup.LayoutParams.*;
public class TestActivity extends Activity { public class TestActivity extends Activity {
private ViewGroup content;
private Size contentSize = new Size(1000, 1000);
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Match parent decor view.
FrameLayout root = new FrameLayout(this);
root.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
// Inner content view with fixed size.
content = new FrameLayout(this);
content.setLayoutParams(new ViewGroup.LayoutParams(
contentSize.getWidth(), contentSize.getHeight()));
// Add.
root.addView(content);
setContentView(root);
}
public Size getContentSize() {
return contentSize;
}
public ViewGroup getContentView() {
return content;
}
public void inflate(View child) {
inflate(child, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
public void inflate(View child, ViewGroup.LayoutParams params) {
content.addView(child, params);
content.requestLayout();
}
} }

@ -16,10 +16,12 @@ class GridLinesLayout extends View {
private Grid gridMode; private Grid gridMode;
private final Drawable horiz; Drawable horiz;
private final Drawable vert; Drawable vert;
private final float width; private final float width;
Task<Void> drawTask = new Task<>();
private final static float GOLDEN_RATIO_INV = 0.61803398874989f; private final static float GOLDEN_RATIO_INV = 0.61803398874989f;
public GridLinesLayout(@NonNull Context context) { public GridLinesLayout(@NonNull Context context) {
@ -46,7 +48,7 @@ class GridLinesLayout extends View {
public void setGridMode(Grid gridMode) { public void setGridMode(Grid gridMode) {
this.gridMode = gridMode; this.gridMode = gridMode;
invalidate(); postInvalidate();
} }
private int getLineCount() { private int getLineCount() {
@ -75,6 +77,7 @@ class GridLinesLayout extends View {
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
super.onDraw(canvas); super.onDraw(canvas);
drawTask.start();
int count = getLineCount(); int count = getLineCount();
for (int n = 0; n < count; n++) { for (int n = 0; n < count; n++) {
float pos = getLinePosition(n); float pos = getLinePosition(n);
@ -89,5 +92,6 @@ class GridLinesLayout extends View {
vert.draw(canvas); vert.draw(canvas);
canvas.translate(- pos * getWidth(), 0); canvas.translate(- pos * getWidth(), 0);
} }
drawTask.end(null);
} }
} }

@ -14,7 +14,7 @@ class PinchGestureLayout extends GestureLayout {
private final static float ADD_SENSITIVITY = 2f; private final static float ADD_SENSITIVITY = 2f;
private ScaleGestureDetector mDetector; ScaleGestureDetector mDetector;
private boolean mNotify; private boolean mNotify;
private float mAdditionFactor = 0; private float mAdditionFactor = 0;

@ -58,8 +58,8 @@ class TapGestureLayout extends GestureLayout {
// Views to draw the focus marker. // Views to draw the focus marker.
LayoutInflater.from(getContext()).inflate(R.layout.layout_focus_marker, this); LayoutInflater.from(getContext()).inflate(R.layout.layout_focus_marker, this);
mFocusMarkerContainer = (FrameLayout) findViewById(R.id.focusMarkerContainer); mFocusMarkerContainer = findViewById(R.id.focusMarkerContainer);
mFocusMarkerFill = (ImageView) findViewById(R.id.fill); mFocusMarkerFill = findViewById(R.id.fill);
} }

Loading…
Cancel
Save