summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorTor Lillqvist <tlillqvist@suse.com>2011-11-30 21:39:18 +0200
committerTor Lillqvist <tlillqvist@suse.com>2011-11-30 21:52:52 +0200
commit5510127e89d6971a219ce3664e4631d6c6dda2b1 (patch)
tree7e2d7d06892e086700d5b6bddc8a3ec99c476f6b /android
parenta7fe1a0a088b2d3d68e3fc4b0d3e8d5a34f3e203 (diff)
Android code refactorig and hacking
Sorry for the large unstructured commit. But hey, the Android code is experimental so far. Extract the native lo-bootstrap code into a fairly normal library built in sal. (Previously it was the JNI part of the "Bootstrap" app.) Just linkink normally to liblo-bootstrap from C++ code that uses it works fine, no need to do a dlsym lookup. Bootstrap is still a subclass of NativeActivity and can thus still be used as an "app" (to start unit tests, or whatever), but can also be used from some other app's Java code to just get access to the lo-bootstrap native methods. Introduce a new top-level "module", android, for Bootstrap and the experiments with DocumentLoader. Note that the experimental DocumentLoader app still crashes. It can't create the com.sun.star.frame.Desktop instance. I spent lots of time debugging in the painfully inadequate ndk-gdb. (Even the newer gdb build from the "mingw-and-ndk" project is quite crappy in many ways.) I should really experiment with corresponding code on a normal platform first before even trying on Android. Basically, I think that if I just can get the concept of Java code that instantiates and uses LO components *in-process* working on a normal desktop platform, it should work on Android, too.
Diffstat (limited to 'android')
-rw-r--r--android/Bootstrap/.gitignore6
-rw-r--r--android/Bootstrap/AndroidManifest.xml24
-rw-r--r--android/Bootstrap/Makefile129
-rw-r--r--android/Bootstrap/ant.properties17
-rw-r--r--android/Bootstrap/build.xml114
-rw-r--r--android/Bootstrap/project.properties11
-rw-r--r--android/Bootstrap/res/layout/main.xml12
-rw-r--r--android/Bootstrap/res/values/strings.xml4
-rw-r--r--android/Bootstrap/src/fi/iki/tml/CommandLine.java176
-rw-r--r--android/Bootstrap/src/org/libreoffice/android/Bootstrap.java172
-rw-r--r--android/experiments/DocumentLoader/AndroidManifest.xml (renamed from android/examples/DocumentLoader/AndroidManifest.xml)0
-rw-r--r--android/experiments/DocumentLoader/Makefile120
-rw-r--r--android/experiments/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java (renamed from android/examples/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java)38
13 files changed, 812 insertions, 11 deletions
diff --git a/android/Bootstrap/.gitignore b/android/Bootstrap/.gitignore
new file mode 100644
index 000000000000..9034b9895557
--- /dev/null
+++ b/android/Bootstrap/.gitignore
@@ -0,0 +1,6 @@
+assets
+bin
+gen
+libs
+obj
+local.properties \ No newline at end of file
diff --git a/android/Bootstrap/AndroidManifest.xml b/android/Bootstrap/AndroidManifest.xml
new file mode 100644
index 000000000000..159bbf105d75
--- /dev/null
+++ b/android/Bootstrap/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.libreoffice.android"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="9" />
+ <!-- This .apk uses a subclass of NativeActivity, so it *has* Java code. -->
+ <!-- android:hasCode="false" -->
+ <application android:label="@string/app_name"
+ android:debuggable="true">
+ <!-- <activity android:name="android.app.NativeActivity" -->
+ <activity android:name=".Bootstrap"
+ android:label="LibreOffice Bootstrap"
+ android:configChanges="orientation|keyboardHidden">
+ <!-- Tell NativeActivity the name of our .so -->
+ <meta-data android:name="android.app.lib_name"
+ android:value="lo-bootstrap" />
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/android/Bootstrap/Makefile b/android/Bootstrap/Makefile
new file mode 100644
index 000000000000..d8a7004579c7
--- /dev/null
+++ b/android/Bootstrap/Makefile
@@ -0,0 +1,129 @@
+# The full path the the app's directory needs to be supplied in a
+# couple of places, unfortunately.
+
+APP_DATA_PATH=/data/data/org.libreoffice.android
+
+NDK_HOME:=$(shell type -p ndk-build)
+NDK_HOME:=$(shell dirname $(NDK_HOME))
+
+SODEST=libs/armeabi-v7a
+OBJLOCAL=obj/local/armeabi-v7a
+
+define COPY
+cp $(1) $(SODEST)$(if $(2),/$(2)) && \
+arm-linux-androideabi-strip --strip-debug $(SODEST)$(if $(2),/$(2),/$(notdir $(1))) && \
+cp $(1) $(OBJLOCAL)$(if $(2),/$(2))
+endef
+
+# The default target just builds.
+
+all: build-ant lo-bootstrap.jar
+
+copy-stuff:
+#
+# Copy shared libraries we need to libs/armeabi-v7a so that ant will
+# include them in the .apk.
+#
+# Copy them to obj/local/armeabi-v7a, too, where gdb will look for
+# them.
+#
+ mkdir -p $(SODEST) $(OBJLOCAL)
+#
+# First the most important one, liblo-bootstrap.so
+ $(call COPY,$(OUTDIR)/lib/liblo-bootstrap.so)
+#
+# Then the cppunittester "program". As all "program"
+# files we build for Android actually is a shared object.
+ $(call COPY,$(OUTDIR)/bin/cppunit/cppunittester,libcppunittester.so)
+#
+# The cppunit library
+ $(call COPY,$(OUTDIR)/lib/libcppunit-1.12.so)
+#
+# cppunit "plug-ins", first ones from sal
+#
+ $(call COPY,../../sal/$(INPATH)/lib/*.so)
+#
+# and ones from other modules. Note that depending on when you try
+# this, these might not have been built yet.
+#
+ for F in $(SRC_ROOT)/cppu/$(INPATH)/lib/qa_*.so; do \
+ $(call COPY,$${F},`basename $${F}`); \
+ done
+#
+ for F in i18npool_test_breakiterator; do \
+ $(call COPY,$(WORKDIR)/LinkTarget/CppunitTest/libtest_$${F}.so); \
+ done
+#
+# Other "programs"
+ $(call COPY,$(OUTDIR)/bin/uno,libunoexe.so)
+#
+# Libs and UNO components that the tests from other modules need.
+#
+ for F in $(strip \
+ comphelpgcc3 \
+ gcc3_uno \
+ i18nisolang1gcc3 \
+ i18nutilgcc3 \
+ icudatalo \
+ icui18nlo \
+ icuuclo \
+ localedata_en \
+ localedata_others \
+ reg \
+ store \
+ ucbhelper4gcc3 \
+ uno_cppu \
+ uno_salhelpergcc3 \
+ uno_cppuhelpergcc3 \
+ unoexceptionprotector \
+ xml2 \
+ xmlreader \
+ bootstrap.uno \
+ i18npool.uno); do \
+ $(call COPY,$(OUTDIR)/lib/lib$${F}.so); \
+ done
+#
+# Then the shared GNU C++ library
+ $(call COPY,$(NDK_HOME)/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/libgnustl_shared.so)
+#
+# bridgetest components, not in solver
+ for F in bridgetest constructors cppobj; do \
+ $(call COPY,$(SRC_ROOT)/testtools/$(INPATH)/lib/lib$${F}.uno.so); \
+ done
+#
+# Then other "assets". Let the directory structure under assets mimic
+# that under solver for now.
+ mkdir -p assets/bin assets/lib assets/xml/ure assets/ComponentTarget/i18npool/util
+ cp $(OUTDIR)/bin/udkapi.rdb assets/bin
+ cp $(OUTDIR)/bin/types.rdb assets/bin
+ cp $(OUTDIR)/xml/ure/services.rdb assets/xml/ure
+ cp $(WORKDIR)/ComponentTarget/i18npool/util/i18npool.component assets/ComponentTarget/i18npool/util
+ for F in uno_services uno_types; do \
+ sed -e 's!uri="./!uri="$(APP_DATA_PATH)/lib/!g' <$(SRC_ROOT)/testtools/$(INPATH)/lib/$${F}.rdb >assets/lib/$${F}.rdb; \
+ done
+
+build-ant: copy-stuff
+ unset JAVA_HOME && ant debug
+
+lo-bootstrap.jar: build-ant
+ cd bin/classes && jar cvf ../../lo-bootstrap.jar fi/iki/tml org/libreoffice/android/Bootstrap.class
+
+install: copy-stuff lo-bootstrap.jar
+ cp lo-bootstrap.jar $(OUTDIR)bin
+ unset JAVA_HOME && ant debug install
+ @echo
+ @echo 'Run it with something like what "make run" does (see Makefile)'
+ @echo
+
+run:
+# Note: these are just examples.
+#
+ adb shell am start -n org.libreoffice.android/.Bootstrap -e lo-main-library libcppunittester -e lo-main-cmdline "$(APP_DATA_PATH)/lib/libqa_sal_types.so"
+#
+ sleep 10
+ adb shell am start -n org.libreoffice.android/.Bootstrap -e lo-main-library libcppunittester -e lo-main-cmdline "$(APP_DATA_PATH)/lib/libtest_i18npool_test_breakiterator.so --protector libunoexceptionprotector.so unoexceptionprotector '-env:UNO_TYPES=file:///assets/bin/udkapi.rdb file:///assets/bin/types.rdb' '-env:UNO_SERVICES=file:///assets/xml/ure/services.rdb file:///assets/ComponentTarget/i18npool/util/i18npool.component' -env:LO_LIB_DIR=file://$(APP_DATA_PATH)/lib"
+#
+# adb shell am start -n org.libreoffice.android/.Bootstrap -e lo-main-library libunoexe -e lo-main-cmdline "-ro /assets/lib/uno_services.rdb -ro /assets/lib/uno_types.rdb -s com.sun.star.test.bridge.BridgeTest -- com.sun.star.test.bridge.CppTestObject" -e lo-main-delay 2
+
+clean:
+ rm -rf bin assets
diff --git a/android/Bootstrap/ant.properties b/android/Bootstrap/ant.properties
new file mode 100644
index 000000000000..ee52d86d94a4
--- /dev/null
+++ b/android/Bootstrap/ant.properties
@@ -0,0 +1,17 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked in Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
diff --git a/android/Bootstrap/build.xml b/android/Bootstrap/build.xml
new file mode 100644
index 000000000000..6b091c49c2bd
--- /dev/null
+++ b/android/Bootstrap/build.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="LibreOfficeBootstrap" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <loadproperties srcFile="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'"
+ unless="sdk.dir"
+ />
+
+
+<!-- extension targets. Uncomment the ones where you want to do custom work
+ in between standard targets -->
+<!--
+ <target name="-pre-build">
+ </target>
+ <target name="-pre-compile">
+ </target>
+
+ /* This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir} */
+ <target name="-post-compile">
+ </target>
+-->
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+ <!-- Re-define the "-package-resources" target to not compress resources -->
+
+ <target name="-package-resources" depends="-crunch">
+ <!-- only package resources if *not* a library project -->
+ <do-only-if-not-library elseText="Library project: do not package resources..." >
+ <aapt executable="${aapt}"
+ command="package"
+ versioncode="${version.code}"
+ versionname="${version.name}"
+ debug="${build.is.packaging.debug}"
+ manifest="AndroidManifest.xml"
+ assets="${asset.absolute.dir}"
+ androidjar="${android.jar}"
+ apkfolder="${out.absolute.dir}"
+ nocrunch="${build.packaging.nocrunch}"
+ resourcefilename="${resource.package.file.name}"
+ resourcefilter="${aapt.resource.filter}"
+ projectLibrariesResName="project.libraries.res"
+ projectLibrariesPackageName="project.libraries.package"
+ previousBuildType="${build.last.target}"
+ buildType="${build.target}">
+ <res path="${out.res.absolute.dir}" />
+ <res path="${resource.absolute.dir}" />
+ <nocompress /> <!-- forces no compression on any files in assets or res/raw -->
+ <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw -->
+ </aapt>
+ </do-only-if-not-library>
+ </target>
+
+</project>
diff --git a/android/Bootstrap/project.properties b/android/Bootstrap/project.properties
new file mode 100644
index 000000000000..730e911f2f9e
--- /dev/null
+++ b/android/Bootstrap/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-14
diff --git a/android/Bootstrap/res/layout/main.xml b/android/Bootstrap/res/layout/main.xml
new file mode 100644
index 000000000000..5839d8cda704
--- /dev/null
+++ b/android/Bootstrap/res/layout/main.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+<TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello World"
+ />
+</LinearLayout>
diff --git a/android/Bootstrap/res/values/strings.xml b/android/Bootstrap/res/values/strings.xml
new file mode 100644
index 000000000000..f296dd4b137d
--- /dev/null
+++ b/android/Bootstrap/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">LibreOfficeBootstrap</string>
+</resources>
diff --git a/android/Bootstrap/src/fi/iki/tml/CommandLine.java b/android/Bootstrap/src/fi/iki/tml/CommandLine.java
new file mode 100644
index 000000000000..fb5adec2acf5
--- /dev/null
+++ b/android/Bootstrap/src/fi/iki/tml/CommandLine.java
@@ -0,0 +1,176 @@
+// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+
+// Copyright (C) 2011 Tor Lillqvist <tml@iki.fi>
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+package fi.iki.tml;
+
+import java.util.*;
+
+public class CommandLine
+ implements Iterable<String>
+{
+ private String commandLine;
+
+ public class Tokenizer
+ implements Iterator<String>
+ {
+ private int index = 0;
+ private String savedNext = null;
+
+ public Tokenizer()
+ {
+ }
+
+ public boolean hasNext()
+ {
+ if (savedNext != null)
+ return true;
+ try {
+ savedNext = next();
+ return true;
+ }
+ catch (NoSuchElementException e) {
+ }
+ return false;
+ }
+
+ public String next()
+ {
+ if (savedNext != null) {
+ String result = savedNext;
+ savedNext = null;
+ return result;
+ }
+
+ StringBuffer sb = new StringBuffer(commandLine.length());
+
+ while (index < commandLine.length() &&
+ commandLine.charAt(index) == ' ')
+ index++;
+
+ if (index == commandLine.length())
+ throw new NoSuchElementException();
+
+ while (index < commandLine.length() &&
+ commandLine.charAt(index) != ' ') {
+ char c = commandLine.charAt(index);
+ if (c == '\'') {
+ index++;
+ while (index < commandLine.length() &&
+ commandLine.charAt(index) != '\'') {
+ sb.append(commandLine.charAt(index));
+ index++;
+ }
+ } else if (c == '"') {
+ index++;
+ while (index < commandLine.length() &&
+ commandLine.charAt(index) != '\"') {
+ if (commandLine.charAt(index) == '\\') {
+ index++;
+ if (index < commandLine.length())
+ sb.append(commandLine.charAt(index));
+ } else {
+ sb.append(commandLine.charAt(index));
+ }
+ index++;
+ }
+ } else if (c == '\\') {
+ index++;
+ if (index < commandLine.length())
+ sb.append(commandLine.charAt(index));
+ } else {
+ sb.append(c);
+ }
+ index++;
+ }
+ return sb.toString();
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public Iterator<String> iterator()
+ {
+ return new Tokenizer();
+ }
+
+ public CommandLine(String commandLine)
+ {
+ this.commandLine = commandLine;
+ }
+
+ public String[] split()
+ {
+ ArrayList<String> argv = new ArrayList<String>(10);
+
+ try {
+ for (String s : this)
+ argv.add(s);
+ }
+ catch (NoSuchElementException e) {
+ }
+
+ return argv.toArray(new String[0]);
+ }
+
+ public static String[] split(String commandLine)
+ {
+ return new CommandLine(commandLine).split();
+ }
+
+ public static void main(String[] args)
+ {
+ class Test
+ {
+ Test(String commandLine)
+ {
+ String[] argv = split(commandLine);
+ System.out.println("Split of " + commandLine + ":");
+ int n = 0;
+ for (String s : argv) {
+ System.out.println("argv[" + n + "}: length " + s.length() + ": \"" + s + "\"");
+ n++;
+ }
+ }
+ }
+
+ new Test("");
+ new Test(" ");
+ new Test(" ");
+ new Test(" '' ");
+ new Test("abc def");
+ new Test("abc '' def");
+ new Test("abc \"\" def");
+ new Test(" abc def ");
+ new Test(" abc def ");
+ new Test("abc\" \"def");
+ new Test("abc\" \"def \"gh\\i\\\" jkl\"");
+ new Test("abc' def' '\\ghi jkl'");
+ }
+}
+
+// vim:set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
new file mode 100644
index 000000000000..46ce235d3ad4
--- /dev/null
+++ b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
@@ -0,0 +1,172 @@
+// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+
+// Version: MPL 1.1 / GPLv3+ / LGPLv3+
+//
+// The contents of this file are subject to the Mozilla Public License Version
+// 1.1 (the "License"); you may not use this file except in compliance with
+// the License or as specified alternatively below. You may obtain a copy of
+// the License at http://www.mozilla.org/MPL/
+//
+// Software distributed under the License is distributed on an "AS IS" basis,
+// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+// for the specific language governing rights and limitations under the
+// License.
+//
+// Major Contributor(s):
+// Copyright (C) 2011 Tor Lillqvist <tml@iki.fi> (initial developer)
+// Copyright (C) 2011 SUSE Linux http://suse.com (initial developer's employer)
+//
+// All Rights Reserved.
+//
+// For minor contributions see the git repository.
+//
+// Alternatively, the contents of this file may be used under the terms of
+// either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+// the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+// in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+// instead of those above.
+
+package org.libreoffice.android;
+
+import android.app.Activity;
+import android.app.NativeActivity;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.Log;
+
+import fi.iki.tml.CommandLine;
+
+// We override NativeActivity so that we can get at the intent of the
+// activity and its extra parameters, that we use to tell us what
+// actual LibreOffice "program" to run. I.e. something that on desktop
+// OSes would be a program, but for Androis is actually built as a
+// shared object, with an "lo_main" function.
+
+public class Bootstrap extends NativeActivity
+{
+ private static String TAG = "lo-bootstrap";
+
+ private static native boolean setup(String dataDir,
+ String apkFile,
+ String[] ld_library_path);
+
+ public static native boolean setup(int lo_main_ptr,
+ Object lo_main_argument,
+ int lo_main_delay);
+
+ // This is not just a wrapper for the C library dlopen(), but also
+ // loads recursively dependent libraries.
+ public static native int dlopen(String library);
+
+ // This is just a wrapper for the C library dlsym().
+ public static native int dlsym(int handle, String symbol);
+
+ // To be called after you are sure libgnustl_shared.so
+ // has been loaded
+ public static native void patch_libgnustl_shared();
+
+ // Wrapper for getpid()
+ public static native int getpid();
+
+ // Wrapper for system()
+ public static native void system(String cmdline);
+
+ // Wrapper for putenv()
+ public static native void putenv(String string);
+
+ public static void setup(Activity activity)
+ {
+ String dataDir = null;
+
+ ApplicationInfo ai = activity.getApplicationInfo();
+ dataDir = ai.dataDir;
+ Log.i(TAG, String.format("dataDir=%s\n", dataDir));
+
+ String llp = System.getenv("LD_LIBRARY_PATH");
+ if (llp == null)
+ llp = "/vendor/lib:/system/lib";
+
+ String[] llpa = llp.split(":");
+
+ if (!setup(dataDir, activity.getApplication().getPackageResourcePath(), llpa))
+ return;
+
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ setup(this);
+
+ String mainLibrary = getIntent().getStringExtra("lo-main-library");
+
+ if (mainLibrary == null)
+ mainLibrary = "libcppunittester";
+
+ mainLibrary += ".so";
+
+ Log.i(TAG, String.format("mainLibrary=%s", mainLibrary));
+
+ // Get "command line" to pass to the LO "program"
+ String cmdLine = getIntent().getStringExtra("lo-main-cmdline");
+
+ if (cmdLine == null)
+ cmdLine = "/data/data/org.libreoffice.android/lib/libqa_sal_types.so";
+
+ // argv[0] will be replaced by android_main() in lo-bootstrap.c by the
+ // pathname of the mainLibrary.
+ cmdLine = "dummy-program-name " + cmdLine;
+
+ Log.i(TAG, String.format("cmdLine=%s", cmdLine));
+
+ String[] argv = CommandLine.split(cmdLine);
+
+ // Load the LO "program" here and look up lo_main
+ int loLib = dlopen(mainLibrary);
+
+ if (loLib == 0) {
+ Log.i(TAG, String.format("Could not load %s", mainLibrary));
+ return;
+ }
+
+ int lo_main = dlsym(loLib, "lo_main");
+ if (lo_main == 0) {
+ Log.i(TAG, String.format("No lo_main in %s", mainLibrary));
+ return;
+ }
+
+ // Tell lo-bootstrap to Start a strace on itself if requested
+ String strace_args = getIntent().getStringExtra("lo-strace");
+ if (strace_args != null)
+ system("/system/xbin/strace -p " + getpid() + " " + (strace_args != "yes" ? strace_args : "" ) + " &");
+
+ int delay = 0;
+ String sdelay = getIntent().getStringExtra("lo-main-delay");
+ if (sdelay != null)
+ delay = Integer.parseInt(sdelay);
+
+ // Tell lo-bootstrap.c the stuff it needs to know
+ if (!setup(lo_main, argv, delay))
+ return;
+
+ // Finally, call our super-class, NativeActivity's onCreate(),
+ // which eventually calls the ANativeActivity_onCreate() in
+ // android_native_app_glue.c, which starts a thread in which
+ // android_main() from lo-bootstrap.c is called.
+
+ // android_main() calls the lo_main() defined in sal/main.h
+ // through the function pointer passed to setup() above, with
+ // the argc and argv also saved from the setup() call.
+ super.onCreate(savedInstanceState);
+ }
+
+ // This is used to load the 'lo-bootstrap' library on application
+ // startup. The library has already been unpacked into
+ // /data/data/<app name>/lib/liblo-bootstrap.so at installation
+ // time by the package manager.
+ static {
+ System.loadLibrary("lo-bootstrap");
+ }
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/examples/DocumentLoader/AndroidManifest.xml b/android/experiments/DocumentLoader/AndroidManifest.xml
index c137311155d1..c137311155d1 100644
--- a/android/examples/DocumentLoader/AndroidManifest.xml
+++ b/android/experiments/DocumentLoader/AndroidManifest.xml
diff --git a/android/experiments/DocumentLoader/Makefile b/android/experiments/DocumentLoader/Makefile
new file mode 100644
index 000000000000..7db82ae1a43a
--- /dev/null
+++ b/android/experiments/DocumentLoader/Makefile
@@ -0,0 +1,120 @@
+NDK_HOME:=$(shell type -p ndk-build)
+NDK_HOME:=$(shell dirname $(NDK_HOME))
+
+SODEST=libs/armeabi-v7a
+OBJLOCAL=obj/local/armeabi-v7a
+
+define COPYSO
+cp $(1) $(SODEST)$(if $(2),/$(2)) && \
+arm-linux-androideabi-strip --strip-debug $(SODEST)$(if $(2),/$(2),/$(notdir $(1))) && \
+cp $(1) $(OBJLOCAL)$(if $(2),/$(2))
+endef
+
+define COPYJAR
+cp $(1) libs
+endef
+
+# The default target just builds.
+
+all: build-ant
+
+copy-stuff:
+# First always clean
+ rm -rf libs $(OBJLOCAL)
+ mkdir -p $(SODEST) $(OBJLOCAL)
+#
+# Copy jar files we need, and even construct one.
+#
+ for F in $(strip \
+ java_uno \
+ juh \
+ jurt \
+ ridl \
+ unoloader \
+ ); do \
+ $(call COPYJAR,$(OUTDIR)/bin/$${F}.jar); \
+ done
+#
+# lo-bootstrap.jar from ../../Bootstrap
+#
+ cp ../../Bootstrap/lo-bootstrap.jar libs
+#
+# com.sun.star.frame.XComponentLoader is not in any jar
+#
+ cd libs && \
+ LD_LIBRARY_PATH=$(OUTDIR_FOR_BUILD)/lib \
+ DYLD_LIBRARY_PATH=$(OUTDIR_FOR_BUILD)/lib \
+ $(OUTDIR_FOR_BUILD)/bin/javamaker -BUCR -nD \
+ $(OUTDIR)/bin/udkapi.rdb $(OUTDIR)/bin/offapi.rdb \
+ -Tcom.sun.star.frame.XComponentLoader && \
+ jar cvf more.jar com
+#
+# Copy shared libraries (including UNO components) we need to
+# libs/armeabi-v7a so that ant will include them in the .apk.
+#
+# Copy them to obj/local/armeabi-v7a, too, where gdb will look for
+# them.
+#
+ for F in $(strip \
+ comphelpgcc3 \
+ gcc3_uno \
+ i18nisolang1gcc3 \
+ i18nutilgcc3 \
+ icudatalo \
+ icui18nlo \
+ icuuclo \
+ java_uno \
+ juh \
+ juhx \
+ jvmaccessgcc3 \
+ lo-bootstrap \
+ localedata_en \
+ localedata_others \
+ reg \
+ sal_textenc \
+ store \
+ ucbhelper4gcc3 \
+ uno_cppu \
+ uno_sal \
+ uno_salhelpergcc3 \
+ uno_cppuhelpergcc3 \
+ xml2 \
+ xmlreader \
+ bootstrap.uno \
+ i18npool.uno \
+ ); do \
+ $(call COPYSO,$(OUTDIR)/lib/lib$${F}.so); \
+ done
+#
+# Then the shared GNU C++ library
+ $(call COPYSO,$(NDK_HOME)/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/libgnustl_shared.so)
+#
+# Then other "assets". Let the directory structure under assets mimic
+# that under solver for now.
+ mkdir -p assets/bin assets/lib assets/xml/ure assets/ComponentTarget/i18npool/util
+ cp $(OUTDIR)/bin/udkapi.rdb assets/bin
+ cp $(OUTDIR)/bin/types.rdb assets/bin
+ cp $(OUTDIR)/bin/uno.ini assets
+ cp $(OUTDIR)/xml/ure/services.rdb assets/xml/ure
+ cp $(SRC_ROOT)/odk/examples/java/DocumentHandling/test/test1.odt assets
+ cp $(WORKDIR)/ComponentTarget/i18npool/util/i18npool.component assets/ComponentTarget/i18npool/util
+#
+# Then gdbserver and gdb.setup so that we can debug with ndk-gdb.
+#
+ cp $(NDK_HOME)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/gdbserver $(SODEST)
+ echo set solib-search-path ./obj/local/armeabi-v7a >$(SODEST)/gdb.setup
+
+build-ant: copy-stuff
+ unset JAVA_HOME && ant debug
+
+install: copy-stuff
+ unset JAVA_HOME && ant debug install
+ @echo
+ @echo 'Run it with something like what "make run" does (see Makefile)'
+ @echo
+
+run: install
+ adb shell am start -n org.libreoffice.android.examples/.DocumentLoader -e input /assets/test1.odt
+
+clean:
+ rm -rf bin assets
diff --git a/android/examples/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java b/android/experiments/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java
index 41f69dd019b0..819cf82ccaba 100644
--- a/android/examples/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java
+++ b/android/experiments/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java
@@ -30,13 +30,7 @@ package org.libreoffice.android.examples;
import android.app.Activity;
import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.EditText;
+import android.util.Log;
import com.sun.star.uno.UnoRuntime;
@@ -45,6 +39,8 @@ import org.libreoffice.android.Bootstrap;
public class DocumentLoader
extends Activity {
+ private static String TAG = "DocumentLoader";
+
@Override
public void onCreate(Bundle savedInstanceState)
{
@@ -52,29 +48,49 @@ public class DocumentLoader
try {
- Thread.sleep(20000);
-
Bootstrap.setup(this);
Bootstrap.dlopen("libjuh.so");
+ // Load more shlibs here explicitly in advance because
+ // that makes debugging work better, sigh
+ Bootstrap.dlopen("libuno_cppu.so");
+ Bootstrap.dlopen("libuno_salhelpergcc3.so");
+ Bootstrap.dlopen("libuno_cppuhelpergcc3.so");
+ Bootstrap.dlopen("libbootstrap.uno.so");
+ Bootstrap.dlopen("libgcc3_uno.so");
+ Bootstrap.dlopen("libjava_uno.so");
+
+ Bootstrap.putenv("UNO_TYPES=file:///assets/bin/udkapi.rdb file:///assets/bin/types.rdb");
+ Bootstrap.putenv("UNO_SERVICES=file:///assets/xml/ure/services.rdb");
+ // Bootstrap.putenv("INIFILENAME=vnd.sun.star.pathname:/assets/uno.ini");
+
com.sun.star.uno.XComponentContext xContext = null;
xContext = com.sun.star.comp.helper.Bootstrap.defaultBootstrap_InitialComponentContext();
+ Log.i(TAG, "xContext is" + (xContext!=null ? " not" : "") + " null");
+
com.sun.star.lang.XMultiComponentFactory xMCF =
xContext.getServiceManager();
Object oDesktop = xMCF.createInstanceWithContext(
"com.sun.star.frame.Desktop", xContext);
+ Log.i(TAG, "oDesktop is" + (oDesktop!=null ? " not" : "") + " null");
+
com.sun.star.frame.XComponentLoader xCompLoader =
(com.sun.star.frame.XComponentLoader)
UnoRuntime.queryInterface(
com.sun.star.frame.XComponentLoader.class, oDesktop);
- // Getting the given starting directory
- String sUrl = "file:///assets/inputfile.doc";
+ Log.i(TAG, "xCompLoader is" + (xCompLoader!=null ? " not" : "") + " null");
+
+ String input = getIntent().getStringExtra("input");
+ if (input == null)
+ input = "/assets/test1.odt";
+
+ String sUrl = "file://" + input;
// Loading the wanted document
com.sun.star.beans.PropertyValue propertyValues[] =