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

Reply via email to