[Libreoffice-commits] .: 3 commits - android/Bootstrap android/experimental sal/android

Tor Lillqvist tml at kemper.freedesktop.org
Wed May 16 00:18:42 PDT 2012


 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 <tlillqvist at 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 <tlillqvist at 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 <tlillqvist at 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)


More information about the Libreoffice-commits mailing list