android/Bootstrap/src/org/libreoffice/android/Bootstrap.java | 6 android/experimental/DocumentLoader/Makefile | 7 sal/android/lo-bootstrap.c | 208 +++++++++++ 3 files changed, 216 insertions(+), 5 deletions(-)
New commits: commit d31e409ec1eb3e5ea81ec2a2288a046cf1e395a1 Author: Tor Lillqvist <tlillqv...@suse.com> Date: Wed May 16 09:56:29 2012 +0300 Update library list Change-Id: I9c652fc6940bd856aa8ba5f7e2daaae6a5502b3d diff --git a/android/experimental/DocumentLoader/Makefile b/android/experimental/DocumentLoader/Makefile index b81c0b5..3c513ec 100644 --- a/android/experimental/DocumentLoader/Makefile +++ b/android/experimental/DocumentLoader/Makefile @@ -48,7 +48,6 @@ copy-stuff: basebmplo \ basegfxlo \ bootstrap.uno \ - cdrimportlo \ comphelpgcc3 \ datelo \ dbaxmllo \ @@ -84,7 +83,6 @@ copy-stuff: mergedlo \ msfilterlo \ mswordlo \ - msworkslo \ ooxlo \ reflection.uno \ reg \ @@ -116,10 +114,9 @@ copy-stuff: utllo \ vbahelperlo \ vbaswobj.uno \ + wpftdrawlo \ + wpftwriterlo \ vcllo \ - visioimportlo \ - wpftlo \ - wpgimportlo \ xml2 \ xmlfdlo \ xmlreader \ commit 182c1e4f99d7d3ae73cafdae02573ca29b6639cc Author: Tor Lillqvist <tlillqv...@suse.com> Date: Wed May 16 09:55:48 2012 +0300 Call lo-bootstrap's redirect_stdio Change-Id: I45732ac81d00837ce517ed5c527c8c767e690abf diff --git a/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java index b562da8..82a40b7 100644 --- a/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java +++ b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java @@ -101,6 +101,10 @@ public class Bootstrap extends NativeActivity // (contentbroker.cxx), also this called indirectly through the lo-bootstrap library public static native void initUCBHelper(); + // A method that starts a thread to redirect stdout and stderr writes to + // the Android logging mechanism, or stops the redirection. + public static native boolean redirect_stdio(boolean state); + // This setup() method is called 1) in apps that use *this* class as their activity from onCreate(), // and 2) should be called from other kinds of LO code using apps. public static void setup(Activity activity) @@ -111,6 +115,8 @@ public class Bootstrap extends NativeActivity dataDir = ai.dataDir; Log.i(TAG, String.format("dataDir=%s\n", dataDir)); + redirect_stdio(true); + String llp = System.getenv("LD_LIBRARY_PATH"); if (llp == null) llp = "/vendor/lib:/system/lib"; commit c53c665de33d931e5d3a6ad767240fc83ac8bd69 Author: Tor Lillqvist <tlillqv...@suse.com> Date: Wed May 16 09:50:52 2012 +0300 Add stdout and stderr redirection to the Android log On a (non-rooted) device it is not possible to set the log.redirect-stdio property so that it would be effective (i.e. read by the Zygote process when it starts). Such redirection has to be done in-process. Add a (JNI-callable) method to set it up: Point file descriptors 1 and 2 at pipes that are read by a thread that logs each line through the Android logging API. Code based on Android's own logwrapper.c. Change-Id: Id5308293595096a44a2ffed2dbc0c252be109de7 diff --git a/sal/android/lo-bootstrap.c b/sal/android/lo-bootstrap.c index 75a3898..f3ba3bb 100644 --- a/sal/android/lo-bootstrap.c +++ b/sal/android/lo-bootstrap.c @@ -67,6 +67,8 @@ #define ROUND_DOWN(ptr,multiple) (void *)(((unsigned) (ptr)) & ~((multiple)-1)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + struct engine { int dummy; }; @@ -1631,6 +1633,212 @@ Java_org_libreoffice_android_Bootstrap_initUCBHelper(JNIEnv* env, (*InitUCBHelper)(); } +/* Code for reading lines from the pipe based on the (Apache-licensed) Android + * logwrapper.c + */ + +static int +read_from(int fd, const char *tag, char *buffer, int *sz, int *a, int *b, size_t sizeof_buffer) +{ + int nread; + + nread = read(fd, buffer+*b, sizeof_buffer - 1 - *b); + *sz = nread; + + if (nread == -1) { + LOGE("redirect_thread: Reading from %d failed: %s", fd, strerror(errno)); + close(fd); + return -1; + } + + if (nread == 0) { + LOGI("redirect_thread: EOF from fd %d", fd); + close(fd); + return 0; + } + + *sz += *b; + + for (*b = 0; *b < *sz; (*b)++) { + if (buffer[*b] == '\n') { + buffer[*b] = '\0'; + __android_log_print(ANDROID_LOG_INFO, tag, "%s", &buffer[*a]); + *a = *b + 1; + } + } + + if (*a == 0 && *b == (int) sizeof_buffer - 1) { + // buffer is full, flush + buffer[*b] = '\0'; + __android_log_print(ANDROID_LOG_INFO, tag, "%s", &buffer[*a]); + *b = 0; + } else if (*a != *b) { + // Keep left-overs + *b -= *a; + memmove(buffer, &buffer[*a], *b); + *a = 0; + } else { + *a = 0; + *b = 0; + } + + return nread; +} + +static int stdout_pipe[2], stderr_pipe[2]; + +static void * +redirect_thread(void *arg) +{ + char buffer[2][4096]; + int a[2] = { 0, 0 }; + int b[2] = { 0, 0 }; + int sz[2]; + + (void) arg; + + while (1) { + fd_set readfds; + int nfds = 0; + + FD_ZERO(&readfds); + if (stdout_pipe[0] != -1) { + FD_SET(stdout_pipe[0], &readfds); + nfds = MAX(nfds, stdout_pipe[0] + 1); + } + if (stderr_pipe[0] != -1) { + FD_SET(stderr_pipe[0], &readfds); + nfds = MAX(nfds, stderr_pipe[0] + 1); + } + if (nfds == 0) { + LOGI("redirect_thread: Nothing to read any more, thread exiting"); + return NULL; + } + + if (select(nfds, &readfds, NULL, NULL, NULL) == -1) { + LOGE("redirect_thread: select failed: %s, thread exiting", strerror(errno)); + close(stdout_pipe[0]); + stdout_pipe[0] = -1; + close(stderr_pipe[0]); + stderr_pipe[0] = -1; + return NULL; + } + + if (stdout_pipe[0] != -1 && + FD_ISSET(stdout_pipe[0], &readfds)) { + if (read_from(stdout_pipe[0], "stdout", buffer[0], &sz[0], &a[0], &b[0], sizeof(buffer[0])) <= 0) { + stdout_pipe[0] = -1; + } + } + + if (stderr_pipe[0] != -1 && + FD_ISSET(stderr_pipe[0], &readfds)) { + if (read_from(stderr_pipe[0], "stderr", buffer[1], &sz[1], &a[1], &b[1], sizeof(buffer[1])) <= 0) { + stderr_pipe[0] = -1; + } + } + } +} + +static int +redirect_to_null(void) +{ + int null = open("/dev/null", O_WRONLY); + if (null == -1) { + LOGE("redirect_stdio: Could not open /dev/null: %s", strerror(errno)); + /* If we can't redirect stdout or stderr to /dev/null, just close them + * then instead. Huh? + */ + close(1); + close(2); + return 0; + } + if (dup2(null, 1) == -1) { + LOGE("redirect_stdio: Could not dup2 %d to 1: %s", null, strerror(errno)); + close(null); + close(1); + close(2); + return 0; + } + if (dup2(null, 2) == -1) { + LOGE("redirect_stdio: Could not dup2 %d to 2: %s", null, strerror(errno)); + close(null); + close(1); + close(2); + return 0; + } + close(null); + return 1; +} + +__attribute__ ((visibility("default"))) +jboolean +Java_org_libreoffice_android_Bootstrap_redirect_1stdio(JNIEnv* env, + jobject clazz, + jboolean state) +{ + static jboolean current = JNI_FALSE; + pthread_t thread; + + (void) env; + (void) clazz; + + if (state == current) + return current; + + if (state == JNI_FALSE) { + if (!redirect_to_null()) + return current; + } else { + if (pipe(stdout_pipe) == -1) { + LOGE("redirect_stdio: Could not create pipes: %s", strerror(errno)); + return current; + } + if (pipe(stderr_pipe) == -1) { + LOGE("redirect_stdio: Could not create pipes: %s", strerror(errno)); + close(stdout_pipe[0]); + close(stdout_pipe[1]); + return current; + } + LOGI("redirect_stdio: stdout pipe: [%d,%d], stderr pipe: [%d,%d]", + stdout_pipe[0], stdout_pipe[1], stderr_pipe[0], stderr_pipe[1]); + + if (dup2(stdout_pipe[1], 1) == -1) { + LOGE("redirect_stdio: Could not dup2 %d to 1: %s", stdout_pipe[1], strerror(errno)); + close(stdout_pipe[0]); + close(stdout_pipe[1]); + close(stderr_pipe[0]); + close(stderr_pipe[1]); + return current; + } + + if (dup2(stderr_pipe[1], 2) == -1) { + LOGE("redirect_stdio: Could not dup2 %d to 2: %s", stdout_pipe[1], strerror(errno)); + /* stdout has already been redirected to its pipe, so redirect + * it back to /dev/null + */ + redirect_to_null(); + close(stdout_pipe[0]); + close(stdout_pipe[1]); + close(stderr_pipe[0]); + close(stderr_pipe[1]); + return current; + } + close(stdout_pipe[1]); + close(stderr_pipe[1]); + + if (pthread_create(&thread, NULL, redirect_thread, NULL) != 0) { + LOGE("redirect_stdio: Could not create thread: %s", strerror(errno)); + redirect_to_null(); + close(stdout_pipe[0]); + close(stderr_pipe[0]); + return current; + } + } + current = state; + return current; +} + __attribute__ ((visibility("default"))) JavaVM * lo_get_javavm(void) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits