Commit Graph
386 Commits
Author SHA1 Message Date
Michael Weghorn 19363c84e0 android: Set archivesBaseName differently after gradle update
Setting the archive base name in build.gradle using

    project.ext.set("archivesBaseName", "LibreOfficeViewer")

no longer worked after

    commit 39326bc7d4
    Date:   Tue Apr 19 15:49:53 2022 +0200

        android: Update Android Gradle Plugin to 7.1.3

        ... and gradle to 7.2, which is what Android Studio suggested
        and did automatically when confirming.

As a consequence, the generated .apk or .aar files
would no longer have the app name in them, but be
called e.g. "source-strippedUIEditing-release-unsigned.apk"
instead of
"LibreOfficeViewer-strippedUIEditing-release-unsigned.apk".

Setting `archivesBaseName` in `android.defaultConfig`
in libOSettings.gradle works, so move it there.

Change-Id: Id03cbe10681aca85c35aeef64527bc7707c95736
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133191
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-20 10:45:59 +02:00
Michael Weghorn f22f83fbac android: Update dependencies to current versions
This requires the Gradle update from
Change-Id Ia982d72d877e229c3006c6d528b830d16c88481f
"android: Update Android Gradle Plugin to 7.1.3"
as a prerequisite, since the build would otherwise fail
with

> > Task :desugarStrippedUIDebugFileDependencies FAILED
> D8: Method name '$private$<clinit>' in class
> 'com.sun.star.frame.XMenuBarMergingAcceptor$-CC' cannot be represented
> in dex format.
>
> FAILURE: Build failed with an exception.

after updating only the dependencies.

Change-Id: Ifa007fa0e520e9494ace173d1643abb7d7a5f9c6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133183
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-20 05:20:08 +02:00
Michael Weghorn 8917c8b11a android: Drop obsolete "sourceCompatibility 6"
This addresses this warning when building Android Viewer:

> > Task :compileStrippedUIDebugJavaWithJavac
> warning: [options] source value 6 is obsolete and will be removed in a future release
> warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.

Change-Id: Ic1a80117e7e8c31774947729452bfafacd7a24c8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133182
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-20 05:19:52 +02:00
Michael Weghorn 39326bc7d4 android: Update Android Gradle Plugin to 7.1.3
... and gradle to 7.2, which is what Android Studio suggested
and did automatically when confirming.

Also apply the following optional, but recommended change
while doing so:

> Migrate from lintOptions to lint
> Configuration related to lint is now performed using the lint block.

Change-Id: Ia982d72d877e229c3006c6d528b830d16c88481f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133179
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-20 05:19:36 +02:00
Michael Weghorn 76d50f8327 android: Stop using ANDROID_SDK_HOME env variable
Otherwise, upgrading to Android Gradle Plugin 7.1.3 and
gradle 7.2 (which will be done in a follow-up commit)
would make the build fail like this:

> FAILURE: Build failed with an exception.
>
> * Where:
> Build file '/home/michi/development/git/libreoffice-WORKTREE-for-android-x86/android/source/build.gradle' line: 1
>
> * What went wrong:
> A problem occurred evaluating root project 'source'.
> > Failed to apply plugin 'com.android.internal.application'.
>    > ANDROID_SDK_HOME is set to the root of your SDK: /home/michi/Android/Sdk
>      ANDROID_SDK_HOME was meant to be the parent path of the preference folder expected by the Android tools.
>      It is now deprecated.
>
>      To set a custom preference folder location, use ANDROID_USER_HOME.
>
>      It should NOT be set to the same directory as the root of your SDK.
>      To set a custom SDK location, use ANDROID_HOME.

We don't actually rely on `ANDROID_SDK_HOME` being evaluated
by the Android toolchain, but it used to be set in configure.ac,
and the value was then assigned to the `sdk.dir` property written to
`android/source/local.properties`.

Just use a new variable name `ANDROID_SDK_DIR`
and keep the mechanism otherwise unchanged for now.

Change-Id: I44826621a1342119d40036fb704d8ff1eeed7c77
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133178
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-20 05:19:20 +02:00
Michael Weghorn 258fd217a3 android: Remove redundant label attribute from activities
Android Studio was showing an info/warning in the "Problems"
pane that this label is redundant, so remove it.
(The app name is used by default if nothing else is specified
anyway.)

Change-Id: I799c681488b95e2fffe89b59e7de18febe654dcb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133174
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-20 05:18:49 +02:00
Michael Weghorn 2ab389b251 android: Update compileSdkVersion/targetSdkVersion to 31
Google Play now requires that apps target API level 30 or higher, and
compileSdkVersion/targetSdkVersion 31 is also needed to update
the com.google.android.material dependency to >= 1.5.0 [1].

Explicitly set the `android:exported="true"` attribute for activities
which is required when targeting Android 12 or newer; quoting from
the list of behavior changes for apps targeting Android 12 [1]:

> Safer component exporting
>
> If your app targets Android 12 or higher and contains activities,
> services, or broadcast receivers that use intent filters, you must
> explicitly declare the android:exported attribute for these app
> components.  Warning: If an activity, service, or broadcast receiver
> uses intent filters and doesn't have an explicitly-declared value for
> android:exported, your app can't be installed on a device that runs
> Android 12 or higher.
>
> If the app component includes the LAUNCHER category, set
> android:exported to true. In most other cases, set android:exported
> to false.
>
> The following code snippet shows an example of a service that
> contains an intent filter whose android:exported attribute is set to
> false:
>
> <service android:name="com.example.app.backgroundService"
>          android:exported="false">
>     <intent-filter>
>         <action android:name="com.example.app.START_BACKGROUND" />
>     </intent-filter>
> </service>

The app worked fine in a quick test on an x86_64 AVD with API level 31.

[1] https://github.com/material-components/material-components-android/releases/tag/1.5.0-alpha03

Change-Id: Ibb919e4edb995740e48ebc3338ffab6ca35c1373
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133167
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-20 05:18:36 +02:00
Michael Weghorn 003e2873e4 android: Use proper Intent to open doc for API level < 19
`Intent.ACTION_OPEN_DOCUMENT` was introduced in API level 19,
therefore `Intent.ACTION_GET_CONTENT` is supposed to be used
for older Android versions.

The previous attempt at doing so didn't work, since no
`ActivityNotFoundException` is thrown when trying
to set the action to `Intent.ACTION_OPEN_DOCUMENT` on
older Android versions.

Fix that by using a proper version check instead.

Change-Id: Ie06fa3f39e3042b4b7161a3c937bf655eb658abd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133025
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-14 20:40:23 +02:00
Michael Weghorn f869807175 android: Use "ContentResolver#query" available from API level 1
Use the `ContentResolver#query` overload that is available from
Android API level 1 on, not the one that's only available from
API level 26 on [2], which would otherwise trigger an exception
if run on devices running Android version < 8.0, as seen
on an AVD with API level 21:

> E/AndroidRuntime( 2914): FATAL EXCEPTION: main
> E/AndroidRuntime( 2914): Process: org.libreoffice, PID: 2914
> E/AndroidRuntime( 2914): java.lang.NoSuchMethodError: No virtual method query(Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/CancellationSignal;)Landroid/database/Cursor; in class Landroid/content/ContentResolver; or its super classes (declaration of 'android.content.ContentResolver' appears in /system/framework/framework.jar)
> E/AndroidRuntime( 2914):        at org.libreoffice.ui.FileUtilities.retrieveDisplayNameForDocumentUri(FileUtilities.java:137)
> E/AndroidRuntime( 2914):        at org.libreoffice.ui.LibreOfficeUIActivity.createUI(LibreOfficeUIActivity.java:206)
> E/AndroidRuntime( 2914):        at org.libreoffice.ui.LibreOfficeUIActivity.onCreate(LibreOfficeUIActivity.java:147)
> E/AndroidRuntime( 2914):        at android.app.Activity.performCreate(Activity.java:5937)
> E/AndroidRuntime( 2914):        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
> E/AndroidRuntime( 2914):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
> E/AndroidRuntime( 2914):        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
> E/AndroidRuntime( 2914):        at android.app.ActivityThread.access$800(ActivityThread.java:144)
> E/AndroidRuntime( 2914):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
> E/AndroidRuntime( 2914):        at android.os.Handler.dispatchMessage(Handler.java:102)
> E/AndroidRuntime( 2914):        at android.os.Looper.loop(Looper.java:135)
> E/AndroidRuntime( 2914):        at android.app.ActivityThread.main(ActivityThread.java:5221)
> E/AndroidRuntime( 2914):        at java.lang.reflect.Method.invoke(Native Method)
> E/AndroidRuntime( 2914):        at java.lang.reflect.Method.invoke(Method.java:372)
> E/AndroidRuntime( 2914):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
> E/AndroidRuntime( 2914):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
>

[1] https://developer.android.com/reference/android/content/ContentResolver#query(android.net.Uri,%20java.lang.String[],%20java.lang.String,%20java.lang.String[],%20java.lang.String)
[2] https://developer.android.com/reference/android/content/ContentResolver#query(android.net.Uri,%20java.lang.String[],%20android.os.Bundle,%20android.os.CancellationSignal)

Change-Id: I13ecc57d3d6b25a7eb2e5ff85a3420ef8064cb20
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133024
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-14 20:40:09 +02:00
Michael Weghorn 70cb4955f1 android: Port from Android Support Lib to AndroidX
Replace the no longer maintained Android Support Library
with the Android Jetpack libraries.

Quoting [1]:

> Version 28.0.0 is the last release of the Support Library. There will be
> no more android.support library releases. All new feature development
> will be in the androidx namespace.

Most porting was done automatically by using Android Studio's
"Refactor" -> "Migrate to AndroidX..." function.

In `android/source/res/layout/toolbar_bottom.xml` and
`android/source/res/layout/toolbar_color_picker.xml`,
the uses of
`app:layout_behavior="android.support.design.widget.BottomSheetBehavior"`
had to be replaced manually as described at [2], because
the app would crash when using the old "android.support"
values.

Also drop the Android Support Library related bits from configure.ac

In a quick test, this worked fine and no obvious
difference was visible when running this in various AVDs.

When trying to test this in an x86 AVD still using
SDK 16 (Android 4.1), which is currently specified
as Android Viewer's `minSdkVersion`, only various
unrelated issues showed up, some of which will be
handled in follow-up commits.

After the migration, many weird errors showed up in
Android Studio, which disappeared after invalidating
the caches (via "File" -> "Invalidate Caches...").

[1] https://developer.android.com/jetpack/androidx
[2] https://stackoverflow.com/questions/45100963/runtimeexception-could-not-inflate-behavior-subclass

Change-Id: I2a57f0ebd56e7ecc09b7d65aae17fd15088a633b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133002
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-14 16:49:41 +02:00
Michael Weghorn d2572dc9d6 android: Deduplicate LOKitThread#load{,New}Document
After Change-Id I15ecc2eba6c5ee441f6e14f8229594cab05dbba7
"tdf#148556 android: Don't delay refresh when loading doc",
the only thing that `LOKitThread#loadNewDocument` does
in addition to `LOKithThread#loadDocument` is to save the
newly created document (to a temp file) if loading was
successful.

So, have `loadDocument` return a boolean saying whether
loading was successful and call that method from
`loadNewDocument` to reduce duplication.

Change-Id: I9b99e011b3f5105bb60f95174de393462ff08271
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132966
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-13 18:23:02 +02:00
Michael Weghorn 4476fd51a3 tdf#148556 android: Don't delay refresh when loading doc
The previous way of using a separate Runnable
to do the refresh and posting that to the
main handler instead of doing the refresh
right away resulted in a timing issue, due
to which it could happen that a Calc document
would not be rendered when initally loaded
(but only after another tile reevaluation was
triggered, e.g. by tapping on the screen).

While this appears to happen mostly on fast hardware,
I could reproduce on my AVD as well when increasing
the minimum time that has to pass between
tile reevaluations to 100 ms:

    --- a/android/source/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
    +++ b/android/source/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
    @@ -157,7 +157,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
             }

             long currentReevaluationNanoTime = System.nanoTime();
    -        if ((currentReevaluationNanoTime - reevaluationNanoTime) < 25 * 1000000) {
    +        if ((currentReevaluationNanoTime - reevaluationNanoTime) < 100 * 1000000) {
                 return;
             }

For the bad case, the Runnable that triggers the
refresh would be taken from the message queue and
run on the main thread at a point in time that
resulted in `LOKitShell.sendTileReevaluationRequest`
not getting called in `ComposedTileLayer#reevaluateTiles`
due to the above-mentioned minimum time in between
tile reevaluations.

Avoid the problem and simplify the whole handling by
no longer posting a Runnable to the main handler, but
calling `refresh()` right away.

Posting to the main handler had been introduced in

    commit 27326e0f58
    Date:   Fri Aug 3 07:13:00 2018 -0700

        tdf#119082 Exception wrong thread on Android Viewer

to avoid crashes due to things being done on the wrong thread
when switching to another app and then back to Android Viewer
(s. tdf#119082), but that is no longer a problem, because the
document is no longer loaded anew in that case since

    commit 1bc4247220
    Date:   Fri Apr 9 13:59:43 2021 +0200

        tdf#95517 android: Rework app/doc lifecycle handling

, so the code path is not used there any more, but only when
the document is initially loaded, triggered in
`LibreOfficeMainActivity#onCreate`.

After all, the problem seems to be a similar one as fixed in

    commit 128f67e0ef
    Date:   Tue May 18 14:27:51 2021 +0200

        tdf#142348 android: Avoid extra refresh after loading doc

, where another timing issue in the handling of a refresh event could
result in a blank page instead of the Calc doc being rendered.

With the refresh being done right away, the synchronization added
in

    commit 55661298bb
    Date:   Wed Apr 1 09:00:13 2020 +0200

        tdf#131195 android: Don't destroy doc while loading it

is also no more needed, because the situation described in its
commit message no longer applies:

> Since the 'refresh()' in 'LOKitThread::loadDocument' is
> not executed synchronously but posted to the main handler,
> this needs to be synchronized to prevent the document from
> being deleted while it's being used.

Change-Id: I15ecc2eba6c5ee441f6e14f8229594cab05dbba7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132965
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-13 18:22:49 +02:00
Michael Weghorn 2f998468b0 android: Drop leftover German translation
The English string had already been dropped in

    commit a23bd42e9b
    Author: Michael Weghorn <m.weghorn@posteo.de>
    Date:   Tue Apr 6 14:26:06 2021 +0200

        android: Drop custom file abstraction + UI

While the leftover German translation is just ignored
in development builds, it resulted in an error
when building a release APK like this:

> ./gradlew assembleStrippedUIEditingRelease
> warn: removing resource org.libreoffice:string/filter without required default value.
>
>
> > Task :compileStrippedUIEditingReleaseJavaWithJavac
> warning: [options] source value 6 is obsolete and will be removed in a future release
> warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
> Note: /home/michi/development/git/libreoffice-WORKTREE-for-android-x86/android/source/src/java/org/libreoffice/SettingsActivity.java uses or overrides a deprecated API.
> Note: Recompile with -Xlint:deprecation for details.
> Note: /home/michi/development/git/libreoffice-WORKTREE-for-android-x86/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java uses unchecked or unsafe operations.
> Note: Recompile with -Xlint:unchecked for details.
> 2 warnings
>
> > Task :lintVitalStrippedUIEditingRelease
> /home/michi/development/git/libreoffice-WORKTREE-for-android-x86/android/source/res/values-de/strings.xml:28: Error: "filter" is translated here but not found in default locale [ExtraTranslation]
>     <string name="filter">Filtern nach</string>
>             ~~~~~~~~~~~~~
>
>    Explanation for issues of type "ExtraTranslation":
>    If a string appears in a specific language translation file, but there is
>    no corresponding string in the default locale, then this string is probably
>    unused. (It's technically possible that your application is only intended
>    to run in a specific locale, but it's still a good idea to provide a
>    fallback.)
>
>    Note that these strings can lead to crashes if the string is looked up on
>    any locale not providing a translation, so it's important to clean them
>    up.
>
> 1 errors, 0 warnings
>
> > Task :lintVitalStrippedUIEditingRelease FAILED
>
> FAILURE: Build failed with an exception.

Change-Id: I9a6c984d3250852d0e806cffdff81770ed868299
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132834
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-11 19:53:36 +02:00
Michael Weghorn 9c5facd726 android: Pass variable for "selected" param
... of the CalcHeaderCell ctor, to simplify this a bit.

Change-Id: I02ff00acccaec26de54534c6c021b9cd05f1d472
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132813
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-04-11 13:19:07 +02:00
Michael Weghorn 44950bc4bb android: Enable support for FODS
Enable support for MIME type
"application/vnd.oasis.opendocument.spreadsheet-flat-xml" in
AndroidManifest, the comment saying it crashes the app
is obsolete.

However, at least on my Android 10 AVD, that MIME type
does not seem to be associated with '*.fods' files, so
they were not offered to be opened. MIME type
"application/octet-stream" was used instead, for which
no support is declared.

For testing, I just disabled the MIME type filter locally and
was then able to open an FODS file just fine:

    --- a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
    +++ b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
    @@ -266,7 +266,7 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
             }

             intent.setType("*/*");
    -        intent.putExtra(Intent.EXTRA_MIME_TYPES, SUPPORTED_MIME_TYPES);;
    +        //intent.putExtra(Intent.EXTRA_MIME_TYPES, SUPPORTED_MIME_TYPES);;

Change-Id: Ibf3f559a313f0b89bc4c25498e3efa0fcbded506
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132263
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-03-29 11:59:28 +02:00
Ilhan Yesil e72a7368b3 tdf#131548 Android: jump to cell
Added LOK_CALLBACK_SC_FOLLOW_JUMP: fire this signal to jump to cell
cursor in android viewer. Payload format same as
LOK_CALLBACK_INVALIDATE_TILES.

Change-Id: Ic896baccf1327d6ccdf104811446e3454a42679e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116448
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-09-03 11:45:21 +02:00
Michael Weghorn 6bfa94398a tdf#142618 android: Don't crash when passed MIME type is null
Change-Id: I5fb532b36fe650596f25a1ba8b7dc56e21292dc1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117053
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-06-13 20:49:21 +02:00
Michael Weghorn 4a9eef7849 tdf#106893 android: Show whole doc when closing soft keyboard
When closing the software keyboard after typing,
a black area instead of the doc content was shown
in Android Viewer.
This looks related to the fact that a SurfaceView
is involved, s.a. [1] which suggests two potential
solutions to fix the issue, but none of them really
works well. (Setting a transparent background didn't
have any effect when I tried. Using
'android:windowSoftInputMode="adjustPan"' in
AndroidManifest.xml would work in general, but trigger
the  problem described in tdf#96789, namely the
software keyboard would be shown on top of the
document and the last part of the document would
not be visible with the software keyboard enabled
any more.)

Rather, make sure an 'LOEvent.SIZE_CHANGED' is
triggered when the software keyboard is enabled or
disabled, in which case 'LayerView#onLayout' is called
with a 'changed=true' parameter.
To avoid resetting zoom and position of the document
for this case, call the 'redraw' function with param
'false' when processing this type of event in
'LOKitThread#processEvent'
(s.a. Change-Id: I8ba6a7cd8d984ad99654e188e00144e1edf407ed,
"android: Don't reset zoom and position on refresh event"
that did a similar thing for 'LOEvent.REFRESH').

This adds a 'force' boolean parameter to
'GeckoLayerClient#sendResizeEventIfNecessary', which
interestingly had been there before commit

    43bbf53bba
    Date:   Tue Jan 27 13:01:53 2015 +0900

        android: remove unneded code from GeckoLayerClient

but I didn't further check whether it had been used
in any way that would have been useful for this
scenario back then.

Stackoverflow article [2] was quite helpful.

[1] https://stackoverflow.com/questions/2978290/androids-edittext-is-hidden-when-the-virtual-keyboard-is-shown-and-a-surfacevie
[2] https://stackoverflow.com/questions/52223095/how-to-detect-redraw-of-screen-has-completed-after-soft-keyboard-closes

Change-Id: If3fdd1335468fc50901fc6c1982c1463c7804309
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115973
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-05-21 22:00:24 +02:00
Michael Weghorn 817c89fa45 android: Inline 'LayerView#setViewportSize' to only call site
It doesn't override any parent class methods and was
only called from here.

Change-Id: Iccfacb42e8d5514994eafac841c0ec55be65b062
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115972
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-05-21 21:59:56 +02:00
Michael Weghorn 1cfc6c545c android: Don't reset zoom and position on refresh event
Don't call 'zoomAndRepositionTheDocument' for a REFRESH
event. The only two places sending such an event are in
'LibreOfficeMainActivity#onStart' and in
'FormattingControler#sendInsertGraphic'.

I don't see any need to reset the zoom and position in
any of those two cases. Doing so had the effect that any
manual zoom changes would be lost when e.g. switching
between the LibreOffice Viewer app and another one,
after a "Save As" or when inserting a picture.

In my opinion, it's desirable to keep the view
the user had before doing any of those actions and
just rendering the document anew.

To do so, add an extra bool parameter
'resetZoomAndPosition' to the relevant methods
in 'LOKitThread' that says whether a reset
should take place.

Change-Id: I8ba6a7cd8d984ad99654e188e00144e1edf407ed
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115950
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-05-21 21:59:31 +02:00
Michael Weghorn a3f682f90f tdf#106370 android: Make inserting pictures work
Instead of just setting LibreOfficeMainActivity's
'pendingInsertGraphic' member when inserting an
image, call the method responsible for asking what
compression to apply, doing the actual compression
and sending the event so the picture is actually
inserted right away.

'LibreOfficeMainActivity#pendingInsertGraphic' is
(by now) only evaluated in 'LOKitTileProvider' when the
document is initially loaded, therefore just setting
it had no effect.

The more complicated handling used previously instead
of just inserting the picture right away was probably
necessary/used because 'LibreOfficeMainActivity#onStart'
used to reload the whole document before

    commit 1bc4247220
    Author: Michael Weghorn <m.weghorn@posteo.de>
    Date:   Fri Apr 9 13:59:43 2021 +0200

        tdf#95517 android: Rework app/doc lifecycle handling

and that was called when returning to the main activity
from the picture chooser. (That is just a guess, I didn't
actually verify this).

While this fix probably doesn't have much to do with what
caused that functionality to not work back in 2018,
when most of the feature was introduced but it did
not yet fully work as mentioned in

    commit 8d977511e3
    Date:   Mon Aug 14 11:41:30 2017 -0500

        tdf#106370 Android: add ability to insert pictures

        Added ability to insert pictures to Android Viewer.
        You can take photo or select photo from device or
        the cloud (Google photos, Dropbox). You can also
        compress the picture before inserting it with multiple
        compress grades. So far, inserting doesn't work for
        Writer due LO native library issues (I think).

it still makes inserting pictures "just work" by now.

Change-Id: Idad9dcbba177ea12f056bc31bd6b9c08621062cf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115932
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-05-21 21:59:01 +02:00
Michael Weghorn 128f67e0ef tdf#142348 android: Avoid extra refresh after loading doc
commit 1bc4247220
    Date:   Fri Apr 9 13:59:43 2021 +0200

        tdf#95517 android: Rework app/doc lifecycle handling

changed activity lifecycle for Android Viewer's
'LibreOfficeMainActivity'. It moved sending an event to
trigger loading of the document from the 'onStart' to the
'onCreate' method and added sending a more lightweight refresh
event the 'onStart' method instead.

However, since a refresh is already done when loading the
document, there's no need to do another refresh when the 'onStart'
method is called right after the 'onCreate' method.
Therefore, set a flag in the 'onCreate' method and use that
to skip sending the extra refresh event for that case. This
not only avoids doing unnecessary work but also avoids that
the two could get into each others way, resulting in Calc
documents sometimes not being rendered on initial load.

Change-Id: I5c47e1b5f7a42a49fb903891aa84585b36994a4b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115750
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-05-19 07:42:57 +02:00
Michael Weghorn 55c17dff49 android: Don't crash trying to process non-existing file from recents
When the "Recent files" list in Android Viewer contained an entry
for an Uri that was no longer pointing to a valid file, a
SecurityException was thrown trying to query the display name
from it.

Catch the SecurityException that is thrown and just return an
empty string, the document is then not displayed in the
"Recent files" list.

One scenario:

1) open file located in the "Download" directory from within the app
2) close the app
3) delete the file
4) open the app again

-> crash, with this backtrace in ADB log:

    05-11 08:37:14.230  3892  4707 E DatabaseUtils: java.lang.SecurityException: Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.downloads.documents/document/msf%3A1091 from pid=6981, uid=10177 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
    05-11 08:37:14.230  3892  4707 E DatabaseUtils:         at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:804)
    05-11 08:37:14.230  3892  4707 E DatabaseUtils:         at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:670)
    05-11 08:37:14.230  3892  4707 E DatabaseUtils:         at android.content.ContentProvider$Transport.query(ContentProvider.java:238)
    05-11 08:37:14.230  3892  4707 E DatabaseUtils:         at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:106)
    05-11 08:37:14.230  3892  4707 E DatabaseUtils:         at android.os.Binder.execTransactInternal(Binder.java:1138)
    05-11 08:37:14.230  3892  4707 E DatabaseUtils:         at android.os.Binder.execTransact(Binder.java:1102)
    05-11 08:37:14.230  6981  6981 D AndroidRuntime: Shutting down VM
    05-11 08:37:14.231  6981  6981 E AndroidRuntime: FATAL EXCEPTION: main
    05-11 08:37:14.231  6981  6981 E AndroidRuntime: Process: org.libreoffice, PID: 6981
    05-11 08:37:14.231  6981  6981 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{org.libreoffice/org.libreoffice.ui.LibreOfficeUIActivity}: java.lang.SecurityException: Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.downloads.documents/document/msf%3A1091 from pid=6981, uid=10177 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3333)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3477)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:216)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:7464)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:955)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime: Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.downloads.documents/document/msf%3A1091 from pid=6981, uid=10177 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.os.Parcel.createExceptionOrNull(Parcel.java:2285)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.os.Parcel.createException(Parcel.java:2269)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.os.Parcel.readException(Parcel.java:2252)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.content.ContentProviderProxy.query(ContentProviderNative.java:472)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.content.ContentResolver.query(ContentResolver.java:1112)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at org.libreoffice.ui.FileUtilities.retrieveDisplayNameForDocumentUri(FileUtilities.java:137)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at org.libreoffice.ui.LibreOfficeUIActivity.createUI(LibreOfficeUIActivity.java:206)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at org.libreoffice.ui.LibreOfficeUIActivity.onCreate(LibreOfficeUIActivity.java:147)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.Activity.performCreate(Activity.java:7990)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.Activity.performCreate(Activity.java:7979)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3308)
    05-11 08:37:14.231  6981  6981 E AndroidRuntime:        ... 11 more
    05-11 08:37:14.233  2293  3174 W ActivityTaskManager:   Force finishing activity org.libreoffice/.ui.LibreOfficeUIActivity

Change-Id: I7a8e824e557dba8771cf1f210ae89d6f60498737
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115374
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-05-11 10:05:45 +02:00
Michael Weghorn bcd7a72442 tdf#142153 android: Delete unused textures immediately
Don't delay the call to 'glDeleteTextures' but
always call it immediately via 'TextureReaper.get().reap()'
in 'Subtile#cleanTexture'.

Delaying it appears to sometimes cause it to be called
"at the wrong time", resulting in black areas being
shown instead of properly rendering/displaying the document
content in the corresponding tile.

This fixes the issue also mentioned in commit
1bc4247220
("tdf#95517 android: Rework app/doc lifecycle handling"),
which was present before, though:

> (Well, sometimes there is an issue with
> invalidation/repaint and single tiles remain black,
> but that happened previously - when the whole doc
> was loaded anew - just the same way).

Change-Id: I5f18dbe3133d9d00a76b129fd119c2e80441e531
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115241
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-05-07 18:32:04 +02:00
Michael Weghorn 70554d74a6 tdf#135136 Android: Don't hardcode height of TextViews
Otherwise the text gets cut off when using a large
system font size.

Change-Id: I265d57ae310e39e9e452f6e744f17ed4807a00b2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115134
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-05-05 17:44:25 +02:00
Michael Weghorn fbcc644bad android: Some trivial style improvements
Those were mostly suggested by Android Studio, like:

* mark members static or final
* drop unused variables and members
* avoid unnecessary cast
* simplify condition: '(!cond)' instead of 'cond == false'
* drop unused imports

Change-Id: I252fe836e4a3184e13af59a30202c6daccac1794
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114546
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-23 23:26:16 +02:00
Michael Weghorn 710badae87 android: Drop unused FileUtilities members
... and make its static 'LOGTAG' member final.

Change-Id: I6d16bc76590341a60db9e123d20d81dcd7adba71
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114545
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-23 23:24:31 +02:00
Michael Weghorn 8646ed9247 android: Drop unused FolderIconView class
It appears to be unused since

    commit f3eccc6553
    Date:   Tue Feb 3 18:19:32 2015 +0000

        tdf#87432: normal icons for folders in android doc browser

Change-Id: I6984ff75392f7f28ba1b2659846d164d25b66f2b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114544
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-23 23:24:10 +02:00
Michael Weghorn 3199182588 android: Offer 'Save As' in readonly mode
Provide the "Save As..." menu entry in Android
Viewer also if read-only mode is used, either
because the experimental editing mode is disabled
or there is no write access to the document.

This way, a copy of the original document
can be saved elsewhere.

In case experimental mode is enabled, editing
is allowed after saving the document.

Call 'ToolbarController#setEditMode' in
'ToolbarController#switchToEditMode' right away instead
of posting it to the main handler in a Runnable along
with the other commands (that change the UI), so the new state
is already taken into account in
'LibreOfficeMainActivity#onResume' and the toolbar
isn't switched back to view mode there right away.

Change-Id: I321e42d0833463b31c7b39336d66b29bd51d9890
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114539
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-23 15:01:31 +02:00
Michael Weghorn 01521db61e tdf#95615 android: Don't offer "Save" after opening template
When the input document in Android Viewer is a template,
a new doc is created and a plain '.uno:Save'
(which 'LibreOfficeMainActivity#saveDocument' triggers when the
"Save" menu entry is selected) will therefore fail.
A proper URI to save to (rather than overwriting the
template itself) is only known after a "Save As" anyway,
so don't set the 'mDocument' member until then, which leads to
the "Save" menu entry becoming disabled, just as is the
case when explicitly choosing to create a new document in
the start activity.

For now, the check whether the document is a template
checks whether the MIME type detected for the URI
ends with "template", which is the case for ODF and
OOXML types (like
"application/vnd.oasis.opendocument.text-template" or
"application/vnd.openxmlformats-officedocument.wordprocessingml.template").
This can be refined further as needed, e.g. by explicitly
adding more MIME types to check.

(Editing the actual template instead of creating a new doc
from it would be a different use case that remains
unsupported also with this change in place.)

Change-Id: I81ff957de27f620a026dbc01097b8061886293a1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114157
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-16 08:50:30 +02:00
Michael Weghorn 5ce43b2b4e android: Show file picker for new docs on "Save As"
When creating a new document in Android Viewer,
don't show a file picker to choose where to save
the file at once, but create a new document and
only ask where to save the file once "Save As"
has been selected.
The plain "Save" entry is disabled until then,
since no URI to save to is known at this time.

The handling for the temporary local file,
which is used for all of the "actual work"
remains unchanged.

While at it, rename
'ToolbarController#disableMenuItem' to
'ToolbarController#enableMenuItem' and
invert the meaning of the boolean parameter
since I find that more straightforward and it also
better matches the naming of the underlying
'MenuItem' method as well.

Change-Id: I3eefada5531bfb2202aca25f2c9f170a463f87f6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114152
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-16 08:50:03 +02:00
Michael Weghorn 865ec16158 android: Drop unused 'FileUtilities#doAccept'
Change-Id: I8b7f268862c3800012548376b3e60ac1f7dca9e3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114151
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-16 08:49:42 +02:00
Michael Weghorn 5306ecda9c android: Allow printing and PDF export regardless of mode
Don't only enable the "Export To PDF" and "Print" menu
items if the experimental editing mode is enabled, but
always offer them, since they should be sufficiently stable
and don't require any editing of the document.

To do so, move them into a new menu group
"group_misc_actions", and move the entry for sending
UNO commands up, so it remains in the
"group_edit_actions" menu group whose entries are
hidden unless editing mode is enabled.

Change-Id: I425cf6d0a45306ff48b45dad6fd0e804b87a2546
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114147
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-16 08:49:21 +02:00
Michael Weghorn 40f30020b9 android: Merge 2 'LOKitTileProvider#printDocument' methods
... and move the check for a new enough SDK version to
the beginning.

Change-Id: I7f5528985b8c43e218b88899409fdd22b640f72e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114145
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-16 08:48:52 +02:00
Michael Weghorn 9ebcb80e2e android: Ask where to save PDF file on export
In Android Viewer, show a file picker to select
where to save the PDF file on PDF export, rather
than unconditionally trying to save in the
"Documents" directory.

This also means that permission
'android.PERMISSION_WRITE_EXTERNAL_STORAGE' is
now no longer needed for this task, s. commit
message from

    commit 7d9db806d6
    Date:   Fri Apr 9 11:24:16 2021 +0200

        android: Request PERMISSION_WRITE_EXTERNAL_STORAGE again

for more details.

Also, adapt the 'TileKitProvider#saveDocumentAs'
methods to return a boolean value indicating
whether the save operation was successful,
and trigger showing the message right into
'LibreOfficeMainActivity#exportToPDF'.

Rename 'LOKitTileProvider#exportToPDF(boolean print)' to
just 'LOKitTileProvider#printDocument()', since the only
remaining use case for which it is used is printing now.

Change-Id: I779d782813ca01640811690a388a4b7fd3db4b2a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114143
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-16 08:48:28 +02:00
Michael Weghorn d16e569209 android: Add a "Save As..." menu entry
This adds a "Save As..." menu entry to Android
Viewer in order to save the currently opened file
to a different location.

Currently, the file is always saved in the corresponding
ODF format, regardless of the original file type,
i.e. that e.g. a DOCX file is saved in ODT format.
(This could be extended to allow a selection of the
target format as needed.)

Like "Save As" (and as compared to "Save a Copy")
in the desktop version, the app remembers the
new document URI and subsequent save operations
will overwrite the newly saved file, not the originally
opened one.
(There is no need to create a new temporary
local file to use, though.)

The directory of the currently used file
is preselected in the file chooser used to
specify where to save the new file.

Make sure to copy the file in a non-main thread,
since the destination URI might be handled
by a DocumentsProvider that does network access.
However, for now the main thread just waits for
the separate thread to finish, just like

    commit 7f838b73e8
    Date:   Fri Mar 19 15:46:36 2021 +0100

        tdf#129833 android: Move reading file to separate thread

implemented it for copying from the URI to the
temporary file when opening a file.

This also adds a 'TileProvider#isDrawing' method
(like the already existing 'isTextDocument',
'isSpreadsheet' and 'isPresentation' ones).

Change-Id: I6f56b71763431b89a6c74be35cc1e81fad136cd0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114058
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-16 08:47:59 +02:00
Michael Weghorn a2b4564d71 android: Extract copying Uri to stream in thread to separate method
This essentially extracts what

    commit 7f838b73e8
    Date:   Fri Mar 19 15:46:36 2021 +0100

        tdf#129833 android: Move reading file to separate thread

introduced into a separate helper method.

Change-Id: Ic70ba9f2e2bc125415ff1b3fa3375c3389181c43
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114123
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-16 08:47:38 +02:00
Michael Weghorn 4db8535fba android: Don't store whether spreadsheet in LibreOfficeMainActivity
LOKitTileProvider has that information, so query it instead
and don't duplicate information in LibreOfficeMainActivity.

Change-Id: I233986d6e94e5676464cb3399303efd545e33d32
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114057
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-14 10:25:46 +02:00
Michael Weghorn bcf0ed2f67 android: Drop some unused Turkish translations
Those are leftovers; they're unused since

    commit a23bd42e9b
    Date:   Tue Apr 6 14:26:06 2021 +0200

        android: Drop custom file abstraction + UI

Change-Id: I898391cfccd465e4d18d51ee07ee847978872ef1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113885
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-12 07:21:48 +02:00
Michael Weghorn c0c43f4742 android: Drop 'LibreOfficeMainActivity#onSaveInstanceState'
It just calls the parent class method anyway.

Change-Id: I802e75ad650b71d6daa08494ff812985bb844a5f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113884
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-12 07:21:26 +02:00
Michael Weghorn 1bc4247220 tdf#95517 android: Rework app/doc lifecycle handling
Previously, the document was always closed in
LibreOfficeMainActivity's 'onStop' and loaded anew in
its 'onStart' method.
In order to not lose user changes, there was also
a caching mechanism in LOKitTileProvider, also triggered
in 'LibreOfficeMainActivity#onStop'.

This means that e.g. each time a switch to another
Activity/app happened, a cache document with the user
modifications in it should have been created for
restoration. That did not really seem to work
particularly well in a few tests, as also described
in tdf#95517 ("changes reset after show Settings").

The documentation aboue Activity lifecycle says [1]

> The entire lifetime of an activity happens between the first call to
> onCreate(Bundle) through to a single final call to onDestroy(). An
> activity will do all setup of "global" state in onCreate(), and release
> all remaining resources in onDestroy(). For example, if it has a thread
> running in the background to download data from the network, it may
> create that thread in onCreate() and then stop the thread in
> onDestroy().

This changes the handling to load the document in the
'onCreate' method and clos it only in 'onDestroy',
i.e. the document remains open while e.g. switching
to another Activity or app, thus making it unnecessary
to try to restore state as good as possible in 'onStart'.
An invalidation of the view (via 'LOEvent.REFRESH')
generally seems to be enough.
(Well, sometimes there is an issue with
invalidation/repaint and single tiles remain black,
but that happened previously - when the whole doc
was loaded anew - just the same way).

This allows dropping some extra handling needed
to try to restore the previous state, along with the
caching mechanism in LOKitTileProvider (that had some
other issues, e.g. it didn't reliably create the cache
file, since the file extension was not always set, and
'LOKitTileProvider#cacheDocument' was relying on that
to derive the document type).

I am not sure whether I missed any aspect that the
previous implementation was trying to solve, but
at least these scenarios I found and tested worked
as expected with the change in place:

* user changes still present after switching between apps
  (s. tdf#106648 "Android: save current work when onSaveInstanceState is
   called")
* for the Calc case, the sheet that was selected before
  switching apps is still selected (s. tdf#101689
  "Android Viewer calc returns to first sheet")
* user changes no longer get lost when selecting a menu item
  (s. tdf#95517 "changes reset after show Settings")
* case where the user leaves the app by pressing Home, and starts it again
  (as described in commit 83386129f5
  "android: Fix the application lifecycle.")

[1] https://developer.android.com/reference/android/app/Activity#activity-lifecycle

Change-Id: If59734cbfd62673884786066c94e2c2a1d6a916e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113883
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-12 07:20:58 +02:00
Michael Weghorn d8fea0b8cc android: Always create a temporary local copy of the doc
Always create a local copy of the original document
to work with, rather than doing a different handling
depending on the type of the URI used to specify the
file to load.

This will also simplify adding support for "Save As"
in upcoming commits, where the temporary
file can remain the same and only the URI for the
actual document will need to be changed.

Change-Id: I2587611fa56b76d8a5384ac25c57335e8d12e987
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113882
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-12 07:20:36 +02:00
Michael Weghorn d3f8f4b166 android: Turn 3 "internal" docs into raw resources
Make 'example.odt', 'license.txt' and 'notice.txt'
(which can be opened via the "About" dialog)
resources of the app by copying them to a new directory
'res_generated' instead of into assets, and include
'res_generated' into resources, then use an
'android.resource://' URI instead of a 'file:///assets/'
one in AboutDialogFragment.
The latter does not work with when passed as a parameter
to 'ContentResolver.openInputStream'.

Adapt/Simplify 'LibreOfficeMainActivity#copyFileToTemp' to
make loading those docs using the 'android.resource://'
URI work and use the existing 'copyStream' method for copying from
the input to the output stream.

This is in preparation for upcoming commit with Change-Id
I7731ef81a4242fa0ce3b3fd8ced1683a6a6bee8c,
"android: Always create a temporary local copy of the doc".

Change-Id: I7731ef81a4242fa0ce3b3fd8ced1683a6a6bee8c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113881
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-12 07:20:14 +02:00
Michael Weghorn bcb74b5092 android: Drop fallback of opening default doc
Drop the fallback of opening 'example.odt' when
no file to open was given.
I see no valid way how that fallback should be
reached, so write an error log message instead,
just in case there is still a way to get there.

Change-Id: I8b8040ba0099cba9196f65982f09c67791be01c2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113880
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-12 07:19:50 +02:00
Michael Weghorn 224df2980f android: Extract method to copy stream
Extract method 'copyStream' used to copy the
temporary file to the actual document URI when
saving.
It will also be used for copying the other way around
when initially opening the document.

Change-Id: I5382f4a7c49b454ff38fb8f95afab3c39145c11f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113879
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-12 07:19:26 +02:00
Michael Weghorn 79d9a73491 android: Add member for document URI
Add a 'mDocumentUri' member in LibreOfficeMainActivity
to store the document URI rather than retrieving it from
the Intent using 'getIntent().getData()' all the time.

This is also in preparation to make it possible to change
the URI later, e.g. when doing a "Save As".

While at it, also switch to readonly mode for the
fallback to 'DEFAULT_DOC_PATH' (though I don't think
this should be relevant anyway).

Change-Id: I629bad1d743e458191dcfa2b1371ea4b280e7b13
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113878
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-12 07:19:05 +02:00
Michael Weghorn d214ab444e android: Check result for CREATE_NEW_DOCUMENT Intent
Only try to retrieve the file URI and load the document
if a file was actually selected.

Change-Id: Icd47c197b67d593e74874e8136233b6e41a1a68d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113845
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-09 17:19:26 +02:00
Michael Weghorn 7d9db806d6 android: Request PERMISSION_WRITE_EXTERNAL_STORAGE again
Requesting the permission on app start had been dropped in

    commit a23bd42e9b
    Date:   Tue Apr 6 14:26:06 2021 +0200

        android: Drop custom file abstraction + UI

Since the app now uses the Android Storage Access Framework [1]
in order to open or create files from within the app,
it not longer needs PERMISSION_WRITE_EXTERNAL_STORAGE for this.
However, at least PDF export currently still directly writes
to local storage ("Documents" directory), which fails without
that permission being granted.

In addition, opening files passed with a 'file://' URI
in an 'Intent.ACTION_VIEW' also did not work anymore.
I'm not sure whether this use case is particularly
relevant in practice, though; at least all of the (few)
apps I used during testing passed 'content://' URIs in their
Intent.

In addition, in Android 11 (API level 30) or higher,
PERMISSION_WRITE_EXTERNAL_STORAGE no longer has any effect;
from [2]:

> More recent versions of Android rely more on a file's purpose than its
> location for determining an app's ability to access, and write to, a
> given file. In particular, if your app targets Android 11 (API level 30)
> or higher, the WRITE_EXTERNAL_STORAGE permission doesn't have any
> effect on your app's access to storage. This purpose-based storage
> model improves user privacy because apps are given access only to
> the areas of the device's file system that they actually use.
>
> Android 11 introduces the MANAGE_EXTERNAL_STORAGE permission, which
> provides write access to files outside the app-specific directory and
> MediaStore. To learn more about this permission, and why most apps don't
> need to declare it to fulfill their use cases, see the guide on how to
> manage all files [3] on a storage device.

For now, request the permission again, at least as long
as PDF export doesn't use the storage framework to
ask where to save files.
It certainly makes sense to reconsider this in the future (and decide to either
drop the permission completely or request MANAGE_EXTERNAL_STORAGE for API
level >=30).

[1] https://developer.android.com/training/data-storage/shared/documents-files
[2] https://developer.android.com/training/data-storage#permissions
[3] https://developer.android.com/training/data-storage/manage-all-files

Change-Id: Icc4c9c9b7b315d2a0b6a025439ae7e431cdd5b37
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113840
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-09 17:19:01 +02:00
Michael Weghorn 4cfcc0f48a tdf#141338 android: Make "Select file to open" view smaller
Use the same height as is used for the "Recent files"
entries.

Change-Id: Ia6c1e02507ac12b554eb042d6dd32c0fc78cb578
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113675
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-07 08:30:38 +02:00
Michael Weghorn 91eb5026f9 android: Move "Recent files" below system file picker view
Move the view that opens the system file picker when tapped
above the "Recent files" view in the Android Viewer start
activity.

Change-Id: I63ee0ea7fb784a3405877fcf5ed587ce06e8e093
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113674
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-04-07 08:30:17 +02:00