diff options
author | Tor Lillqvist <tlillqvist@suse.com> | 2011-11-14 16:59:01 +0200 |
---|---|---|
committer | Tor Lillqvist <tlillqvist@suse.com> | 2011-11-15 01:54:48 +0200 |
commit | d14416463a0e62cf624cf66e8a599abac5694cd2 (patch) | |
tree | aa58a65b3c9ec4c3632b6dd2ea8d585f21beadbf /sal | |
parent | 12df49396e6bcb07bafc95255a8526caac96e60a (diff) |
Intermediate Android commit, before having NativeActivity load lo-bootstrap
Diffstat (limited to 'sal')
-rw-r--r-- | sal/inc/sal/main.h | 32 | ||||
-rw-r--r-- | sal/osl/android/Makefile | 22 | ||||
-rw-r--r-- | sal/osl/android/jni/lo-bootstrap.c | 357 | ||||
-rw-r--r-- | sal/osl/android/src/org/libreoffice/android/Bootstrap.java | 9 |
4 files changed, 224 insertions, 196 deletions
diff --git a/sal/inc/sal/main.h b/sal/inc/sal/main.h index bf1d2d3ef477..6bbbb1e8e2a2 100644 --- a/sal/inc/sal/main.h +++ b/sal/inc/sal/main.h @@ -119,27 +119,20 @@ static int sal_main(void); #elif defined ANDROID +#include <android/log.h> + +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "lo-bootstrap", __VA_ARGS__)) +#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "lo-bootstrap", __VA_ARGS__)) + #ifdef __cplusplus -extern "C" { -#endif -#include <android_native_app_glue.c> -#ifdef __cplusplus -} +extern "C" void lo_main(int argc, char **argv); #endif #define SAL_MAIN_WITH_ARGS_IMPL \ static int sal_main_with_args(int argc, char **argv); \ \ -void android_main(struct android_app *state) \ +void lo_main(int argc, char **argv) \ { \ - int argc = 0; \ - char **argv = { NULL }; \ -\ - (void) state; \ -\ - /* Make sure glue isn't stripped. */ \ - app_dummy(); \ -\ sal_detail_initialize(argc, argv); \ sal_main_with_args(argc, argv); \ sal_detail_deinitialize(); \ @@ -148,16 +141,9 @@ void android_main(struct android_app *state) \ #define SAL_MAIN_IMPL \ static int sal_main(void); \ \ -void android_main(struct android_app *state) \ +void lo_main(int argc, char **argv) \ { \ - int argc = 0; \ - char **argv = { NULL }; \ -\ - (void) state; \ -\ - /* Make sure glue isn't stripped. */ \ - app_dummy(); \ -\ + LOGI("in lo_main, argc=%d, argv[0]=%s, argv[1]=%s", argc, argv[0], argv[1]); \ sal_detail_initialize(argc, argv); \ sal_main(); \ sal_detail_deinitialize(); \ diff --git a/sal/osl/android/Makefile b/sal/osl/android/Makefile index 4027608180ad..8ee14b8bf2d9 100644 --- a/sal/osl/android/Makefile +++ b/sal/osl/android/Makefile @@ -1,12 +1,18 @@ -all: bin/LibreOfficeBootstrap-debug.apk +NDK_HOME:=$(shell type -p ndk-build) +NDK_HOME:=$(shell dirname $(NDK_HOME)) -bin/LibreOfficeBootstrap-debug.apk : jni/*.c src/org/libreoffice/android/*.java +all: ndk-build V=1 - cp ../../../solver/unxandr.pro/bin/cppunit/cppunittester libs/armeabi-v7a/libcppunittester.so + cp ../../unxandr.pro/bin/cppunittester libs/armeabi-v7a/libcppunittester.so cp ../../../solver/unxandr.pro/lib/libcppunit-1.12.so libs/armeabi-v7a - cp ../../../solver/unxandr.pro/lib/libuno_sal.so libs/armeabi-v7a - ant debug - @echo Install it on the device with ant debug install - @echo Then run it with something like: - @echo adb shell am start -a org.libreoffice.android -n org.libreoffice.android/.Bootstrap -e lo-main-library libcppunittester + cp ../../unxandr.pro/lib/*.so libs/armeabi-v7a + cp $(NDK_HOME)/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/libgnustl_shared.so libs/armeabi-v7a + unset JAVA_HOME && ant debug + @echo 'Install it on the device with ant debug install' + @echo 'Then run it with something like what "make run" does (see Makefile)' +run: all + unset JAVA_HOME && ant debug install +# +# Note: this is of course just an example + adb shell am start -a org.libreoffice.android -n org.libreoffice.android/.Bootstrap -e lo-main-library libcppunittester -e lo-main-cmdline "cppunittester /data/data/org.libreoffice.android/lib/libqa_sal_types.so" diff --git a/sal/osl/android/jni/lo-bootstrap.c b/sal/osl/android/jni/lo-bootstrap.c index 9f9aaa4b947c..56b72fef5f3e 100644 --- a/sal/osl/android/jni/lo-bootstrap.c +++ b/sal/osl/android/jni/lo-bootstrap.c @@ -43,185 +43,185 @@ read_section(JNIEnv *env, int fd, Elf32_Shdr *shdr) { - char *result; + char *result; - result = malloc(shdr->sh_size); - if (lseek(fd, shdr->sh_offset, SEEK_SET) < 0) { - close(fd); - free(result); - return NULL; - } - if (read(fd, result, shdr->sh_size) < shdr->sh_size) { - close(fd); - free(result); - return NULL; - } + result = malloc(shdr->sh_size); + if (lseek(fd, shdr->sh_offset, SEEK_SET) < 0) { + close(fd); + free(result); + return NULL; + } + if (read(fd, result, shdr->sh_size) < shdr->sh_size) { + close(fd); + free(result); + return NULL; + } - return result; + return result; } jobjectArray -Java_org_libreoffice_android_Bootstrap_dlneeds( JNIEnv* env, - jobject clazz, - jstring library) +Java_org_libreoffice_android_Bootstrap_dlneeds(JNIEnv* env, + jobject clazz, + jstring library) { - int i, fd; - int n_needed; - const jbyte *libName; - jobjectArray result; - char *shstrtab, *dynstr; - Elf32_Ehdr hdr; - Elf32_Shdr shdr; - Elf32_Dyn dyn; + int i, fd; + int n_needed; + const jbyte *libName; + jobjectArray result; + char *shstrtab, *dynstr; + Elf32_Ehdr hdr; + Elf32_Shdr shdr; + Elf32_Dyn dyn; - /* Open library and read ELF header */ + /* Open library and read ELF header */ - libName = (*env)->GetStringUTFChars(env, library, NULL); + libName = (*env)->GetStringUTFChars(env, library, NULL); - LOGI("dlneeds(%s)\n", libName); + LOGI("dlneeds(%s)\n", libName); - fd = open (libName, O_RDONLY); + fd = open (libName, O_RDONLY); - (*env)->ReleaseStringUTFChars(env, library, libName); + (*env)->ReleaseStringUTFChars(env, library, libName); - if (fd == -1) { - LOGI("Could not open library"); - return NULL; - } - - if (read(fd, &hdr, sizeof(hdr)) < sizeof(hdr)) { - close(fd); - LOGI("Could not read ELF header"); - return NULL; - } - - /* Read in .shstrtab */ - - if (lseek(fd, hdr.e_shoff + hdr.e_shstrndx * sizeof(shdr), SEEK_SET) < 0) { - close(fd); - LOGI("Could not seek to .shstrtab section header"); - return NULL; - } - if (read(fd, &shdr, sizeof(shdr)) < sizeof(shdr)) { - close(fd); - LOGI("Could not read section header"); - return NULL; - } + if (fd == -1) { + LOGI("Could not open library"); + return NULL; + } - shstrtab = read_section(env, fd, &shdr); - if (shstrtab == NULL) - return NULL; + if (read(fd, &hdr, sizeof(hdr)) < sizeof(hdr)) { + close(fd); + LOGI("Could not read ELF header"); + return NULL; + } - /* Read section headers, looking for .dynstr section */ + /* Read in .shstrtab */ - if (lseek(fd, hdr.e_shoff, SEEK_SET) < 0) { - close(fd); - LOGI("Could not seek to section headers"); - return NULL; - } - for (i = 0; i < hdr.e_shnum; i++) { - if (read(fd, &shdr, sizeof(shdr)) < sizeof(shdr)) { - close(fd); - LOGI("Could not read section header"); - return NULL; + if (lseek(fd, hdr.e_shoff + hdr.e_shstrndx * sizeof(shdr), SEEK_SET) < 0) { + close(fd); + LOGI("Could not seek to .shstrtab section header"); + return NULL; } - if (shdr.sh_type == SHT_STRTAB && - strcmp(shstrtab + shdr.sh_name, ".dynstr") == 0) { - dynstr = read_section(env, fd, &shdr); - if (dynstr == NULL) { - free(shstrtab); + if (read(fd, &shdr, sizeof(shdr)) < sizeof(shdr)) { + close(fd); + LOGI("Could not read section header"); return NULL; - } - break; } - } - if (i == hdr.e_shnum) { - close(fd); - LOGI("No .dynstr section"); - return NULL; - } + shstrtab = read_section(env, fd, &shdr); + if (shstrtab == NULL) + return NULL; - /* Read section headers, looking for .dynamic section */ + /* Read section headers, looking for .dynstr section */ - if (lseek(fd, hdr.e_shoff, SEEK_SET) < 0) { - close(fd); - LOGI("Could not seek to section headers"); - return NULL; - } - for (i = 0; i < hdr.e_shnum; i++) { - if (read(fd, &shdr, sizeof(shdr)) < sizeof(shdr)) { - close(fd); - LOGI("Could not read section header"); - return NULL; - } - if (shdr.sh_type == SHT_DYNAMIC) { - int dynoff; - int *libnames; - jclass String; - - /* Count number of DT_NEEDED entries */ - n_needed = 0; - if (lseek(fd, shdr.sh_offset, SEEK_SET) < 0) { + if (lseek(fd, hdr.e_shoff, SEEK_SET) < 0) { close(fd); - LOGI("Could not seek to .dynamic section"); + LOGI("Could not seek to section headers"); return NULL; - } - for (dynoff = 0; dynoff < shdr.sh_size; dynoff += sizeof(dyn)) { - if (read(fd, &dyn, sizeof(dyn)) < sizeof(dyn)) { - close(fd); - LOGI("Could not read .dynamic entry"); - return NULL; + } + for (i = 0; i < hdr.e_shnum; i++) { + if (read(fd, &shdr, sizeof(shdr)) < sizeof(shdr)) { + close(fd); + LOGI("Could not read section header"); + return NULL; } - if (dyn.d_tag == DT_NEEDED) - n_needed++; - } - - LOGI("Found %d DT_NEEDED libs", n_needed); - - /* Allocate return value */ + if (shdr.sh_type == SHT_STRTAB && + strcmp(shstrtab + shdr.sh_name, ".dynstr") == 0) { + dynstr = read_section(env, fd, &shdr); + if (dynstr == NULL) { + free(shstrtab); + return NULL; + } + break; + } + } - String = (*env)->FindClass(env, "java/lang/String"); - if (String == NULL) { + if (i == hdr.e_shnum) { close(fd); - LOGI("Could not find the String class"); + LOGI("No .dynstr section"); return NULL; - } + } - result = (*env)->NewObjectArray(env, n_needed, String, NULL); - if (result == NULL) { - close (fd); - LOGI("Could not create the String array"); - return NULL; - } + /* Read section headers, looking for .dynamic section */ - n_needed = 0; - if (lseek(fd, shdr.sh_offset, SEEK_SET) < 0) { + if (lseek(fd, hdr.e_shoff, SEEK_SET) < 0) { close(fd); - LOGI("Could not seek to .dynamic section"); + LOGI("Could not seek to section headers"); return NULL; - } - for (dynoff = 0; dynoff < shdr.sh_size; dynoff += sizeof(dyn)) { - if (read(fd, &dyn, sizeof(dyn)) < sizeof(dyn)) { - close(fd); - LOGI("Could not read .dynamic entry"); - return NULL; + } + for (i = 0; i < hdr.e_shnum; i++) { + if (read(fd, &shdr, sizeof(shdr)) < sizeof(shdr)) { + close(fd); + LOGI("Could not read section header"); + return NULL; } - if (dyn.d_tag == DT_NEEDED) { - LOGI("needs: %s\n", dynstr + dyn.d_un.d_val); - (*env)->SetObjectArrayElement(env, result, n_needed, (*env)->NewStringUTF(env, dynstr + dyn.d_un.d_val)); - n_needed++; + if (shdr.sh_type == SHT_DYNAMIC) { + int dynoff; + int *libnames; + jclass String; + + /* Count number of DT_NEEDED entries */ + n_needed = 0; + if (lseek(fd, shdr.sh_offset, SEEK_SET) < 0) { + close(fd); + LOGI("Could not seek to .dynamic section"); + return NULL; + } + for (dynoff = 0; dynoff < shdr.sh_size; dynoff += sizeof(dyn)) { + if (read(fd, &dyn, sizeof(dyn)) < sizeof(dyn)) { + close(fd); + LOGI("Could not read .dynamic entry"); + return NULL; + } + if (dyn.d_tag == DT_NEEDED) + n_needed++; + } + + LOGI("Found %d DT_NEEDED libs", n_needed); + + /* Allocate return value */ + + String = (*env)->FindClass(env, "java/lang/String"); + if (String == NULL) { + close(fd); + LOGI("Could not find the String class"); + return NULL; + } + + result = (*env)->NewObjectArray(env, n_needed, String, NULL); + if (result == NULL) { + close (fd); + LOGI("Could not create the String array"); + return NULL; + } + + n_needed = 0; + if (lseek(fd, shdr.sh_offset, SEEK_SET) < 0) { + close(fd); + LOGI("Could not seek to .dynamic section"); + return NULL; + } + for (dynoff = 0; dynoff < shdr.sh_size; dynoff += sizeof(dyn)) { + if (read(fd, &dyn, sizeof(dyn)) < sizeof(dyn)) { + close(fd); + LOGI("Could not read .dynamic entry"); + return NULL; + } + if (dyn.d_tag == DT_NEEDED) { + LOGI("needs: %s\n", dynstr + dyn.d_un.d_val); + (*env)->SetObjectArrayElement(env, result, n_needed, (*env)->NewStringUTF(env, dynstr + dyn.d_un.d_val)); + n_needed++; + } + } + + close(fd); + free(dynstr); + free(shstrtab); + return result; } - } - - close(fd); - free(dynstr); - free(shstrtab); - return result; } - } - return NULL; + return NULL; } jint @@ -229,15 +229,15 @@ Java_org_libreoffice_android_Bootstrap_dlopen(JNIEnv* env, jobject clazz, jstring library) { - const jbyte *libName = (*env)->GetStringUTFChars(env, library, NULL); - void *p = dlopen (libName, RTLD_LOCAL); - LOGI("dlopen(%s) = %p", libName, p); - (*env)->ReleaseStringUTFChars(env, library, libName); - if (p == NULL) { - LOGI(dlerror()); - return 0; - } - return (jint) p; + const jbyte *libName = (*env)->GetStringUTFChars(env, library, NULL); + void *p = dlopen (libName, RTLD_LOCAL); + LOGI("dlopen(%s) = %p", libName, p); + (*env)->ReleaseStringUTFChars(env, library, libName); + if (p == NULL) { + LOGI(dlerror()); + return 0; + } + return (jint) p; } jint @@ -246,15 +246,15 @@ Java_org_libreoffice_android_Bootstrap_dlsym(JNIEnv* env, jint handle, jstring symbol) { - const jbyte *symName = (*env)->GetStringUTFChars(env, symbol, NULL); - void *p = dlsym ((void *)handle, symName); - LOGI("dlsym(%p,%s) = %p", handle, symName, p); - (*env)->ReleaseStringUTFChars(env, symbol, symName); - if (p == NULL) { - LOGI(dlerror()); - return 0; - } - return (jint) p; + const jbyte *symName = (*env)->GetStringUTFChars(env, symbol, NULL); + void *p = dlsym ((void *)handle, symName); + LOGI("dlsym(%p,%s) = %p", handle, symName, p); + (*env)->ReleaseStringUTFChars(env, symbol, symName); + if (p == NULL) { + LOGI(dlerror()); + return 0; + } + return (jint) p; } jint @@ -263,8 +263,37 @@ Java_org_libreoffice_android_Bootstrap_dlcall(JNIEnv* env, jint function, jobject argument) { - /* To be implemented */ - return 0; + jclass StringArray = (*env)->FindClass(env, "[Ljava/lang/String;"); + + if (StringArray == NULL) { + LOGI("Could not find String[] class"); + return 0; + } + + if ((*env)->IsInstanceOf(env, argument, StringArray)) { + LOGI("Yes, a string array argument of length %d", (*env)->GetArrayLength(env, argument)); + int argc = (*env)->GetArrayLength(env, argument); + const char **argv = malloc(sizeof(char *) * (argc+1)); + int i, result; + for (i = 0; i < argc; i++) { + argv[i] = (*env)->GetStringUTFChars(env, (*env)->GetObjectArrayElement(env, argument, i), NULL); + LOGI("argv[%d] = %s", i, argv[i]); + } + argv[argc] = NULL; + + int (*fp)(int, const char **) = function; + + result = fp(argc, argv); + + for (i = 0; i < argc; i++) + (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, argument, i), argv[i]); + + free(argv); + return result; + } + + /* To be implemented */ + return 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/osl/android/src/org/libreoffice/android/Bootstrap.java b/sal/osl/android/src/org/libreoffice/android/Bootstrap.java index 45a92923c40e..5ba969ad41e3 100644 --- a/sal/osl/android/src/org/libreoffice/android/Bootstrap.java +++ b/sal/osl/android/src/org/libreoffice/android/Bootstrap.java @@ -127,6 +127,9 @@ public class Bootstrap extends Activity String mainLibrary = getIntent().getStringExtra("lo-main-library"); + if (mainLibrary == null) + mainLibrary = "libcppunittester"; + if (mainLibrary != null) { int loLib = loadLibrary(mainLibrary + ".so"); @@ -135,9 +138,13 @@ public class Bootstrap extends Activity // Get "command line" to pass to the LO "program" String cmdLine = getIntent().getStringExtra("lo-main-cmdline"); + + if (cmdLine == null) + cmdLine = "cppunittester /data/data/org.libreoffice.android/lib/libqa_rtl_strings.so"; + String[] argv; if (cmdLine != null) - argv = cmdLine.split(" *"); + argv = cmdLine.split(" "); else argv = new String[0]; int loLibMain = dlsym(loLib, "lo_main"); |