android_jni: Add instrumented tests These tests will run on a real android device or an emulator and will act as a sanity check for the JNI bindings.
diff --git a/android_jni/README.md b/android_jni/README.md index 92f0071..9b8cfd9 100644 --- a/android_jni/README.md +++ b/android_jni/README.md
@@ -52,6 +52,25 @@ The instructions on how to add the AAR package as a dependency to your Android project can be found [here](https://developer.android.com/studio/projects/android-library#psd-add-aar-jar-dependency). +## Running Instrumented Tests + +Step 1 - Build the library + +Make sure to build the library by following the steps under +[Generate the AAR package](#generate-the-aar-package) section above. + +Step 2 - Set up a device/emulator + +Make sure that a device or an emulator has been set up and is available via +`adb`. + +Step 3 - Run the tests + +``` +$ cd android_jni +$ ./gradlew connectedAndroidTest +``` + ## Using Android Studio The entire android_jni directory can be imported as a project into Android Studio.
diff --git a/android_jni/avifandroidjni/build.gradle b/android_jni/avifandroidjni/build.gradle index 707a32d..956528c 100644 --- a/android_jni/avifandroidjni/build.gradle +++ b/android_jni/avifandroidjni/build.gradle
@@ -10,6 +10,7 @@ targetSdk 30 versionCode 1 versionName "1.0" + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes { @@ -33,4 +34,8 @@ } dependencies { -} \ No newline at end of file + androidTestImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'com.google.truth:truth:1.1.3' + androidTestImplementation 'androidx.test:runner:1.5.2' +}
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/README b/android_jni/avifandroidjni/src/androidTest/assets/README new file mode 100644 index 0000000..2307913 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/README
@@ -0,0 +1,7 @@ +This file describes the sources of files in this directory. + +* Sub-Directory: avif + Description: Images used for testing still AVIF decoding. + Source: https://github.com/AOMediaCodec/av1-avif/tree/master/testFiles/Link-U + Filter: Only a subset of fox* files. + Git Hash: 77bd20d
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.10bpc.yuv420.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.10bpc.yuv420.avif new file mode 100644 index 0000000..025c185 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.10bpc.yuv420.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.10bpc.yuv420.monochrome.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.10bpc.yuv420.monochrome.avif new file mode 100644 index 0000000..5b8a127 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.10bpc.yuv420.monochrome.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.8bpc.yuv420.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.8bpc.yuv420.avif new file mode 100644 index 0000000..cf23e6e --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.8bpc.yuv420.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.8bpc.yuv420.monochrome.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.8bpc.yuv420.monochrome.avif new file mode 100644 index 0000000..57ca3f1 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile0.8bpc.yuv420.monochrome.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile1.10bpc.yuv444.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile1.10bpc.yuv444.avif new file mode 100644 index 0000000..132695e --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile1.10bpc.yuv444.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile1.8bpc.yuv444.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile1.8bpc.yuv444.avif new file mode 100644 index 0000000..ba1c5ff --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile1.8bpc.yuv444.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.10bpc.yuv422.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.10bpc.yuv422.avif new file mode 100644 index 0000000..6143168 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.10bpc.yuv422.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv420.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv420.avif new file mode 100644 index 0000000..4299cf7 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv420.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv420.monochrome.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv420.monochrome.avif new file mode 100644 index 0000000..34293c2 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv420.monochrome.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv422.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv422.avif new file mode 100644 index 0000000..2e69ec6 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv422.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv444.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv444.avif new file mode 100644 index 0000000..03c3599 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.12bpc.yuv444.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.8bpc.yuv422.avif b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.8bpc.yuv422.avif new file mode 100644 index 0000000..7f3a788 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/assets/avif/fox.profile2.8bpc.yuv422.avif Binary files differ
diff --git a/android_jni/avifandroidjni/src/androidTest/java/org/aomedia/avif/android/StillImageTest.java b/android_jni/avifandroidjni/src/androidTest/java/org/aomedia/avif/android/StillImageTest.java new file mode 100644 index 0000000..6d92493 --- /dev/null +++ b/android_jni/avifandroidjni/src/androidTest/java/org/aomedia/avif/android/StillImageTest.java
@@ -0,0 +1,84 @@ +package org.aomedia.avif.android; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import androidx.test.platform.app.InstrumentationRegistry; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.aomedia.avif.android.AvifDecoder.Info; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +/** Instrumentation tests for the libavif JNI API, which will execute on an Android device. */ +@RunWith(Parameterized.class) +public class StillImageTest { + + private static final String ASSET_DIRECTORY = "avif"; + + @Parameters + public static List<Object[]> data() throws IOException { + ArrayList<Object[]> list = new ArrayList<>(); + for (String asset : getAssetFiles(ASSET_DIRECTORY)) { + String assetPath = Paths.get(ASSET_DIRECTORY, asset).toString(); + // Test ARGB_8888 for all files. + list.add(new Object[] {Config.ARGB_8888, assetPath}); + // For 8bpc files, test only RGB_565. For other files, test only RGBA_F16. + Config testConfig = assetPath.contains("8bpc") ? Config.RGB_565 : Config.RGBA_F16; + list.add(new Object[] {testConfig, assetPath}); + } + return list; + } + + @Parameter(0) + public Bitmap.Config config; + + @Parameter(1) + public String assetPath; + + @Test + public void testIsAvifImageReturnsTrue() throws IOException { + ByteBuffer buffer = getBuffer(); + assertThat(buffer).isNotNull(); + assertThat(AvifDecoder.isAvifImage(buffer)).isTrue(); + } + + @Test + public void testAvifDecode() throws IOException { + ByteBuffer buffer = getBuffer(); + assertThat(buffer).isNotNull(); + Info info = new Info(); + assertThat(AvifDecoder.getInfo(buffer, buffer.remaining(), info)).isTrue(); + assertThat(info.width).isGreaterThan(0); + assertThat(info.height).isGreaterThan(0); + assertThat(info.depth).isAnyOf(8, 10, 12); + Bitmap bitmap = Bitmap.createBitmap(info.width, info.height, config); + assertThat(bitmap).isNotNull(); + assertThat(AvifDecoder.decode(buffer, buffer.remaining(), bitmap)).isTrue(); + } + + private ByteBuffer getBuffer() throws IOException { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + InputStream is = context.getAssets().open(assetPath); + ByteBuffer buffer = ByteBuffer.allocateDirect(is.available()); + Channels.newChannel(is).read(buffer); + buffer.rewind(); + return buffer; + } + + private static List<String> getAssetFiles(String directoryName) throws IOException { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + return Arrays.asList(context.getAssets().list(directoryName)); + } +}