diff --git a/cameraview/build.gradle b/cameraview/build.gradle
index 39f78f3b..8ec12527 100644
--- a/cameraview/build.gradle
+++ b/cameraview/build.gradle
@@ -17,6 +17,7 @@ android {
versionCode 1
versionName project.version
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ testInstrumentationRunnerArgument "filter", "com.otaliastudios.cameraview.runner.SdkExcludeFilter"
}
buildTypes {
diff --git a/cameraview/src/androidTest/AndroidManifest.xml b/cameraview/src/androidTest/AndroidManifest.xml
index c1ab0b5e..431ee7a8 100644
--- a/cameraview/src/androidTest/AndroidManifest.xml
+++ b/cameraview/src/androidTest/AndroidManifest.xml
@@ -8,12 +8,9 @@
-
diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/PinchGestureFinderTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/PinchGestureFinderTest.java
index 858f8da8..74cc7252 100644
--- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/PinchGestureFinderTest.java
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/PinchGestureFinderTest.java
@@ -4,9 +4,10 @@ package com.otaliastudios.cameraview.gesture;
import androidx.annotation.NonNull;
import androidx.test.espresso.ViewAction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
+import com.otaliastudios.cameraview.runner.SdkExclude;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -18,7 +19,7 @@ import static org.junit.Assert.assertTrue;
* On API 26 these tests fail during Espresso's inRoot() - the window never gains focus.
* This might be due to a system popup or something similar.
*/
-@SdkSuppress(minSdkVersion = 26, maxSdkVersion = 26)
+@SdkExclude(minSdkVersion = 26, maxSdkVersion = 26)
@RunWith(AndroidJUnit4.class)
@SmallTest
public class PinchGestureFinderTest extends GestureFinderTest {
diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/ScrollGestureFinderTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/ScrollGestureFinderTest.java
index 792cdb74..2b6c7418 100644
--- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/ScrollGestureFinderTest.java
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/ScrollGestureFinderTest.java
@@ -4,9 +4,10 @@ package com.otaliastudios.cameraview.gesture;
import androidx.annotation.NonNull;
import androidx.test.espresso.ViewAction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
+import com.otaliastudios.cameraview.runner.SdkExclude;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -22,7 +23,7 @@ import static org.junit.Assert.assertTrue;
* On API 26 these tests fail during Espresso's inRoot() - the window never gains focus.
* This might be due to a system popup or something similar.
*/
-@SdkSuppress(minSdkVersion = 26, maxSdkVersion = 26)
+@SdkExclude(minSdkVersion = 26, maxSdkVersion = 26)
@RunWith(AndroidJUnit4.class)
@SmallTest
public class ScrollGestureFinderTest extends GestureFinderTest {
diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/TapGestureFinderTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/TapGestureFinderTest.java
index 918b996b..0cdc4041 100644
--- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/TapGestureFinderTest.java
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/gesture/TapGestureFinderTest.java
@@ -7,11 +7,11 @@ import androidx.test.espresso.action.GeneralLocation;
import androidx.test.espresso.action.Press;
import androidx.test.espresso.action.Tap;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
import android.view.InputDevice;
import android.view.MotionEvent;
+import com.otaliastudios.cameraview.runner.SdkExclude;
import com.otaliastudios.cameraview.size.Size;
import org.junit.Test;
@@ -24,7 +24,7 @@ import static org.junit.Assert.*;
* On API 26 these tests fail during Espresso's inRoot() - the window never gains focus.
* This might be due to a system popup or something similar.
*/
-@SdkSuppress(minSdkVersion = 26, maxSdkVersion = 26)
+@SdkExclude(minSdkVersion = 26, maxSdkVersion = 26)
@RunWith(AndroidJUnit4.class)
@SmallTest
public class TapGestureFinderTest extends GestureFinderTest {
diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/internal/utils/ImageHelperTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/internal/utils/ImageHelperTest.java
index eaeef505..f884a467 100644
--- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/internal/utils/ImageHelperTest.java
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/internal/utils/ImageHelperTest.java
@@ -22,6 +22,7 @@ import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
import com.otaliastudios.cameraview.BaseTest;
+import com.otaliastudios.cameraview.runner.SdkExclude;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +36,7 @@ import static org.junit.Assert.assertNotNull;
* https://github.com/aosp-mirror/platform_frameworks_base/blob/android10-release/core/jni/android_view_Surface.cpp#L215-L217 .
* For this reason, acquireLatestImage crashes because we requested a different format.
*/
-@SdkSuppress(minSdkVersion = 29)
+@SdkExclude(minSdkVersion = 29)
@RunWith(AndroidJUnit4.class)
@SmallTest
public class ImageHelperTest extends BaseTest {
diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/runner/SdkExclude.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/runner/SdkExclude.java
new file mode 100644
index 00000000..7a119a9b
--- /dev/null
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/runner/SdkExclude.java
@@ -0,0 +1,18 @@
+package com.otaliastudios.cameraview.runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Like {@link androidx.test.filters.SdkSuppress}, but negative.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface SdkExclude {
+ /** The minimum API level to drop (inclusive) */
+ int minSdkVersion() default 1;
+ /** The maximum API level to drop (inclusive) */
+ int maxSdkVersion() default Integer.MAX_VALUE;
+}
\ No newline at end of file
diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/runner/SdkExcludeFilter.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/runner/SdkExcludeFilter.java
new file mode 100644
index 00000000..8dc014ad
--- /dev/null
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/runner/SdkExcludeFilter.java
@@ -0,0 +1,46 @@
+package com.otaliastudios.cameraview.runner;
+
+
+import android.os.Build;
+
+import androidx.annotation.Nullable;
+import androidx.test.internal.runner.filters.ParentFilter;
+
+import org.junit.runner.Description;
+
+/**
+ * Filter for {@link SdkExclude}, based on
+ * {@link androidx.test.internal.runner.TestRequestBuilder}'s SdkSuppressFilter.
+ */
+public class SdkExcludeFilter extends ParentFilter {
+
+ protected boolean evaluateTest(Description description) {
+ final SdkExclude sdkSuppress = getAnnotationForTest(description);
+ if (sdkSuppress != null) {
+ if (Build.VERSION.SDK_INT >= sdkSuppress.minSdkVersion()
+ && Build.VERSION.SDK_INT <= sdkSuppress.maxSdkVersion()) {
+ return false; // exclude the test
+ }
+ return true; // run the test
+ }
+ return true; // no annotation, run the test
+ }
+
+ @Nullable
+ private SdkExclude getAnnotationForTest(Description description) {
+ final SdkExclude s = description.getAnnotation(SdkExclude.class);
+ if (s != null) {
+ return s;
+ }
+ final Class> testClass = description.getTestClass();
+ if (testClass != null) {
+ return testClass.getAnnotation(SdkExclude.class);
+ }
+ return null;
+ }
+
+ @Override
+ public String describe() {
+ return "Skip tests annotated with SdkExclude";
+ }
+}