summaryrefslogtreecommitdiff
path: root/wrappers/java-android/lib
diff options
context:
space:
mode:
Diffstat (limited to 'wrappers/java-android/lib')
-rw-r--r--wrappers/java-android/lib/.gitignore2
-rw-r--r--wrappers/java-android/lib/CMakeLists.txt38
-rw-r--r--wrappers/java-android/lib/build.gradle107
-rw-r--r--wrappers/java-android/lib/consumer-rules.pro0
-rw-r--r--wrappers/java-android/lib/proguard-rules.pro21
-rw-r--r--wrappers/java-android/lib/src/main/AndroidManifest.xml4
-rw-r--r--wrappers/java-android/lib/src/test/java/org/eduvpn/common/VerifyTests.java77
7 files changed, 249 insertions, 0 deletions
diff --git a/wrappers/java-android/lib/.gitignore b/wrappers/java-android/lib/.gitignore
new file mode 100644
index 0000000..1ac6136
--- /dev/null
+++ b/wrappers/java-android/lib/.gitignore
@@ -0,0 +1,2 @@
+/build
+/src/test/resources/*
diff --git a/wrappers/java-android/lib/CMakeLists.txt b/wrappers/java-android/lib/CMakeLists.txt
new file mode 100644
index 0000000..9bea062
--- /dev/null
+++ b/wrappers/java-android/lib/CMakeLists.txt
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 3.18.1)
+project(eduvpn_common)
+
+set(CMAKE_VERBOSE_MAKEFILE on)
+
+# Android -> Go architecture map
+set(arch_map_x86 386)
+set(arch_map_x86_64 amd64)
+set(arch_map_arm arm)
+set(arch_map_arm64 arm64)
+
+set(GOARCH ${arch_map_${ANDROID_ARCH_NAME}})
+
+find_program(MAKE_EXECUTABLE
+ NAMES gmake mingw32-make make
+ NAMES_PER_DIR
+ DOC "GNU Make"
+ REQUIRED
+)
+
+# Inspired by https://github.com/WireGuard/wireguard-android/blob/1.0.20211029/tunnel/tools/CMakeLists.txt
+
+# --target has to be specified to compiler & linker as e.g. ANDROID_C_COMPILER may just be 'clang' without prefixes
+# CGO_CPPFLAGS are concatenated to CGO_CFLAGS and CGO_CXXFLAGS
+add_custom_target(shared-lib
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../../exports"
+ COMMENT "Building shared library for ${ANDROID_LLVM_TRIPLE}"
+ VERBATIM
+ COMMAND ${MAKE_EXECUTABLE}
+ GOOS=android GOARCH=${GOARCH}
+ CC=${ANDROID_C_COMPILER} CXX=${ANDROID_CXX_COMPILER}
+ CGO_CPPFLAGS=--target=${ANDROID_LLVM_TRIPLE} CGO_CFLAGS=${CMAKE_C_FLAGS} CGO_CXXFLAGS=${CMAKE_CXX_FLAGS}
+ CGO_LDFLAGS=${CMAKE_SHARED_LINKER_FLAGS}\ --target=${ANDROID_LLVM_TRIPLE}
+ COPY_LIB_TO=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
+)
+
+# Note about COPY_LIB_TO: this is an easy cross-platform alternative to calling `cp`
+# file(COPY ...) does not work since it runs at the configure stage...
diff --git a/wrappers/java-android/lib/build.gradle b/wrappers/java-android/lib/build.gradle
new file mode 100644
index 0000000..be666aa
--- /dev/null
+++ b/wrappers/java-android/lib/build.gradle
@@ -0,0 +1,107 @@
+import com.android.build.api.dsl.ManagedVirtualDevice
+
+plugins {
+ id 'com.android.library' // Build AAR
+}
+
+android {
+ compileSdk 31
+
+ defaultConfig {
+ minSdk 21
+ targetSdk 31
+ versionCode 1
+ versionName '1.0'
+
+ testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
+
+ consumerProguardFiles 'consumer-rules.pro'
+
+ externalNativeBuild {
+ cmake {
+ // Specify which target we want to build
+ targets 'shared-lib'
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ // Support Java 8+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ externalNativeBuild {
+ cmake {
+ version '3.18.1' // See cmake_minimum_required in CMakeLists.txt
+ path 'CMakeLists.txt'
+ }
+ }
+
+ sourceSets {
+ androidTest {
+ // Use same sources & resources for Android instrumented tests as unit tests
+ java.srcDirs = sourceSets.test.java.srcDirs
+ resources.srcDirs = sourceSets.test.resources.srcDirs
+ }
+ }
+
+ task copyTestData(type: Copy, description: 'Copy test_data to test resources') {
+ from('../../../test_data') {
+ exclude '**/*.py', '**/*.sh'
+ }
+ into sourceSets.test.resources.srcDirs[0].toPath().resolve('org/eduvpn/common')
+ }
+
+ // Copy test_data to Java resources before these are processed
+ // (.named does not find all tasks. Task names were obtained with com.dorongold.task-tree plugin)
+ tasks.matching { t ->
+ t.name in [
+ 'processDebugUnitTestJavaRes', 'processReleaseUnitTestJavaRes',
+ 'processDebugAndroidTestJavaRes', 'processReleaseAndroidTestJavaRes']
+ }.all {
+ dependsOn copyTestData
+ }
+
+ // Do not cache unit test results as the shared library may have changed
+ tasks.matching { t -> t.name in ['testDebugUnitTest', 'testReleaseUnitTest'] }.all {
+ outputs.upToDateWhen { false }
+ }
+
+ testOptions {
+ // Display full exceptions and passed tests for unit tests
+ unitTests.all {
+ testLogging {
+ events 'passed', 'skipped', 'failed'
+ exceptionFormat 'full'
+ }
+ }
+
+ devices {
+ pixel2(ManagedVirtualDevice) {
+ device = 'Pixel 2'
+ apiLevel = 30
+ systemImageSource = 'aosp'
+ abi = 'x86_64'
+ }
+ }
+ }
+}
+
+dependencies {
+ implementation 'net.java.dev.jna:jna:5.10.0@aar'
+
+ testImplementation 'commons-io:commons-io:2.11.0'
+ testImplementation 'net.java.dev.jna:jna:5.10.0' // Include jnidispatch library in unit tests
+ testImplementation 'junit:junit:4.+'
+
+ androidTestImplementation 'commons-io:commons-io:2.11.0'
+ androidTestImplementation 'androidx.test:runner:1.4.0'
+}
diff --git a/wrappers/java-android/lib/consumer-rules.pro b/wrappers/java-android/lib/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/wrappers/java-android/lib/consumer-rules.pro
diff --git a/wrappers/java-android/lib/proguard-rules.pro b/wrappers/java-android/lib/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/wrappers/java-android/lib/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/wrappers/java-android/lib/src/main/AndroidManifest.xml b/wrappers/java-android/lib/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..5a49838
--- /dev/null
+++ b/wrappers/java-android/lib/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest package="org.eduvpn.common">
+
+</manifest>
diff --git a/wrappers/java-android/lib/src/test/java/org/eduvpn/common/VerifyTests.java b/wrappers/java-android/lib/src/test/java/org/eduvpn/common/VerifyTests.java
new file mode 100644
index 0000000..a73ac75
--- /dev/null
+++ b/wrappers/java-android/lib/src/test/java/org/eduvpn/common/VerifyTests.java
@@ -0,0 +1,77 @@
+package org.eduvpn.common;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class VerifyTests {
+ private static byte[] readAll(String resource) throws IOException {
+ try (InputStream stream = VerifyTests.class.getResourceAsStream(resource)) {
+ return IOUtils.toByteArray(stream);
+ }
+ }
+
+ @SuppressWarnings("OptionalGetWithoutIsPresent")
+ @BeforeClass
+ public static void oneTimeSetup() throws IOException {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(
+ VerifyTests.class.getResourceAsStream("public.key")))) {
+ Discovery.insecureTestingSetExtraKey(reader.lines().reduce((a, b) -> b).get());
+ }
+ }
+
+ @Test
+ public void testValid() throws IOException, VerifyException {
+ Discovery.verify(
+ readAll("server_list.json.minisig"),
+ readAll("server_list.json"),
+ "server_list.json",
+ 0
+ );
+ }
+
+ @Test(expected = InvalidSignatureException.class)
+ public void testInvalidSignature() throws IOException, VerifyException {
+ Discovery.verify(
+ readAll("random.txt"),
+ readAll("server_list.json"),
+ "server_list.json",
+ 0
+ );
+ }
+
+ @Test(expected = InvalidSignatureUnknownKeyException.class)
+ public void testWrongKey() throws IOException, VerifyException {
+ Discovery.verify(
+ readAll("server_list.json.wrong_key.minisig"),
+ readAll("server_list.json"),
+ "server_list.json",
+ 0
+ );
+ }
+
+ @Test(expected = SignatureTooOldException.class)
+ public void testOldSignature() throws IOException, VerifyException {
+ Discovery.verify(
+ readAll("server_list.json.minisig"),
+ readAll("server_list.json"),
+ "server_list.json",
+ Long.MAX_VALUE
+ );
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testUnknownExpectedFile() throws IOException, VerifyException {
+ Discovery.verify(
+ readAll("other_list.json.minisig"),
+ readAll("other_list.json"),
+ "other_list.json",
+ 0
+ );
+ }
+}