This allows flexibility on where the app gets installed,
either on internal or external storage, see [1].
Explicitly prefering external location was originally
introduced in
commit 015e1b8444
Date: Fri Jun 28 09:48:41 2013 +0200
android: prefer external storage in DocumentLoader / LibreOffice4Android
With this, these apps can be used even if /data is something like 128MB,
e.g. on normal phones, not tablets / emulators.
, but there seems to be no particular reason for that any more these
days, as either internal or external are fine (and internal
device storage tends to be larger these days as well).
For the debug build configuration, install location was
set to "internalOnly" in
commit 02119a79c1
Date: Mon Oct 13 10:19:25 2014 +0200
android: When debugging, the installLocation must be "internalOnly".
Otherwise the gdbserver ends up with
run-as: exec failed for /data/data/org.libreoffice/lib/gdbserver Error:Permission denied
(you need to run ndk-gdb with --verbose to see that).
temporarily, but then was already "auto" since
commit 66518ead51
Author: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
Date: Thu Aug 31 11:50:51 2017 +0200
use extractNativeLibs="false" for less disk usage and faster installation
[...]
also revive installLocation attribute to allow installation on external
storage and move from manifestPlaceholders from defaultConfig to release
buildType (as otherwise gradle complains about having "Multiple entries
with same key")
Using 'installLocation="auto"' is also a requirement
for the Meta Horizon Store, see [2].
[1] https://developer.android.com/guide/topics/data/install-location
[2] https://developers.meta.com/horizon/resources/publish-mobile-manifest/
Change-Id: Ie40dddbf2886f0693bcd38b7eed85916e2319343
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209420
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
(cherry picked from commit 1a18114fce)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209426
Tested-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
Aragonese currently translated at 41.3% (48 of 116 strings)
Change-Id: I87bb3a722c8456ed2a8e7304570e575d8eead692
android-viewer translated using Weblate
Aragonese currently translated at 38.7% (45 of 116 strings)
Change-Id: Ib22bb2b507e971a796a8fc63101709b3330c8cfd
android-viewer translated using Weblate
Aragonese currently translated at 37.9% (44 of 116 strings)
Change-Id: I59edf236bec8f8cd4fe2dd748529599d4f5a1931
android-viewer translated using Weblate
Aragonese currently translated at 37.0% (43 of 116 strings)
Change-Id: Ide72df61b3d6c12201bba6462058c3b7ab412708
Added translation for android-viewer using Weblate (Kurdish (Kurmanji))
Change-Id: If1128d5c39c0ce7b8a5ee28ab2606b1db95b6a51
Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
Co-authored-by: Weblate <noreply@documentfoundation.org>
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings-26-8/an/
Translation: android-viewer/android-strings-26-8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208501
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Michael Weghorn <m.weghorn@posteo.de>
As [1] says:
> As mentioned on https://issuetracker.google.com/issues/430991549 the
> error disappears if the file is included using `file()` helper, such as
> `apply(from = file("unused.gradle.kts"))`
This helps avoid the issue reported in [2]
(" Gradle task "lintAnalyzeRelease" fails with Android Gradle Plugin
9.0.0-beta02 when applying .gradle.kts files with apply(from = "...")")
otherwise seen when attempting to upgrade to Gradle 9.1.0
and Android Gradle plugin 9.3.1.
Error without this in place but a local change to upgrade Gradle:
> Task :source:lintAnalyzeStrippedUIEditingDebug FAILED
[Incubating] Problems report is available at: file:///home/michi/development/git/libreoffice-WORKTREE-android/android/build/reports/problems/problems-report.html
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':source:lintAnalyzeStrippedUIEditingDebug'.
> A failure occurred while executing com.android.build.gradle.internal.lint.AndroidLintWorkAction
> Unexpected failure during lint analysis (this is a bug in lint or one of the libraries it depends on)
Message: Unexpected failure during lint analysis (this is a bug in lint or one of the libraries it depends on)
Message: \\\`findFirCompiledSymbol\\\` only works on compiled declarations, but the given declaration is not compiled.
Stack: \`KotlinIllegalArgumentExceptionWithAttachments:LLResolutionFacade.findCompiledFirSymbol(LLResolutionFacade.kt:279)←LLResolutionFacade.resolveToFirSymbol$low_level_api_fir(LLResolutionFacade.kt:135)←LowLevelFirApiFacadeKt.resolveToFirSymbol(LowLevelFirApiFacade.kt:37)←KaFirScriptSymbol$special$$inlined$lazyFirSymbol$1.invoke(KaFirPsiSymbol.kt:346)←KaFirScriptSymbol$special$$inlined$lazyFirSymbol$1.invoke(KaFirPsiSymbol.kt:257)←SafePublicationLazyImpl.getValue(LazyJVM.kt:125)←KaFirPsiSymbol.getFirSymbol(KaFirPsiSymbol.kt:72)←KtSymbolUtilsKt.getFirSymbol(ktSymbolUtils.kt:26)←KaFirScopeProvider.getDeclaredMemberScope(KaFirScopeProvider.kt:123)←KaFirScopeProvider.getCombinedDeclaredMemberScope(KaFirScopeProvider.kt:105)←KaBaseSession.getCombinedDeclaredMemberScope(KaBaseSession.kt:-1)←SymbolLightClassUtilsKt.addPropertyBackingFields(symbolLightClassUtils.kt:454)←SymbolLightClassUtilsKt.addPropertyBackingFields$default(symbolLightClassUtils.kt:447)←SymbolLightClassForScript$getOwnFields$$inlined$cachedValue$1.compute(symbolLightUtils.kt:362)←CachedValuesManager$NonPhysicalPsiHandlerProvider.compute(CachedValuesManager.java:222)←CachedValuesManager$NonPhysicalPsiHandlerProvider.compute(CachedValuesManager.java:215)←PsiParameterizedCachedValue.doCompute(PsiParameterizedCachedValue.kt:24)←CachedValueBase.lambda$getValueWithLock$3(CachedValueBase.java:299)←CachedValueBase.computeData(CachedValueBase.java:37)←CachedValueBase.lambda$getValueWithLock$4(CachedValueBase.java:299)←RecursionManager$1.computePreventingRecursion(RecursionManager.java:113)←RecursionGuard.doPreventingRecursion(RecursionGuard.java:28)←RecursionManager.doPreventingRecursion(RecursionManager.java:68)←CachedValueBase.getValueWithLock(CachedValueBase.java:300)←PsiParameterizedCachedValue.getValue(PsiParameterizedCachedValue.kt:18)←CachedValuesManager.getParameterizedCachedValue(CachedValuesManager.java:97)←CachedValuesManager.getCachedValue(CachedValuesManager.java:212)←CachedValuesManager.getCachedValue(CachedValuesManager.java:136)←SymbolLightClassForScript.getOwnFields(SymbolLightClassForScript.kt:229)←SymbolLightClassBase.getFields(SymbolLightClassBase.kt:50)←UClass.getFields(UClass.kt:48)←KotlinScriptUClass.getFields(KotlinScriptUClass.kt:44)←AbstractKotlinUClass.getUastDeclarations(AbstractKotlinUClass.kt:34)←AbstractKotlinUClass.accept(AbstractKotlinUClass.kt:223)←ImplementationUtilsKt.acceptList(implementationUtils.kt:15)←UFile.accept(UFile.kt:89)←UastLintUtilsKt.acceptSourceFile(UastLintUtils.kt:956)←UastGradleVisitor.visitBuildScript(UastGradleVisitor.kt:43)←LintDriver$checkBuildScripts$3.run(LintDriver.kt:1402)←LintClient.runReadAction(LintClient.kt:1645)←LintCliClient.runReadAction(LintCliClient.kt:230)←LintDriver$LintClientWrapper.runReadAction(LintDriver.kt:2690)←LintDriver.checkBuildScripts(LintDriver.kt:1377)←LintDriver.runFileDetectors(LintDriver.kt:1248)←LintDriver.checkProject(LintDriver.kt:1041)←LintDriver.checkProjectRoot(LintDriver.kt:607)←LintDriver.access$checkProjectRoot(LintDriver.kt:179)←LintDriver$analyzeOnly$1.invoke(LintDriver.kt:434)←LintDriver$analyzeOnly$1.invoke(LintDriver.kt:431)←LintDriver.doAnalyze(LintDriver.kt:490)←LintDriver.analyzeOnly(LintDriver.kt:431)←LintCliClient$analyzeOnly$1.invoke(LintCliClient.kt:263)←LintCliClient$analyzeOnly$1.invoke(LintCliClient.kt:260)←LintCliClient.run(LintCliClient.kt:309)←LintCliClient.analyzeOnly(LintCliClient.kt:260)←Main.run(Main.java:1777)←Main.run(Main.java:283)←DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)←Method.invoke(Method.java:580)←AndroidLintWorkAction.invokeLintMainRunMethod(AndroidLintWorkAction.kt:103)←AndroidLintWorkAction.runLint(AndroidLintWorkAction.kt:90)←AndroidLintWorkAction.execute(AndroidLintWorkAction.kt:64)←DefaultWorkerServer.execute(DefaultWorkerServer.java:68)←NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)←NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)←ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)←NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)←AbstractWorker$1.call(AbstractWorker.java:44)←AbstractWorker$1.call(AbstractWorker.java:41)←DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)←DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)←DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)←DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)←DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)←DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)←DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)←AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)←NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)←DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)←FutureTask.run(FutureTask.java:317)←DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)←DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)←DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)←Factories$1.create(Factories.java:30)←DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)←ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)←DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)←DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)←DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)←DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)←DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)←DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)←Executors$RunnableAdapter.call(Executors.java:572)←FutureTask.run(FutureTask.java:317)←ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)←AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)←ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)←ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)←Thread.run(Thread.java:1583)\`
You can run with --stacktrace or set environment variable \`LINT_PRINT_STACKTRACE=true\` to dump a full stacktrace to stdout.
Stack: `RuntimeException:LintDriver$Companion.handleDetectorError(LintDriver.kt:3597)←LintDriver$Companion.handleDetectorError$default(LintDriver.kt:3462)←LintDriver$Companion.handleDetectorError(LintDriver.kt:3458)←LintDriver$analyzeOnly$1.invoke(LintDriver.kt:436)←LintDriver$analyzeOnly$1.invoke(LintDriver.kt:431)←LintDriver.doAnalyze(LintDriver.kt:490)←LintDriver.analyzeOnly(LintDriver.kt:431)←LintCliClient$analyzeOnly$1.invoke(LintCliClient.kt:263)←LintCliClient$analyzeOnly$1.invoke(LintCliClient.kt:260)←LintCliClient.run(LintCliClient.kt:309)←LintCliClient.analyzeOnly(LintCliClient.kt:260)←Main.run(Main.java:1777)←Main.run(Main.java:283)←DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)←Method.invoke(Method.java:580)←AndroidLintWorkAction.invokeLintMainRunMethod(AndroidLintWorkAction.kt:103)←AndroidLintWorkAction.runLint(AndroidLintWorkAction.kt:90)←AndroidLintWorkAction.execute(AndroidLintWorkAction.kt:64)←DefaultWorkerServer.execute(DefaultWorkerServer.java:68)←NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)←NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)←ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)←NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)←AbstractWorker$1.call(AbstractWorker.java:44)←AbstractWorker$1.call(AbstractWorker.java:41)←DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)←DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)←DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)←DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)←DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)←DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)←DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)←AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)←NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)←DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)←FutureTask.run(FutureTask.java:317)←DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)←DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)←DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)←Factories$1.create(Factories.java:30)←DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)←ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)←DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)←DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)←DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)←DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)←DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)←DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)←Executors$RunnableAdapter.call(Executors.java:572)←FutureTask.run(FutureTask.java:317)←ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)←AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)←ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)←ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)←Thread.run(Thread.java:1583)`
You can run with --stacktrace or set environment variable `LINT_PRINT_STACKTRACE=true` to dump a full stacktrace to stdout.
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights from a Build Scan (powered by Develocity).
> Get more help at https://help.gradle.org.
BUILD FAILED in 5m 9s
[1] https://issuetracker.google.com/issues/463283604#comment10
[2] https://issuetracker.google.com/issues/463283604
Change-Id: I5d6bbe844845f62f09458a6365142ddc374b00f8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202698
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Finnish currently translated at 71.5% (83 of 116 strings)
Change-Id: I4099d082bb18627f4d5302aad50079e226e1573b
android-viewer translated using Weblate
Finnish currently translated at 71.5% (83 of 116 strings)
Change-Id: Id43fd2592b2478d62439ebde9d24114fe625d5b0
android-viewer translated using Weblate
Finnish currently translated at 70.6% (82 of 116 strings)
Change-Id: I2ee98fcbca729572718e43d07bdaec8bd89b067c
android-viewer translated using Weblate
Finnish currently translated at 60.3% (70 of 116 strings)
Change-Id: I3f5b0b170d39451e8185fbca3a1933703e1fb599
Co-authored-by: Tommi Pukkila <tommi.pukkila@hotmail.com>
Co-authored-by: Tuomas Hietala <tuomas.hietala@iki.fi>
Co-authored-by: Weblate <noreply@documentfoundation.org>
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/fi/
Translation: android-viewer/android-strings
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201551
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Finnish currently translated at 55.1% (64 of 116 strings)
Change-Id: Iac05b2c469ca885c499d40065c4d0420f700e349
android-viewer translated using Weblate
Finnish currently translated at 54.3% (63 of 116 strings)
Change-Id: Ic244b2ae19c72883f89411243fda32e12fb66981
android-viewer translated using Weblate
Finnish currently translated at 54.3% (63 of 116 strings)
Change-Id: I443ccd1965e1bc067553fe15e04937fc8336ba9d
android-viewer translated using Weblate
Finnish currently translated at 21.5% (25 of 116 strings)
Change-Id: I997f098f42b316747cccb9d3d113c229804d4713
android-viewer translated using Weblate
Finnish currently translated at 18.1% (21 of 116 strings)
Change-Id: I3720d95673cf4bfbf3fe3115a8fc941f7e8532fd
android-viewer translated using Weblate
Finnish currently translated at 18.1% (21 of 116 strings)
Change-Id: Id67d73071369b680e25176ede9b9dace306bec27
android-viewer translated using Weblate
Finnish currently translated at 18.1% (21 of 116 strings)
Change-Id: I0481394ac021022766210f05694f5a15058f137a
Added translation for android-viewer using Weblate (Brahui)
Change-Id: Ic378423bc07625917f7af041f367d2dda73e0cbe
Co-authored-by: Erick Elizondo <erick.elizondo@gmail.com>
Co-authored-by: Hammad Mengal <hammadalo99@gmail.com>
Co-authored-by: Tommi Pukkila <tommi.pukkila@hotmail.com>
Co-authored-by: Tuomas Hietala <tuomas.hietala@iki.fi>
Co-authored-by: Weblate <noreply@documentfoundation.org>
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/fi/
Translation: android-viewer/android-strings
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200918
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
There is no reason to use a custom project structure. The usual Android
project structure makes the development of new features easier using a
modular approach. Therefore, the logic of gradle files was divided into
different levels, gradle scripts was migrated to kotlin,
dependency definitions was moved into toml file.
No one java or kotlin file has been changed.
These changes based on:
1) Android build structure:
https://developer.android.com/build/android-build-structure
2) Migrate your build to version catalogs:
https://developer.android.com/build/migrate-to-catalogs
3) Migrate your build configuration from Groovy to Kotlin
https://developer.android.com/build/migrate-to-kotlin-dsl
Note: The source module has not been renamed to app (this is the usual
name for a top-level application subproject), because I currently do not
know what other changes will need to be made besides gradle scripts
(maybe in the Makefiles or in other) for a correct build. Additional
analysis required.
Change-Id: Ic11efdb51524e795b8c6e2605b6501d9699c525c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195939
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Aragonese currently translated at 18.1% (21 of 116 strings)
Change-Id: I8b208ee3ca8661c1fc8e1e66dece7161b2c07210
android-viewer translated using Weblate
Aragonese currently translated at 15.5% (18 of 116 strings)
Change-Id: Ie203b67a347628d8242bd9dd1bf41e589ea4df65
android-viewer translated using Weblate
Kazakh currently translated at 29.3% (34 of 116 strings)
Change-Id: Iab1d7ff35baa1bde2af46b69c5172342e9eb6d23
android-viewer translated using Weblate
Kazakh currently translated at 18.9% (22 of 116 strings)
Change-Id: I33ca66d0fcadc46a8909d6c861d9fd8377c50317
android-viewer translated using Weblate
Aragonese currently translated at 3.4% (4 of 116 strings)
Change-Id: I69d66db7d7988181bc464563254222566d3efab2
Added translation for android-viewer using Weblate (Aragonese)
Change-Id: I6e8a4c7916e19b0d8645d34c14a8ff27eaaa371d
android-viewer translated using Weblate
Kazakh currently translated at 12.9% (15 of 116 strings)
Change-Id: I1667da5548709f920b8333a476a0216282385fb0
Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Baurzhan Muftakhidinov <baurthefirst@gmail.com>
Co-authored-by: Ildar Mustafin <anmitali198@gmail.com>
Co-authored-by: Weblate <noreply@documentfoundation.org>
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/an/
Translate-URL: https://translations.documentfoundation.org/projects/android-viewer/android-strings/kk/
Translation: android-viewer/android-strings
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196339
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
All settings displayed in the SettingsActivity
are related to editing, and only displayed
if the build includes the editing feature.
Therefore, don't show the settings menu item when
using a build config that doesn't include that feature,
i.e. only show the item for the strippedUIEditing
product flavor, but not the strippedUI or quest
ones. For the latter two, an activity only displaying the
"General" heading would be shown, but nothing
else could be done, which was rather confusing.
Change-Id: I2a1a616c1faee18583320ccb16e717dc933d6565
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194534
Code-Style: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Instead of having one method that enables/disables a menu
item and one that shows/hides it, let
ToolbarController.setItemVisible take care of both.
Use that method also where ToolbarController.enableMenuItem
was used before and drop that now unused method.
The way that hiding/disabling menu items was and is used
is to do that when they are not applicable, in which case
it seems reasonable to consistently both hide and disable
them at the same time.
Quoting from the MenuItem.setVisible doc [1]:
> Sets the visibility of the menu item. Even if a menu item is not
> visible, it may still be invoked via its shortcut (to completely disable
> an item, set it to invisible and disabled).
[1] https://developer.android.com/reference/android/view/MenuItem#setVisible(boolean)
Change-Id: I5d05f5324a1fb5c69e38302b59b2ad56a45342ff
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194533
Tested-by: Jenkins
Code-Style: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
For Meta Quest devices running Horizon OS, it is required
that the default activity size is set to 1024x640,
see also [1].
Add a new product flavor "quest" with an additional
AndroidManifest_quest.xml that sets the corresponding
attributes for the 2 main activities.
Due to the manifest merge logic as described at [2],
it is sufficient to only specify those extra
attributes. The rest is taken from the main
AndroidManifest.xml used for all build flavors.
This makes the LibreOffice Viewer app on a Meta Quest 3
VR headset open in the specified size in landscape mode,
while it was previously opening in a smaller window in
portrait mode.
Also, disable the experimental editing mode for that product
flavor, as it seems to be even more experimental when tested
on a Meta Quest than on another Android device.
(Document UI doesn't update while typing.)
The build flavor can either manually be selected in
Android Studio ("Build" -> "Select Build Variant")
or specified for the gradle target, e.g.
./gradlew assembleQuestRelease
[1] https://developers.meta.com/horizon/documentation/android-apps/panel-sizing
[2] https://developer.android.com/build/manage-manifests#merge-manifests
Change-Id: Ia2b234f50694553d2b3458e4c57e8bb1b1a5baa8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194532
Code-Style: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
It's the same for both product flavors, so
define it once for the main one that is the base
for both of them, and all upcoming flavors, too.
Change-Id: I0532332c0780bac5099a2d98601664b3cf709777
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194531
Tested-by: Jenkins
Code-Style: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
One issue was addressed in previous commit
Change-Id: Iafb7a32668718afc638b8273a05a9d0618f85550
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Wed Nov 19 16:36:25 2025 +0100
tdf#164082 android: Drop storage permission and support for file:// URIs
Change-Id: I1bd43717e9bd19719cb197d15c431670741d584b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194217
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
In the past, LibreOffice Viewer for Android was directly
accessing storage in order to open/save files and when
exporting to PDF.
However, that was switched to using Android's Storage
Access Framework [1], available since Android 4.4
(API level 19), i.e. it is available in all Android
versions supported by the app.
In the past, in order to directly access storage, permission
android.permission.WRITE_EXTERNAL_STORAGE was needed.
That permission no longer has any effect in
Android 11 (API level 30) or higher, quoting 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.
Since PDF export was also switched to use the
Android Storage Framework mechanism in
commit 9ebcb80e2e
Author: Michael Weghorn
Date: Thu Apr 15 11:22:46 2021 +0200
android: Ask where to save PDF file on export
, eventually drop the permission now.
As mentioned in
commit 7d9db806d6
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Fri Apr 9 11:24:16 2021 +0200
android: Request PERMISSION_WRITE_EXTERNAL_STORAGE again
which re-requested the permission before PDF export was
ported to use the Android Storage Framework, the case of
applications passing documents via a file:// URI would also
require storage permission in order to access the file.
However, apps that properly pass the file should pass a
content:// URL instead.
Quoting from the Android 7.0 Behavior changes
documentation [4]:
> Passing file:// URIs outside the package domain may leave the receiver
> with an unaccessible path. Therefore, attempts to pass a file:// URI
> trigger a FileUriExposedException. The recommended way to share the
> content of a private file is using the FileProvider.
(Using content:// URIs has been possible long before Android 7.0,
however.)
Therefore, drop support for file:// URIs as well, which
will prevent apps that would otherwise try to pass file://
URIs from trying to do that for Android Viewer.
If this results in any app no longer being able to
open documents in LibreOffice Viewer, that app most
likely needs to be adjusted to pass a content:// URI instead,
which will also make it work for newer Android versions.
(Total Commander is one case that apparently doesn't do
that yet, previously resulting in a crash when storage
permissions were not granted, see tdf#164082. That is
reproducible in an Android 7.0 AVD, while opening
the file fromm other apps, e.g. from Material Files [5],
works perfectly fine, using content:// URIs.)
Eventually dropping the permission makes clear that
the app does not need direct storage access, which is
also relevant for security reviews, and addresses this
lint issue from android/source/lint-baseline.xml:
<issue
id="ScopedStorage"
message="WRITE_EXTERNAL_STORAGE is deprecated (and is not granted) when targeting Android 13+. If you need to write to shared storage, use the `MediaStore.createWriteRequest` intent."
errorLine1=" <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="AndroidManifest.xml"
line="9"
column="36"/>
</issue>
That file will be updated/regenerated in a separate
commit.
[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
[4] https://developer.android.com/about/versions/nougat/android-7.0-changes
[5] https://f-droid.org/en/packages/me.zhanghai.android.files/
Change-Id: Iafb7a32668718afc638b8273a05a9d0618f85550
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194215
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
This android.hardware.usb.host feature element was added in
commit 5ada20b358
Author: brainbreaker <gautamprajapati06@gmail.com>
Date: Sun Feb 26 02:27:43 2017 +0530
Improve the Document Provider UX
, when it was still used for the file/document access
logic implemented in the app that was also explicitly
handling USB device support.
That one was dropped in
commit a23bd42e9b
Author: Michael Weghorn
Date: Tue Apr 6 14:26:06 2021 +0200
android: Drop custom file abstraction + UI
, so also drop this from the Android manifest.
Change-Id: Icbd8fa86d1a9a4d8dfb8fccd90846a432a329b90
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194214
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
No need to have a member for this, just pass the
param directly to the VelocityBiasStrategy ctor.
Change-Id: If8fa006afbbb082a0885cef371c89721c64eb3c6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194195
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
Regenerate the file (by removing the old one and
running a build).
This addresses the
> Task :lintReportStrippedUIEditingDebug
Lint found 1 hint (and 199 errors and 2 hints filtered by baseline lint-baseline.xml)
2 errors/warnings were listed in the baseline file (/home/michi/development/git/libreoffice-WORKTREE-android/android/source/lint-baseline.xml) but not found in the project; perhaps they have been fixed?
notice seen without this commit in place.
Change-Id: I000dc86dbf6ee5ce622f6c26fc05ad4f511ec0bd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194106
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Stop calling the method RecyclerView.setHasFixedSize
meant to allow optimiziations (see doc at [1]), because
that is not compatible with the size used in the layout
file.
This prepares for upcoming commit
Change-Id: Id22a2130379fb11372d210049b4f02df29ec52d8
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Mon Nov 17 12:56:47 2025 +0100
android: Update com.google.android.material:material to 1.13.0
which would otherwise trigger errors like this one:
> Task :lintReportStrippedUIEditingDebug
Wrote HTML report to file:///home/michi/development/git/libreoffice-WORKTREE-android/android/source/build/reports/lint-results-strippedUIEditingDebug.html
Lint found 4 errors, 1 hint (and 199 errors and 2 hints filtered by baseline lint-baseline.xml)
2 errors/warnings were listed in the baseline file (/home/michi/development/git/libreoffice-WORKTREE-android/android/source/lint-baseline.xml) but not found in the project; perhaps they have been fixed?
Lint found 4 errors and 1 hint. First failure:
/home/michi/development/git/libreoffice-WORKTREE-android/android/source/src/java/org/libreoffice/FontController.java:257: Error: When using `setHasFixedSize() in an RecyclerView, wrap_content cannot be used as a value for size in the scrolling direction. [InvalidSetHasFixedSize from androidx.recyclerview.lint.recyclerview]
recyclerView.setHasFixedSize(true);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Task :lintStrippedUIEditingDebug FAILED
[1] https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView#setHasFixedSize(boolean)
Change-Id: I34b7b88506d549aa38d06e292ce8a6e96057e619
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194105
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
See [1]:
> Currently, there are multiple ways to set a property with Groovy DSL syntax:
>
> ---
> propertyName = value
> setPropertyName(value)
> setPropertyName value
> propertyName(value)
> propertyName value
> ---
>
> The latter one, "space-assignment", is a Gradle-specific feature that is
> not part of the Groovy language. In regular Groovy, this is just a
> method call: propertyName(value), and Gradle generates propertyName
> method in the runtime if this method hasn’t been present already. This
> feature may be a source of confusion (especially for new users) and adds
> an extra layer of complexity for users and the Gradle codebase without
> providing any significant value. Sometimes, classes declare methods with
> the same name, and these may even have semantics that are different from
> a plain assignment.
>
> These generated methods are now deprecated and will be removed in Gradle
> 10.0, and both propertyName value and propertyName(value) will stop
> working unless the explicit method propertyName is defined. Use explicit
> assignment propertyName = value instead.
This addresses warnings seen during the Android Viewer build like:
> Configure project :
Build file '/home/michi/development/git/libreoffice-WORKTREE-android/android/source/build.gradle': line 19
Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated. This is scheduled to be removed in Gradle 10.0. Use assignment ('url = <value>') instead. Consult the upgrading guide for further information: https://docs.gradle.org/8.13/userguide/upgrading_version_8.html#groovy_space_assignment_syntax
at build_7nyveb4ly8p00ms61u72dhwli$_run_closure1$_closure2$_closure4.doCall$original(/home/michi/development/git/libreoffice-WORKTREE-android/android/source/build.gradle:19)
(Run with --stacktrace to get the full stack trace of this deprecation warning.)
at build_7nyveb4ly8p00ms61u72dhwli$_run_closure1$_closure2.doCall$original(/home/michi/development/git/libreoffice-WORKTREE-android/android/source/build.gradle:18)
(Run with --stacktrace to get the full stack trace of this deprecation warning.)
[1] https://docs.gradle.org/8.13/userguide/upgrading_version_8.html#groovy_space_assignment_syntax
Change-Id: I963b3a1b38912d134619293cd9197f8545ed5515
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194103
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
When the size of the app window for LibreOffice Viewer
changes (e.g. because a user manually resized the
window on a desktop device or when rotating a device),
recalculate the document position and zoom factor
to make proper use of the newly available space.
On app window resize/rotation, GeckoLayerClient sends
a LOEvent.SIZE_CHANGED event (see e.g.
GeckoLayerClient.setViewportSize).
In order to achieve the desired result, adjust the
corresponding event handler to call LOKitThread.redraw
with a `resetZoomAndPosition` param of true instead of
false.
Change-Id: I2a088975e6083ce72641c8e2ea9d111015fb50bf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193967
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Simplify this further after
Change-Id: Icae6258fa4516348dc2c8978f42024d9884216f7
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Thu Nov 13 12:40:50 2025 +0100
android: Skip (not) reading from null map
Change-Id: I1c44456bc6e5a17e2dae0c03d1dfaf54dcbbea09
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193963
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
The only caller of setPrefs passes a null param.
Therefore, drop the param and the logic that would
only have been relevant for a non-null param.
Change-Id: Icae6258fa4516348dc2c8978f42024d9884216f7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193962
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
Instead call the logic to get the main thread directly
in JavaPanZoomController.checkMainThread.
Change-Id: I5fe02ba038b0e4ea954012e2a7296f59113e1eb6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193960
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
JavaPanZoomController is the only implementation.
Use that one directly instead, which also removes
the need for some casting in GeckoLayerClient.
Change-Id: Id9c4a8ed154b66ac81274eb1648477163eb546a0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193959
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
Now with
Change-Id: If1ebe5da94d8193794cce41e052bd401e0c8adbc
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Thu Nov 13 10:59:12 2025 +0100
android: Move GeckoLayerClient.notifyReady logic to ctor
in place, the member is already set to true in the ctor,
so there's no need to check for that anymore.
Change-Id: Idb762da74ed334e9ffb56e709ec92c960bc82113
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193954
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Instead of calling the method after creating the
object, move the logic into the ctor itself.
This also allows to make a few more members final.
Change-Id: If1ebe5da94d8193794cce41e052bd401e0c8adbc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193953
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Pass the LayerView as a param to the ctor, instead
of calling GeckoLayerView.setView separately afterwards.
This also allows to make two more members final.
Change-Id: Ic3ffcde590a84fec4413ef6225aa8417e3960f84
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193950
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>