summaryrefslogtreecommitdiff
path: root/README.Android
blob: be1d765d734a2326617dd80e96e78a85e241dd00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
Android-specific notes

* Getting something running

	Create an AVD in the android UI, don't even try to get
the data partition size right in the GUI, that is doomed to producing
and AVD that doesn't work. Instead start it from the console:

	emulator-arm -avd <Name> -partition-size 500

	Where <Name> is the literal name of the AVD that you entered.
Then it is necessary to get stdout/err to go to somewhere we can find it:

	adb shell stop; adb shell setprop log.redirect-stdio true; adb shell start

	Then:

	make cmd cmd=bash
	cd android/qa/sc
	make clean all install
	make run ; adb shell logcat

	And if all goes well - you should have some nice unit
test output to enjoy. After a while of this loop you'll probably
find that android has lost a lot of space on your device at
this point:

	adb shell stop; adb shell setprop log.redirect-stdio true; adb shell start

	and continue onwards & upwards.

* Debugging

	Debugging is fun, the default NDK gdb (in v7) is busted, you
need to download a new one from:

	http://code.google.com/p/mingw-and-ndk/

	Even this 'fixed' gdb is broken in the way that it can see
symbols only for shlibs that were already loaded when the debuggee was
attached, so you need to carefully guess where to put:

	fprintf(stderr, "Sleeping NOW!\n"); ::sleep(20);

	into the code; and when you see that in logcat, you have time
to run: ndk-gdb and it will attach the process.

	thread 12 # or perhaps 13
	backtrace

	may show you the native code trace.

* Common Errors / Gotchas

lo_dlneeds: Could not read ELF header of /data/data/org.libreoffice...libfoo.so
	This (most likely) means that the install quietly failed, and that
the file is truncated; check it out with adb shell ls -l /data/data/....


* Detailed explanation

Unit tests are the first thing we want to run on Android, to get some
idea how well, if at all, the basic LO libraraies work. We want to
build even unit tests as normal Android apps, i.e. packaged as .apk
files, so that they run in a sandboxed environment like that of
whatever eventual end-user Android apps there will be that use LO
code.

Sure, we could quite easily build unit tests as plain Linux
executables (built against the Android libraries, of course, not
GNU/Linux ones), push them to the device or emulator with adb and run
them from adb shell, but that would not be a good test as the
environment such processs run in is completely different from that in
which real end-user apps with GUI etc run. We have no intent to
require LibreOffice code to be used only on "rooted" devices etc.

All Android apps are basically Java programs. They run "in" a Dalvik
virtual machine. Yes, you can also have apps where *your* code is only
native code, written in a compiled language like C or C++. But also
also such apps are actually started by system-provided Java
bootstrapping code (NativeActivity) running in a Dalvik VM.

Such a native app (or actually, "activity") is not built as a
executable program, but as a shared object. The Java NativeActivity
bootstrapper loads that shared object with dlopen.

It is somewhat problematic to construct .apk packages except by using
the high-level tools in the Android SDK. At least I haven't figured
out how to manually construct an .apk that is properly signed so that
it will run in the emulator. (I don't have any Android device...) I
only know how to let the SDK Ant tooling do it...

At this stage, the plan is that a LO Android app will work would
something like this:

We have a Java class org.libreoffice.android.Bootstrap that that loads
a small helper native library liblo-bootstrap.so that implements JNI
wrappers for dlopen(), dlsym(), and ELF header scanning coresponding
to looking for DT_NEEDED entries with readelf.

The Java code then loads the actual native library that corresponds to
the LibreOffice-related "program" we want to run. For unit tests, a
library that corresponds to cppunittester program. Then through helper
functions in liblo-bootstrap it calls a named function in that
"program".

This Android-specific native code (the lo-bootstrap library) is for
now in sal/android, and the Java code in the android "module"
(subdirectory right here).