Files
odfstudio/android
+26 c38a7db4c8 android-viewer translated using Weblate
Asturian currently translated at 100.0% (116 of 116 strings)

Change-Id: I8eb81db4571666e86dfac665fd082baaaa23704b

android-viewer translated using Weblate

Portuguese (Brazil) currently translated at 100.0% (116 of 116 strings)

Change-Id: I370de79d9016ec8f0be7d292d1e9abc4313fb2f9

android-viewer translated using Weblate

Portuguese (Brazil) currently translated at 100.0% (116 of 116 strings)

Change-Id: I05b62988c74079f6fbdcd5f9814484b9085ef19a

android-viewer translated using Weblate

Romanian currently translated at 2.5% (3 of 116 strings)

Change-Id: Ie4e439529b016aa3de7e30af632aa51e55231e51

Update translation files for android-viewer

Updated by "Remove blank strings" hook in Weblate.

Change-Id: I768a3ce6dcd914d5dcf9f3e6691badcb05413c53

android-viewer translated using Weblate

Romanian currently translated at 1.7% (2 of 116 strings)

Change-Id: Ic4b65e62594f6228710cf9b483d1feddf13f8bff

android-viewer translated using Weblate

Afrikaans currently translated at 100.0% (116 of 116 strings)

Change-Id: Ia8ac96ef22f1ba75238734b17833d515ba94132b

android-viewer translated using Weblate

Tagalog currently translated at 100.0% (116 of 116 strings)

Change-Id: I3a3b0c3765542509e1a8e4829d42ede0211df01f

android-viewer translated using Weblate

Georgian currently translated at 100.0% (116 of 116 strings)

Change-Id: Ib9d9af42b5d1826255e522125a8f7f2af0d6127b

android-viewer translated using Weblate

Hebrew currently translated at 100.0% (116 of 116 strings)

Change-Id: I55fba0974ace39f116824dc599d7805b387d8977

android-viewer translated using Weblate

Esperanto currently translated at 0.0% (0 of 116 strings)

Change-Id: I3d403b1e830248e30573956c0c44e1538f2b5ee1

android-viewer translated using Weblate

Interlingua currently translated at 75.8% (88 of 116 strings)

Change-Id: I4fd57416ecf460e45651fc73efef736d1431d318

android-viewer translated using Weblate

Interlingua currently translated at 75.8% (88 of 116 strings)

Change-Id: If057d610b14188ae0db7f3d20a5a914c56b81b0f

android-viewer translated using Weblate

Slovak currently translated at 100.0% (116 of 116 strings)

Change-Id: Ia913e5f4627a89904c77643382bfdf006c8e70b7

android-viewer translated using Weblate

Abkhazian currently translated at 0.0% (0 of 116 strings)

Change-Id: I239da92abf3a1ddbf5f788fd869b6682d20809c7

android-viewer translated using Weblate

Portuguese currently translated at 100.0% (116 of 116 strings)

Change-Id: I7d9b6b6a8e83a20571d7b2e35edd0f484065192a

android-viewer translated using Weblate

Hungarian currently translated at 100.0% (116 of 116 strings)

Change-Id: I216c938054bf5b5a62bc463599402b2e4f7d4508

android-viewer translated using Weblate

Indonesian currently translated at 100.0% (116 of 116 strings)

Change-Id: I540e30365ad7c6d46560ca75f2124b063b5f506a

android-viewer translated using Weblate

Nepali currently translated at 17.2% (20 of 116 strings)

Change-Id: I7f628a7f40979983d2ad3594fa2166dc8e90f158

android-viewer translated using Weblate

Greek currently translated at 100.0% (116 of 116 strings)

Change-Id: Ie670518955161245eef8f6f745b78e04e277d23b

android-viewer translated using Weblate

Ukrainian currently translated at 100.0% (116 of 116 strings)

Change-Id: I7a82e827afbfa19189c7b18c59447bba64e7cc87

android-viewer translated using Weblate

Lower Sorbian currently translated at 100.0% (116 of 116 strings)

Change-Id: I616b44866cfbe0715face315d2191fb9db38caa1

android-viewer translated using Weblate

Upper Sorbian currently translated at 100.0% (116 of 116 strings)

Change-Id: I1dc905bb16c4446a1716adfbfca982f4d3276e92

android-viewer translated using Weblate

Dutch currently translated at 100.0% (116 of 116 strings)

Change-Id: I2e47958f5cb7e1bc9e66335a0a7b5b877ff06f17

android-viewer translated using Weblate

Dutch currently translated at 100.0% (116 of 116 strings)

Change-Id: Ib1bb2f5fbe18bc840ea8cb615129d609f81e1bed

android-viewer translated using Weblate

Icelandic currently translated at 100.0% (116 of 116 strings)

Change-Id: I49f0c7513a29237aa764a76568104f29fd192f55

android-viewer translated using Weblate

Italian currently translated at 100.0% (116 of 116 strings)

Change-Id: I115c77a50a911cb7ecb9cba942b14cc7701543b7

android-viewer translated using Weblate

Asturian currently translated at 100.0% (116 of 116 strings)

Change-Id: Id6e6b4ab3b318e182b45f996421c954725d6860b

android-viewer translated using Weblate

Asturian currently translated at 100.0% (116 of 116 strings)

Change-Id: I994e707dfb5146546332a3b7027aedf07cc186b5

android-viewer translated using Weblate

Czech currently translated at 100.0% (116 of 116 strings)

Change-Id: I24f909c87b5c60ce65036064f39119ba8ef16e1a

android-viewer translated using Weblate

Slovenian currently translated at 100.0% (116 of 116 strings)

Change-Id: I9d5b6dd53f912b498d291e386bb7ea82d3ff8c74

android-viewer translated using Weblate

Japanese currently translated at 83.6% (97 of 116 strings)

Change-Id: Id84aca3465b0cfd47d3b973e57317447be10228d

android-viewer translated using Weblate

Japanese currently translated at 83.6% (97 of 116 strings)

Change-Id: Ied50226ceadc2e5f0ea25d68e902e39715582390

android-viewer translated using Weblate

Chinese (Traditional Han script) currently translated at 100.0% (116 of 116 strings)

Change-Id: Iedcab7dd5ec2860d4652e7b8bbea69d7b9e77dc1

android-viewer translated using Weblate

Finnish currently translated at 0.0% (0 of 116 strings)

Change-Id: I7bff03aa120b862a96d30d15e3ca88c5ac6b5508

android-viewer translated using Weblate

Basque currently translated at 100.0% (116 of 116 strings)

Change-Id: I2f90a91002ceb47798951f692598912c7b3e2870

android-viewer translated using Weblate

Polish currently translated at 100.0% (116 of 116 strings)

Change-Id: Ib6948225c9bd2b49b54780e28b7006b4b7e08cef

android-viewer translated using Weblate

Persian currently translated at 100.0% (116 of 116 strings)

Change-Id: I4cf681d3fc334245d8eb5831eb55438a40d805d8

android-viewer translated using Weblate

Portuguese (Brazil) currently translated at 100.0% (116 of 116 strings)

Change-Id: Ic7b2cab3e08137e3ed31d214b0dd8cecf8e02af1

android-viewer translated using Weblate

French currently translated at 100.0% (116 of 116 strings)

Change-Id: Ida71234c709a03e85a7ee06c19d496642194fd3c

android-viewer translated using Weblate

Punjabi currently translated at 95.6% (111 of 116 strings)

Change-Id: I941848df77f885572c8aa03774c4aba655256d2a

android-viewer translated using Weblate

Punjabi currently translated at 95.6% (111 of 116 strings)

Change-Id: I4778b279c99c6958ef94bd6f62f619f2de560945

android-viewer translated using Weblate

Kazakh currently translated at 0.0% (0 of 116 strings)

Change-Id: Icd73da37f57b52b229098a6292479b3c7138e19f

android-viewer translated using Weblate

Welsh currently translated at 100.0% (116 of 116 strings)

Change-Id: I5486455397fa466868c03db5c9284ff9e8c2bbd2

android-viewer translated using Weblate

Catalan currently translated at 100.0% (116 of 116 strings)

Change-Id: I6e113abdc3eef5137987d15c94f0fd167fb15ec9

android-viewer translated using Weblate

Catalan currently translated at 100.0% (116 of 116 strings)

Change-Id: I104c22a23bb49788a1f801aa55d6e592222d57e5

android-viewer translated using Weblate

Spanish currently translated at 100.0% (116 of 116 strings)

Change-Id: I4fd24e5f966c747043c3a83e185b2d62f467813b

android-viewer translated using Weblate

Galician currently translated at 100.0% (116 of 116 strings)

Change-Id: Ie572b7d48cb3221fbbc95bf939a0f013a81f6886

android-viewer translated using Weblate

Armenian currently translated at 100.0% (116 of 116 strings)

Change-Id: I44e44f2fd60e58af8e1ff7215710c4b4b47e62b2

android-viewer translated using Weblate

Turkish currently translated at 100.0% (116 of 116 strings)

Change-Id: Ic87d85a9269e8293d92c1c5272910a0536ac978b

android-viewer translated using Weblate

German currently translated at 100.0% (116 of 116 strings)

Change-Id: Ie7bf6ddd67fc69793cf9ed1ce2b00a84114e6c8b

android-viewer translated using Weblate

German currently translated at 100.0% (116 of 116 strings)

Change-Id: I1ea4c5c81e172c42938c51ffb875390052ea210d
Co-authored-by: A S Alam <amanpreet.alam@gmail.com>
Co-authored-by: Adam Rak <kitynska@gmail.com>
Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Aitor Salaberria <amento@ni.eus>
Co-authored-by: Andika Triwidada <andika@gmail.com>
Co-authored-by: Andy Flagg <libreoffice.tagalog@gmail.com>
Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Cheng-Chia Tseng <pswo10680@gmail.com>
Co-authored-by: Christian Kühl <kuehl.christian@googlemail.com>
Co-authored-by: Dimitris Spingos <dmtrs32@gmail.com>
Co-authored-by: Ekaterine Papava <papava.e@gtu.ge>
Co-authored-by: Elisabetta Manuele <lyzbetta@gmail.com>
Co-authored-by: Gábor Kelemen <gabor.kelemen.extern@allotropia.de>
Co-authored-by: Hossein <hossein@libreoffice.org>
Co-authored-by: Joan Montané <joan@montane.cat>
Co-authored-by: Martin Srebotnjak <miles@filmsi.net>
Co-authored-by: Michael Wolf <milupo@sorbzilla.de>
Co-authored-by: Miloiu Andrei <miloiuandrei@gmail.com>
Co-authored-by: Miloš Šrámek <msramek22@gmail.com>
Co-authored-by: Olivier Hallot <olivier.hallot@libreoffice.org>
Co-authored-by: Paul Roos <iNetRoos@gmail.com>
Co-authored-by: Rhoslyn Prys <post@meddal.com>
Co-authored-by: Stanislav Horáček <stanislav.horacek@gmail.com>
Co-authored-by: Sveinn í Felli <sv1@fellsnet.is>
Co-authored-by: Sérgio Marques <smarquespt@gmail.com>
Co-authored-by: Taichi Haradaguchi <aaaa@users.noreply.translations.documentfoundation.org>
Co-authored-by: Tigran Zargaryan <tigranflib@gmail.com>
Co-authored-by: Weblate <noreply@documentfoundation.org>
Co-authored-by: Xandru Martino Ruz <xandrumartino@softastur.org>
Co-authored-by: Xosé <xosecalvo@gmail.com>
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Co-authored-by: emism <softinterlingua@gmail.com>
Co-authored-by: kees538 <kees538@gmail.com>
Co-authored-by: sophie <gautier.sophie@gmail.com>
Co-authored-by: vpanter <Leo.Moons@proximus.be>
Co-authored-by: Євген Кондратюк <lachend@gmail.com>
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/ab/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/af/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/ast/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/ca/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/cs/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/cy/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/de/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/dsb/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/el/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/eo/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/es/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/eu/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/fa/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/fi/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/fr/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/gl/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/he/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/hsb/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/hu/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/hy/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/ia/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/id/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/is/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/it/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/ja/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/ka/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/kk/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/ne/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/nl/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/pa/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/pl/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/pt/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/pt_BR/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/ro/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/sk/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/sl/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/tl/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/tr/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/uk/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/zh_Hant/
Translation: android-viewer/android-strings
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183799
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2025-04-11 09:55:54 +02:00
..

LibreOffice for Android

Bootstrap

Contains common code for all projects on Android to bootstrap LibreOffice. In addition it is a home to LibreOfficeKit (LOK - see libreofficekit/README.md) JNI classes.

Stuff in Source Directory

LibreOffice Android application - the code is based on Fennec (Firefox for Android). It uses OpenGL ES 2 for rendering of the document tiles which are gathered from LibreOffice using LOK. The application contains the LibreOffice core in one shared library: liblo-native-code.so, which is bundled together with the application.

Architecture and Threading

The application implements editing support using 4 threads:

  1. The Android UI thread, we can't perform anything here that would take a considerable amount of time.
  2. An OpenGL thread which contains the OpenGL context and is responsible for drawing all layers (including tiles) to the screen.
  3. A thread (LOKitThread), that performs LibreOfficeKit calls, which may take more time to complete. In addition it also receives events from the soffice thread (see below) when the callback emits an event. Events are stored in a blocking queue (thread processes events in FCFS order, goes to sleep when no more event is available and awakens when there are events in the queue again).
  4. A native thread created by LibreOfficeKit (we call it the soffice thread), where LibreOffice itself runs. It receives calls from LOKitThread, and may emit callback events as necessary.

LOKitThread

LOKitThread (org.libreoffice.LOKitThread) communicates with LO via JNI (this can be done only for one thread) and processes events (defined in org.libreoffice.LOEvent) triggered from UI.

Application Overview

LibreOfficeMainActivity (org.libreoffice.LibreOfficeMainActivity) is the entry point of the application - everything starts up and tears down from here (onCreate, onResume, onPause, onStart, onStop, onDestroy).

Document View

From here on one of the most interesting pieces are the classes around document view, which includes listening to touch events, recalculating the viewport, tiled handling and rendering the layers to the document.

Viewport - the viewport is the currently visible part of the document. It is defined by view rectangle and zoom.

Layers - document view is rendered using many layers. Such layers are: document background, scroll handles, and also the document tiles.

Document View Classes

  • LayerView (org.mozilla.gecko.gfx.LayerView) is the document view of the application. It uses the SurfaceView (android.view.SurfaceView) as the main surface to draw on using OpenGL ES 2.

  • GLController (org.mozilla.gecko.gfx.GLController) - holder of the OpenGL context.

  • RenderControllerThread (org.mozilla.gecko.gfx.RenderControllerThread) executes the rendering requests through LayerRenderer.

  • LayerRenderer (org.mozilla.gecko.gfx.LayerRenderer) renders all the layers.

  • GeckoLayerClient (org.mozilla.gecko.gfx.GeckoLayerClient) is the middle man of the application, which connects all the bits together. It is the document view layer holder so the any management (including tiled rendering) usually go through this class. It listens to draw requests and viewport changes from PanZoomController (see "Touch events").

Touch Events, Scrolling and Zooming

The main class that handles the touch event, scrolling and zooming is JavaPanZoomController org.mozilla.gecko.gfx.JavaPanZoomController (implementation of PanZoomController interface). When the user performs a touch action, the document view needs to change, which means the viewport changes. JavaPanZoomController changes the viewport and signals the change through PanZoomTarget (org.mozilla.gecko.gfx.PanZoomTarget).

Tiled Rendering

Tiled rendering is a technique that splits the document to bitmaps of same size (typically 256x256) which are fetched on demand.

In the application the ComposedTileLayer (org.mozilla.gecko.gfx.ComposedTileLayer) is the layer responsible for tracking and managing the tiles. Tiles are in this case also layers (sub layers?) implemented in SubTile (org.mozilla.gecko.gfx.SubTile), where each one is responsible for one tile bitmap (actually OpenGL texture once it has been uploaded).

When the viewport changes, the request for tile rechecking is send to LOKitThread (see LOKitThread#tileReevaluationRequest), where the tiles are rechecked, add and removed if necessary.

CompositeTileLayer is actually an abstract class, which has two implementations. One is DynamicTileLayer (org.mozilla.gecko.gfx.DynamicTileLayer), which is used for main tile view of the document, and FixedZoomTileLayer (org.mozilla.gecko.gfx.FixedZoomTileLayer), which just renders the tiles at a fixed zoom level. This is then used as a background low resolution layer.

Tile Invalidation

Tile can change in LibreOffice when user changes the content (adds, removes text or changes the properties). In this case, an invalidation rectangle is signaled from LibreOffice, which includes a rectangle that needs to be invalidated. In this case LOKitThread gets this request via callback, and rechecks all tiles if they need to be invalidated. For more details see LOKitThread#tileInvalidation).

Editing

For editing there are 2 coarse tasks that the LibreOffice app must do:

  1. send input events to LibreOffice core (keyboard, touch and mouse)
  2. listen to messages (provided via callback) from LibreOffice core and react accordingly

In most cases when an input event happens and is send to the LO core, then a message from LO core follows. For example: when the user writes to the keyboard, key event is sent and an invalidation request from LO core follows. When user touches an image, a mouse event is sent, and a "new graphic selection" message from LO core follows.

All keyboard and touch events are sent to LOKitThread as LOEvents. In LOKitThread they are processed and sent to LibreOffice core. The touch events originate in JavaPanZoomController, the keyboard events in LOKitInputConnectionHandler (org.libreoffice.LOKitInputConnectionHandler), however there are other parts too - depending on the need.

InvalidationHandler (org.libreoffice.InvalidationHandler) is the class that is responsible to process messages from LibreOffice core and to track the state.

Overlay

Overlay elements like cursor and selections aren't drawn by the LO core, instead the core only provides data (cursor position, selection rectangles) and the app needs to draw them. DocumentOverlay (org.libreoffice.overlay.DocumentOverlay) and DocumentOverlayView (org.libreoffice.overlay.DocumentOverlayView) are the classes that provide the overlay over the document, where selections and the cursor is drawn.

Icons

App uses material design icons available at [1].

[1] - https://www.google.com/design/icons/

Emulator and Debugging Notes

For instructions on how to build for Android, see README.cross.

Getting Something Running

Attach your device, so 'adb devices' shows it. Then run:

    cd android/source
    make install
    adb logcat

and if all goes well, you should have some nice debug output to enjoy when you start the app.

Using the Emulator

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 an AVD that doesn't work. Instead start it from the console:

    LD_LIBRARY_PATH=$(pwd)/lib emulator-arm -avd <Name> -partition-size 500

where is the literal name of the AVD that you entered.

[ In order to have proper acceleration, you need the 32-bit libGL.so:

    sudo zypper in Mesa-libGL-devel-32bit

and run emulator-arm after the installation. ]

Then you can run ant/adb as described above.

After a while of this loop you might find that you have lost a lot of space on your emulator's or device's /data volume. You can do:

    adb shell stop; adb shell start

Debugging

First of all, you need to configure the build with --enable-debug or --enable-dbgutil. You may want to provide --enable-symbols to limit debuginfo, like --enable-symbols="sw/" or so, in order to fit into the memory during linking.

Building with all symbols is also possible but the linking is currently slow (around 10 to 15 minutes) and you need lots of memory (around 16GB + some swap).

Using ndk-gdb

Direct support for using ndk-gdb has been removed from the build system. It is recommended that you give the lldb debugger a try that has the benefit of being nicely integrated into Android Studio (see below for instructions). If you nevertheless want to continue using ndk-gdb, use the following steps that are described in more detail here: https://stackoverflow.com/a/10539883

  • add android:debuggable="true" to AndroidManifest.xml
  • push gdbserver to device, launch and attach to application
  • forward debugging port from host to device
  • launch matching gdb on host and run following setup commands: - set solib-search-path obj/local/ - file obj/local//liblo-native-code.so - target remote :

Pretty printers aren't loaded automatically due to the single shared object, but you can still load them manually. E.g. to have a pretty-printer for rtl::OString, you need:

    (gdb) python sys.path.insert(0, "/master/solenv/gdb")
    (gdb) source /master/instdir/program/libuno_sal.so.3-gdb.py

Using Android Studio (and Thus lldb)

Note that lldb might not yield the same results as ndk-gdb. If you suspect a problem with lldb, you can try to manually use ndk-gdb as described above. Using lldb from within Android Studio is more comfortable though and works like this:

  • open android/source/build.gradle in Android Studio via File|New → Import Project
  • make sure you select the right build variant (strippedUIDebug is what you want)
  • use Run|Edit Configurations to create a new configuration of type "Android Native"
    • on tab "General" pick module "source"
    • on tab "Native Debugger" add android/obj/local/<hostarch> to the Symbol directories
    • on the LLDB startup commands tab add "command script import /path/to/solenv/lldb/libreoffice/LO.py" to get some pretty printing hooks for the various string classes

Then you can select your new configuration and use Run | Debug to launch it. Note that lldb doesn't initially stop execution, so if you want to add breakpoints using lldb prompt, you manually have to pause execution, then you can switch to the lldb tab and add your breakpoints. However making use of the editor just using File|Open .. to open the desired file in Android Studio and then toggling the breakpoint by clicking on the margin is more comfortable.

Debugging the Java Part

Open android/source/build.gradle in Android studio via File|New → Import Project and you can use Android Studio's debugging interface. Just make sure you pick the correct build variant (strippedUIDebug)

The alternative is to use the jdb command-line debugger. Steps to use it:

  1. Find out the JDWP ID of a debuggable application:

     adb jdwp
    

    From the list of currently active JDWP processes, the last number is the just started debuggable application.

  2. Forward the remote JDWP port/process ID to a local port:

     adb forward tcp:7777 jdwp:31739
    
  3. Connect to the running application:

     jdb -sourcepath src/java/ -attach localhost:7777
    

Assuming that you're already in the LOAndroid3 directory in your shell.

Debugging the Missing Services

Android library only include essential services that are compiled for LibreOffice in order to reduce the size of the apk. When developing, some services might become useful and we should add those services to the combined library.

In order to identify missing services, we need to be able to receive SAL_INFO from cppuhelper/source/shlib.cxx in logcat and therefore identify what services are missing. To do so, you may want add the following when configuring the build.

--enable-symbols="cppuhelper/ sal/"

[TODO: This is nonsense. --enable-symbols enables the -g option, not SAL_INFO. Perhaps this was a misunderstanding of meaning of --enable-selective-debuginfo, the old name for the option.]

Which services are combined in the android lib is determined by

solenv/bin/native-code.py

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/...

Startup Details

All Android apps are basically Java programs. They run "in" a Dalvik (or on Android 5 or newer - ART) virtual machine. Yes, you can also have apps where all your code is native code, written in a compiled language like C or C++. But 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.

Anyway, our current "experimental" apps are not based on NativeActivity. They have normal Java code for the activity, and just call out to a single, app-specific native library (called liblo-native-code.so) to do all the heavy lifting.

Triple-T metadata for F-Droid

The subdirectory source/src/main/play contains data in the Triple-T structure that F-Droid evaluates to extract metadata.

More information: https://f-droid.org/en/docs/All_About_Descriptions_Graphics_and_Screenshots/#triple-t-structure

As Android Viewer currently uses a non-default directory layout, this currently needs to be placed in a different subdirectory than the actual source code in order for F-Droid to find it, see the related discussion for more details.