summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/config.cmake18
-rw-r--r--platform/android/src/test/Main.java15
-rw-r--r--platform/android/src/test/main.jni.cpp76
-rw-r--r--platform/android/src/test/runtime.cpp73
-rw-r--r--platform/android/src/test/runtime.hpp9
-rw-r--r--platform/android/src/test/test_runner.cpp10
-rw-r--r--platform/android/src/test/version-script8
7 files changed, 110 insertions, 99 deletions
diff --git a/platform/android/config.cmake b/platform/android/config.cmake
index 4a2361a7db..d78a6ce94b 100644
--- a/platform/android/config.cmake
+++ b/platform/android/config.cmake
@@ -85,23 +85,25 @@ target_link_libraries(mapbox-gl
PRIVATE mbgl-filesource
)
-## Test library ##
-
-set(MBGL_TEST_TARGET_TYPE "library")
+## Test executable ##
macro(mbgl_platform_test)
target_sources(mbgl-test
- PRIVATE platform/default/src/mbgl/test/main.cpp
-
- # Main test entry point
- platform/android/src/test/main.jni.cpp
+ PRIVATE platform/android/src/test/test_runner.cpp
+ PRIVATE platform/android/src/test/runtime.cpp
)
target_include_directories(mbgl-test
PRIVATE platform/android/include
)
+ set_target_properties(mbgl-test
+ PROPERTIES
+ LINK_FLAGS
+ "-fPIE -pie \
+ -Wl,--export-dynamic \
+ -Wl,--version-script=${CMAKE_SOURCE_DIR}/platform/android/src/test/version-script")
+
target_link_libraries(mbgl-test
- PRIVATE mbgl-core
PRIVATE mbgl-filesource
)
endmacro()
diff --git a/platform/android/src/test/Main.java b/platform/android/src/test/Main.java
deleted file mode 100644
index b0f3aeb7b9..0000000000
--- a/platform/android/src/test/Main.java
+++ /dev/null
@@ -1,15 +0,0 @@
-
-public class Main {
- public native void runAllTests(String[] args);
-
- public static void main(String[] args) throws Exception {
- // Load the tests
- System.loadLibrary("mbgl-test");
-
- // Run the tests
- new Main().runAllTests(args);
-
- // Exit explicitly otherwise dalvikvm won't quit
- System.exit(0);
- }
-}
diff --git a/platform/android/src/test/main.jni.cpp b/platform/android/src/test/main.jni.cpp
deleted file mode 100644
index 1cd0d26d2c..0000000000
--- a/platform/android/src/test/main.jni.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "../jni.hpp"
-
-#include <jni/jni.hpp>
-
-#include <mbgl/util/logging.hpp>
-#include <mbgl/test.hpp>
-
-#include <vector>
-
-namespace {
-
-// Main class (entry point for tests from dalvikvm)
-struct Main {
- static constexpr auto Name() {
- return "Main";
- }
-
- /**
- * JNI Bound to Main#runAllTests()
- */
- static void runAllTests(jni::JNIEnv& env, const jni::Object<Main>&, const jni::Array<jni::String>& args) {
- mbgl::Log::Warning(mbgl::Event::JNI, "Starting tests");
-
- // We need to create a copy of the argv data since Java-internals are stored in UTF-16.
- std::vector<std::string> data;
- // Add a fake first argument to align indices. Google Test expects the first argument to
- // start at index 1; index 0 is the name of the executable.
- data.push_back("main.jar");
- const int argc = args.Length(env);
- for (auto i = 0; i < argc; i++) {
- data.emplace_back(jni::Make<std::string>(env, args.Get(env, i)));
- }
-
- // Create an array of char pointers that point back to the data array.
- std::vector<const char*> argv;
- for (const auto& arg : data) {
- argv.push_back(arg.data());
- }
- mbgl::runTests(argv.size(), const_cast<char**>(argv.data()));
- }
-};
-
-} // namespace
-
-// We're declaring the function, which is libandroid_runtime.so.
-// It is defined in AndroidRuntime.cpp:
-// https://github.com/android/platform_frameworks_base/blob/master/core/jni/AndroidRuntime.cpp
-// Once this symbol goes away, we'll have to revisit.
-// This method loads and registers all of the Android-native frameworks so that we can use
-// android.util.Log, android.graphics.Bitmap and so on.
-// Setting the weak attribute tells the linker that this symbol is loaded at runtime and avoids
-// a missing symbol error.
-namespace android {
-struct AndroidRuntime {
- static int startReg(JNIEnv* env) __attribute__((weak));
-};
-} // namespace android
-
-// Main entry point
-extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *) {
- // Load Android-native jni bindings
- jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6);
- android::AndroidRuntime::startReg(&env);
-
- // Load the main library jni bindings
- mbgl::Log::Info(mbgl::Event::JNI, "Registering main JNI Methods");
- mbgl::android::registerNatives(vm);
-
- // Load the test library jni bindings
- mbgl::Log::Info(mbgl::Event::JNI, "Registering test JNI Methods");
-
- jni::RegisterNatives(env, *jni::Class<Main>::Find(env),
- jni::MakeNativeMethod<decltype(Main::runAllTests), &Main::runAllTests>("runAllTests"));
-
- return JNI_VERSION_1_6;
-}
diff --git a/platform/android/src/test/runtime.cpp b/platform/android/src/test/runtime.cpp
new file mode 100644
index 0000000000..9cf79c501c
--- /dev/null
+++ b/platform/android/src/test/runtime.cpp
@@ -0,0 +1,73 @@
+#include "runtime.hpp"
+#include "../jni.hpp"
+
+#include <cassert>
+#include <dlfcn.h>
+#include <jni.h>
+#include <signal.h>
+#include <string>
+
+// Required for art / libsigchain
+extern "C" JNIEXPORT void EnsureFrontOfChain(int, struct sigaction*) { }
+extern "C" JNIEXPORT void AddSpecialSignalHandlerFn(int, void*) { }
+extern "C" JNIEXPORT void RemoveSpecialSignalHandlerFn(int, bool (*) (int, siginfo_t*, void*)) { }
+
+namespace {
+const std::string kClassPathCommand{"--class_path="};
+const std::string kClassPath{"-Djava.class.path="};
+const std::string kDefaultDex{"/data/local/tmp/core-tests/classes.dex"};
+} // namespace
+
+namespace mbgl {
+namespace android {
+
+bool initRuntime(int argc, char *argv[]) {
+ void* vmHandle = dlopen("libart.so", RTLD_NOW);
+ assert(vmHandle != nullptr);
+
+ using CreateJavaVMFn = jint (*)(JavaVM** vm, JNIEnv** env, void* vmArgs);
+ CreateJavaVMFn createJavaVMFn = reinterpret_cast<CreateJavaVMFn>(dlsym(vmHandle, "JNI_CreateJavaVM"));
+ assert(createJavaVMFn != nullptr);
+
+ std::string classPath = kClassPath + kDefaultDex;
+ for (int i = 0; i < argc; ++i) {
+ const std::string arg{argv[i]};
+ if (arg.compare(0, kClassPathCommand.length(), kClassPathCommand) == 0) {
+ classPath = kClassPath + arg.substr(kClassPathCommand.length());
+ break;
+ }
+ }
+
+ JavaVMOption options[1];
+ options[0].optionString = classPath.c_str();
+
+ JavaVMInitArgs args;
+ args.version = JNI_VERSION_1_6;
+ args.nOptions = 1;
+ args.options = options;
+ args.ignoreUnrecognized = JNI_FALSE;
+
+ JavaVM* vm;
+ JNIEnv* env;
+
+ if (createJavaVMFn(&vm, &env, &args) != JNI_OK) {
+ return false;
+ }
+
+ void* runtimeHandle = dlopen("libandroid_runtime.so", RTLD_NOW);
+ assert(runtimeHandle != nullptr);
+
+ using RegisterNativesFn = jint (*)(JNIEnv* env);
+ RegisterNativesFn registerNativesFn = reinterpret_cast<RegisterNativesFn>(dlsym(runtimeHandle, "registerFrameworkNatives"));
+ assert(registerNativesFn != nullptr);
+
+ if (registerNativesFn(env) != JNI_OK) {
+ return false;
+ }
+
+ mbgl::android::registerNatives(vm);
+ return true;
+}
+
+} // namespace android
+} // namespace mbgl
diff --git a/platform/android/src/test/runtime.hpp b/platform/android/src/test/runtime.hpp
new file mode 100644
index 0000000000..c5e69d61c0
--- /dev/null
+++ b/platform/android/src/test/runtime.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+namespace mbgl {
+namespace android {
+
+bool initRuntime(int argc, char *argv[]);
+
+} // namespace android
+} // namespace mbgl
diff --git a/platform/android/src/test/test_runner.cpp b/platform/android/src/test/test_runner.cpp
new file mode 100644
index 0000000000..008e3c5748
--- /dev/null
+++ b/platform/android/src/test/test_runner.cpp
@@ -0,0 +1,10 @@
+#include "runtime.hpp"
+#include <mbgl/test.hpp>
+
+int main(int argc, char *argv[]) {
+ if (!mbgl::android::initRuntime(argc, argv)) {
+ return 1;
+ }
+
+ mbgl::runTests(argc, argv);
+}
diff --git a/platform/android/src/test/version-script b/platform/android/src/test/version-script
new file mode 100644
index 0000000000..ebc2c17018
--- /dev/null
+++ b/platform/android/src/test/version-script
@@ -0,0 +1,8 @@
+{
+global:
+ EnsureFrontOfChain;
+ AddSpecialSignalHandlerFn;
+ RemoveSpecialSignalHandlerFn;
+local:
+ *;
+};