NetCipher provides the interface for starting Tor on demand. It also
provides the mechanism to upgrade the TLS settings to the best possible,
based on what each device is capable of.
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Serbian (sr) by Слободан Симић(Slobodan Simić) <slsimic@gmail.com>
Currently translated at 13.8% (5 of 36 strings)
Translated using Weblate: Serbian (sr) by Слободан Симић(Slobodan Simić) <slsimic@gmail.com>
Currently translated at 100.0% (468 of 468 strings)
Co-authored-by: Слободан Симић(Slobodan Simić) <slsimic@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/sr/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sr/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 21.5% (101 of 468 strings)
Added translation using Weblate: Frisian (fy) by vancha <tjipke@tutanota.com>
Co-authored-by: vancha <tjipke@tutanota.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fy/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Korean (ko) by Myeongjin Lee <aranet100@gmail.com>
Currently translated at 97.6% (457 of 468 strings)
Co-authored-by: Myeongjin Lee <aranet100@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ko/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (36 of 36 strings)
Translated using Weblate: German (de) by nautilusx <translate@disroot.org>
Currently translated at 100.0% (36 of 36 strings)
Co-authored-by: nautilusx <translate@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/de/
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Bengali (Bangladesh) (bn-rBD) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 94.2% (441 of 468 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 87.6% (410 of 468 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 82.9% (388 of 468 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 76.9% (360 of 468 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 64.3% (301 of 468 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 57.4% (269 of 468 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 51.7% (242 of 468 strings)
Translated using Weblate: Bengali (Bangladesh) (bn-rBD) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 29.4% (138 of 468 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 48.0% (225 of 468 strings)
Translated using Weblate: Bengali (Bangladesh) (bn-rBD) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 29.0% (136 of 468 strings)
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/bn/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/bn_BD/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Catalan (ca) by Rafael Ruiz <rafael.ruiz@upc.edu>
Currently translated at 100.0% (468 of 468 strings)
Co-authored-by: Rafael Ruiz <rafael.ruiz@upc.edu>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ca/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Portuguese (pt) by ssantos <ssantos@web.de>
Currently translated at 100.0% (36 of 36 strings)
Translated using Weblate: Portuguese (pt) by ssantos <ssantos@web.de>
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Portuguese (Portugal) (pt-PT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (36 of 36 strings)
Translated using Weblate: Portuguese (Portugal) (pt-rPT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (468 of 468 strings)
Co-authored-by: ssantos <ssantos@web.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pt_PT/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt_PT/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Arabic (ar) by Rex_sa <rex.sa@pm.me>
Currently translated at 100.0% (468 of 468 strings)
Co-authored-by: Rex_sa <rex.sa@pm.me>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ar/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>
Currently translated at 100.0% (468 of 468 strings)
Co-authored-by: bruh <quangtrung02hn16@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/vi/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk <igor_ck@outlook.com>
Currently translated at 100.0% (36 of 36 strings)
Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk <igor_ck@outlook.com>
Currently translated at 100.0% (468 of 468 strings)
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/uk/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/uk/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: Esperanto (eo) by ☆Verdulo <tomek@disroot.org>
Currently translated at 100.0% (36 of 36 strings)
Translated using Weblate: Esperanto (eo) by ☆Verdulo <tomek@disroot.org>
Currently translated at 100.0% (468 of 468 strings)
Co-authored-by: ☆Verdulo <tomek@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/eo/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/eo/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: German (de) by VfBFan <drop0815@posteo.de>
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: German (de) by VfBFan <drop0815@posteo.de>
Currently translated at 100.0% (468 of 468 strings)
Translated using Weblate: German (de) by VfBFan <drop0815@posteo.de>
Currently translated at 100.0% (468 of 468 strings)
Co-authored-by: VfBFan <drop0815@posteo.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/de/
Translation: F-Droid/F-Droid
* origin/fix-icon:
use Android Studio default Ctrl-Alt-L to format all AndroidManifest.xml
fully separate "Last Updated" icon from "Versions"
purge unused AboutActivity
fdroid/fdroidclient!1001
Currently translated at 100.0% (466 of 466 strings)
Translated using Weblate: Swedish (sv) by Jonatan Nyberg <jonatan.nyberg.karl@gmail.com>
Currently translated at 99.3% (463 of 466 strings)
Co-authored-by: Jonatan Nyberg <jonatan.nyberg.karl@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sv/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (466 of 466 strings)
Translated using Weblate: German (de) by J. Lavoie <j.lavoie@net-c.ca>
Currently translated at 100.0% (466 of 466 strings)
Translated using Weblate: German (de) by J. Lavoie <j.lavoie@net-c.ca>
Currently translated at 100.0% (466 of 466 strings)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/de/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/en_GB/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (466 of 466 strings)
Translated using Weblate: Esperanto (eo) by Verdulo <tomek@disroot.org>
Currently translated at 100.0% (466 of 466 strings)
Co-authored-by: Verdulo <tomek@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/eo/
Translation: F-Droid/F-Droid
Currently translated at 46.3% (216 of 466 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 46.7% (217 of 464 strings)
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/bn/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (466 of 466 strings)
Translated using Weblate: Russian (ru) by Andrey <andrey@mailbox.org>
Currently translated at 100.0% (466 of 466 strings)
Translated using Weblate: Russian (ru) by Andrey <andrey@mailbox.org>
Currently translated at 100.0% (36 of 36 strings)
Co-authored-by: Andrey <andrey@mailbox.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/ru/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ru/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
The system partition repos like shipped with CalyxOS are not really visible
to the user, they are built-in. So they should not prevent the warning
banner showing when the user has switched Over Data and Over WiFi to never.
Currently translated at 13.1% (61 of 464 strings)
Added translation using Weblate: Luxembourgish (lb) by Jeff <jeff.croise@gmail.com>
Co-authored-by: Jeff <jeff.croise@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/lb/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: Turkish (tr) by Orhan <orya@pm.me>
Currently translated at 100.0% (464 of 464 strings)
Co-authored-by: Orhan <orya@pm.me>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/tr/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: French (fr) by J. Lavoie <j.lavoie@net-c.ca>
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: German (de) by J. Lavoie <j.lavoie@net-c.ca>
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: French (fr) by J. Lavoie <j.lavoie@net-c.ca>
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: French (fr) by J. Lavoie <j.lavoie@net-c.ca>
Currently translated at 99.7% (463 of 464 strings)
Translated using Weblate: French (fr) by J. Lavoie <j.lavoie@net-c.ca>
Currently translated at 99.5% (462 of 464 strings)
Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/de/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fr/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/it/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (35 of 35 strings)
Translated using Weblate: Albanian (sq) by Besnik Bleta <besnik@programeshqip.org>
Currently translated at 94.2% (33 of 35 strings)
Translated using Weblate: Albanian (sq) by Besnik Bleta <besnik@programeshqip.org>
Currently translated at 100.0% (464 of 464 strings)
Co-authored-by: Besnik Bleta <besnik@programeshqip.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/sq/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sq/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 37.0% (172 of 464 strings)
Translated using Weblate: Thai (th) by Pharadai <film041127@gmail.com>
Currently translated at 36.4% (169 of 464 strings)
Co-authored-by: Pharadai <film041127@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/th/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: French (fr) by lilim <lionel@les-miquelots.net>
Currently translated at 99.7% (463 of 464 strings)
Translated using Weblate: French (fr) by lilim <lionel@les-miquelots.net>
Currently translated at 99.5% (462 of 464 strings)
Translated using Weblate: French (fr) by lilim <lionel@les-miquelots.net>
Currently translated at 99.1% (460 of 464 strings)
Translated using Weblate: French (fr) by lilim <lionel@les-miquelots.net>
Currently translated at 98.9% (459 of 464 strings)
Co-authored-by: lilim <lionel@les-miquelots.net>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fr/
Translation: F-Droid/F-Droid
Currently translated at 40.0% (14 of 35 strings)
Translated using Weblate: Romanian (ro) by Christian Eichert <c@zp1.net>
Currently translated at 31.4% (11 of 35 strings)
Translated using Weblate: Romanian (ro) by Christian Eichert <c@zp1.net>
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: German (de) by Christian Eichert <c@zp1.net>
Currently translated at 100.0% (464 of 464 strings)
Co-authored-by: Christian Eichert <c@zp1.net>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/ro/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/de/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ro/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>
Currently translated at 100.0% (464 of 464 strings)
Co-authored-by: bruh <quangtrung02hn16@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/vi/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: Greek (el) by Michalis <michalisntovas@yahoo.gr>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Michalis <michalisntovas@yahoo.gr>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/el/
Translation: F-Droid/F-Droid
Currently translated at 98.2% (456 of 464 strings)
Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: bruh <quangtrung02hn16@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/vi/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: Bulgarian (bg) by 109247019824 <stoyan@gmx.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: 109247019824 <stoyan@gmx.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/bg/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: Portuguese (Portugal) (pt-rPT) by Sérgio Marques <smarquespt@gmail.com>
Currently translated at 100.0% (464 of 464 strings)
Translated using Weblate: Portuguese (Portugal) (pt-rPT) by Sérgio Marques <smarquespt@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Portuguese (pt) by Sérgio Marques <smarquespt@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Sérgio Marques <smarquespt@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt_PT/
Translation: F-Droid/F-Droid
Currently translated at 27.9% (127 of 455 strings)
Translated using Weblate: Tibetan (bo) by Hans-Christoph Steiner <hans@guardianproject.info>
Currently translated at 69.2% (315 of 455 strings)
Translated using Weblate: Armenian (hy) by Hans-Christoph Steiner <hans@guardianproject.info>
Currently translated at 50.5% (230 of 455 strings)
Translated using Weblate: Burmese (my) by Hans-Christoph Steiner <hans@guardianproject.info>
Currently translated at 45.9% (209 of 455 strings)
Translated using Weblate: Arabic (ar) by Hans-Christoph Steiner <hans@guardianproject.info>
Currently translated at 100.0% (455 of 455 strings)
Deleted translation using Weblate: English (United States) (en_US@rude) (b+en+US@rude)
Co-authored-by: Hans-Christoph Steiner <hans@guardianproject.info>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ar/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/bn_BD/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/bo/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/hy/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/my/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>
Currently translated at 5.7% (2 of 35 strings)
Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>
Currently translated at 95.6% (435 of 455 strings)
Co-authored-by: bruh <quangtrung02hn16@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/vi/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/vi/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 2.6% (12 of 455 strings)
Added translation using Weblate: Sinhala (si) by HelaBasa <R45XvezA@protonmail.ch>
Co-authored-by: HelaBasa <R45XvezA@protonmail.ch>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/si/
Translation: F-Droid/F-Droid
refs #1869
Script to test this in an emulator with `adb root` in `adb shell`:
```bash
cd /data/data/org.fdroid.fdroid.debug/files
rm -f fake.apk; touch fake.apk; chown u0_a159.u0_a159 fake.apk ; dd if=/dev/zero of=fake.apk bs=1M count=635; touch -d 2020-02-02 fake.apk ; df -h; ls -lh
```
<
* privService-getInstalledPackages:
fail fast if privService.getInstalledPackages() isn't working
code formatting using Android Studio 4.1.2 defaults w/ 118 line length
Guard new privileged extension package manager query with API check
Add shared library packages to app cache database using F-DroidPrivilegedExtension query
fdroid/fdroidclient!967
If `privService.getInstalledPackages()` throws something other than a
`RemoteException`, this should fail as fast as possible. Crashing will give
users a prompt to send the crash report. using `finally` will just cause
weirdness since it might try to execute `compareToPackageManager()` even
when it is in the process of crashing.
Currently translated at 100.0% (35 of 35 strings)
Translated using Weblate: Norwegian Nynorsk (nn) by Karl Ove Hufthammer <karl@huftis.org>
Currently translated at 97.1% (34 of 35 strings)
Translated using Weblate: Norwegian Nynorsk (nn) by Karl Ove Hufthammer <karl@huftis.org>
Currently translated at 88.2% (30 of 34 strings)
Translated using Weblate: Norwegian Nynorsk (nn) by Karl Ove Hufthammer <karl@huftis.org>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Karl Ove Hufthammer <karl@huftis.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/nn/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/nn/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Turkish (tr) by hayalci hayalci <gokdenizk@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: hayalci hayalci <gokdenizk@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/tr/
Translation: F-Droid/F-Droid
Currently translated at 17.1% (6 of 35 strings)
Translated using Weblate: Greek (el) by Michalis <michalisntovas@yahoo.gr>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Greek (el) by Michalis <michalisntovas@yahoo.gr>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Greek (el) by Michalis <michalisntovas@yahoo.gr>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Greek (el) by Michalis <michalisntovas@yahoo.gr>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Greek (el) by Michalis <michalisntovas@yahoo.gr>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Michalis <michalisntovas@yahoo.gr>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/el/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/el/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 54.5% (18 of 33 strings)
Translated using Weblate: Spanish (es) by Jo <joaquinfc@protonmail.com>
Currently translated at 54.5% (18 of 33 strings)
Co-authored-by: Jo <joaquinfc@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/es/
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Turkish (tr) by <hgebel@yandex.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: <hgebel@yandex.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/tr/
Translation: F-Droid/F-Droid
Currently translated at 1.5% (7 of 455 strings)
Added translation using Weblate: Occitan (oc) by Quentin PAGÈS <quentinantonin@free.fr>
Co-authored-by: Quentin PAGÈS <quentinantonin@free.fr>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/oc/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Turkish (tr) by Oğuz Ersen <oguzersen@protonmail.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/tr/
Translation: F-Droid/F-Droid
Currently translated at 38.6% (176 of 455 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 34.9% (159 of 455 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 10.5% (48 of 455 strings)
Translated using Weblate: Bengali (Bangladesh) (bn-rBD) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 26.8% (122 of 455 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 7.0% (32 of 455 strings)
Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
Currently translated at 2.1% (10 of 455 strings)
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/bn/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/bn_BD/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Russian (ru) by Andrey <andrey@mailbox.org>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Andrey <andrey@mailbox.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ru/
Translation: F-Droid/F-Droid
Currently translated at 10.5% (48 of 455 strings)
Added translation using Weblate: Nepali (ne) by Naveen Niraula <subtlenv@gmail.com>
Co-authored-by: Naveen Niraula <subtlenv@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ne/
Translation: F-Droid/F-Droid
Currently translated at 14.7% (67 of 455 strings)
Translated using Weblate: Somali (so) by Nadir Nour <dudethatwascool2@gmail.com>
Currently translated at 8.5% (39 of 455 strings)
Added translation using Weblate: Somali (so) by Nadir Nour <dudethatwascool2@gmail.com>
Co-authored-by: Nadir Nour <dudethatwascool2@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/so/
Translation: F-Droid/F-Droid
Currently translated at 13.4% (61 of 455 strings)
Translated using Weblate: Pashto (ps) by ورکنومی <wraknumay@pm.me>
Currently translated at 8.5% (39 of 455 strings)
Added translation using Weblate: Pashto (ps) by ورکنومی <wraknumay@pm.me>
Co-authored-by: ورکنومی <wraknumay@pm.me>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ps/
Translation: F-Droid/F-Droid
* tag 'mergeeme':
remove unused import
Fixed bug package signature info not included
Changed to static property
Fixed "apply suggestion" error
Replaced `equalsIgnoreCase()` with `equals()`
Apply 1 suggestion(s) to 1 file(s)
Added check platform signature available
fdroid/fdroidclient!943
Currently translated at 100.0% (34 of 34 strings)
Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk <igor_ck@outlook.com>
Currently translated at 100.0% (33 of 33 strings)
Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk <igor_ck@outlook.com>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk <igor_ck@outlook.com>
Currently translated at 100.0% (33 of 33 strings)
Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk <igor_ck@outlook.com>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk <igor_ck@outlook.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/uk/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/uk/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (34 of 34 strings)
Translated using Weblate: Polish (pl) by WaldiS <sto@tutanota.de>
Currently translated at 100.0% (33 of 33 strings)
Co-authored-by: WaldiS <sto@tutanota.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pl/
Translation: F-Droid/F-Droid metadata
To further the goal of providing a fully localized experience based on the
user's Language Settings, this applies similar logic as the Latest Tab to
the apps that are featured for each category.
* commit 'a81140be4749189861b2961f84e2704eb5bb467b':
run Android Studio default code formatter with Ctrl-Alt-L
Add Repo.getFileUrl() method to get file URL in a standard way
RepoUrlsTest: Add new tests for correct repo URL formatting
fdroid/fdroidclient!935
* origin/master:
gitlab-ci: fix excluding @LargeTest from emulator jobs
use TAG to identify CleanCacheWorker to WorkManager
add WorkManagerTestRule to CleanCacheWorkerTest
move static helper method into its class: CleanCacheWorker
fdroidclient does not use variables for gradle dependencies
Add WorkManagerTestRule.
Use WorkManager to clean the cache.
Add AndroidX WorkManager.
fdroid/fdroidclient!959
If the job is successful, it should finish without coming closes to
the timeout. Extending the timeout will make it take longer to fail,
but since the job is flaky, and the related code is rarely touched, it
seems worth it.
https://gitlab.com/fdroid/ci-images-client/-/jobs/957371759
```
A fatal error has been detected by the Java Runtime Environment:
SIGSEGV (0xb) at pc=0x00007f6775b513c0, pid=1923, tid=0x00007f675eef6700
JRE version: OpenJDK Runtime Environment (8.0_275-b01) (build 1.8.0_275-8u275-b01-1~deb9u1-b01)
Java VM: OpenJDK 64-Bit Server VM (25.275-b01 mixed mode linux-amd64 compressed oops)
Problematic frame:
V [libjvm.so+0x92d3c0]
Core dump written. Default location: /builds/test/fdroidclient/app/core or core.1923
An error report file with more information is saved as:
/builds/test/fdroidclient/app/hs_err_pid1923.log
Compiler replay data is saved as:
/builds/test/fdroidclient/app/replay_pid1923.log
If you would like to submit a bug report, please visit:
http://bugreport.java.com/bugreport/crash.jsp
```
Currently translated at 99.1% (451 of 455 strings)
Translated using Weblate: Albanian (sq) by Besnik Bleta <besnik@programeshqip.org>
Currently translated at 99.7% (454 of 455 strings)
Co-authored-by: Besnik Bleta <besnik@programeshqip.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sq/
Translation: F-Droid/F-Droid
Added translation using Weblate: English (United Kingdom) (en-rGB) by Chris Jr Williams <chrisjr4eva1987@gmail.com>
Co-authored-by: Chris Jr Williams <chrisjr4eva1987@gmail.com>
Currently translated at 72.7% (331 of 455 strings)
Translated using Weblate: Marathi (mr) by Mahem Jadhav <mahem4ever@gmail.com>
Currently translated at 54.5% (248 of 455 strings)
Translated using Weblate: Marathi (mr) by Mahem Jadhav <mahem4ever@gmail.com>
Currently translated at 37.1% (169 of 455 strings)
Translated using Weblate: Marathi (mr) by Mahem Jadhav <mahem4ever@gmail.com>
Currently translated at 37.8% (172 of 455 strings)
Added translation using Weblate: Marathi (mr) by Mahem Jadhav <mahem4ever@gmail.com>
Co-authored-by: Mahem Jadhav <mahem4ever@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/mr/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Swedish (sv) by Jonatan Nyberg <jonatan.nyberg.karl@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Swedish (sv) by Jonatan Nyberg <jonatan.nyberg.karl@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Jonatan Nyberg <jonatan.nyberg.karl@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sv/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Gontzal Manuel Pujana Onaindia <thadahdenyse@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/eu/
Translation: F-Droid/F-Droid
Currently translated at 72.3% (329 of 455 strings)
Translated using Weblate: Lithuanian (lt) by Moo <hazap@hotmail.com>
Currently translated at 71.8% (327 of 455 strings)
Translated using Weblate: Lithuanian (lt) by Moo <hazap@hotmail.com>
Currently translated at 6.2% (2 of 32 strings)
Translated using Weblate: Lithuanian (lt) by Moo <hazap@hotmail.com>
Currently translated at 72.0% (328 of 455 strings)
Co-authored-by: Moo <hazap@hotmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/lt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/lt/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Italian (it) by x <hardwired1.0@protonmail.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: x <hardwired1.0@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/it/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Italian (it) by Massimiliano Caniparoli <massic80@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Massimiliano Caniparoli <massic80@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/it/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (32 of 32 strings)
Translated using Weblate: Hebrew (he) by Yaron Shahrabani <sh.yaron@gmail.com>
Currently translated at 100.0% (32 of 32 strings)
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/he/
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Esperanto (eo) by Verdulo <tomek@disroot.org>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Esperanto (eo) by Verdulo <tomek@disroot.org>
Currently translated at 100.0% (32 of 32 strings)
Co-authored-by: Verdulo <tomek@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/eo/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/eo/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
This means that sometimes the NearbyView is updated from a
BroadcastReceiver's Context, which is not an Activity. So this has to
try a little harder to fetch the Activity instance needed for the
prompt to request permissions to a folder on the USB. This adds a
failsafe to fallback to the file:/// scanning in SDCardScannerService.
The USB-OTG device can be plugged and unplugged anytime, so the Nearby view
should be updated each time the user switches to this screen. Registered
callbacks should handle updating the USB-OTG status while the Nearby view
is active.
This disables the verification of .pom files. .pom files can add
dependencies, so it would be good to have them verified. But since this
current setup requires all JAR to be verified, any new dependencies would
fail anyway:
https://docs.gradle.org/current/userguide/dependency_verification.html#sec:disabling-metadata-verification
In some cases everything works fine, like on gitlab-ci, and in other places
it always gives errors like this:
```
A problem occurred configuring root project 'client'.
> Dependency verification failed for configuration ':classpath'
4 artifacts failed verification:
- all-1.2.0.pom (com.sun.activation:all:1.2.0) from repository MavenRepo
- jvnet-parent-1.pom (net.java:jvnet-parent:1) from repository MavenRepo
- oss-parent-7.pom (org.sonatype.oss:oss-parent:7) from repository MavenRepo
- oss-parent-9.pom (org.sonatype.oss:oss-parent:9) from repository MavenRepo
This can indicate that a dependency has been compromised. Please carefully verify the checksums.
Open this report for more details: file:///home/hans/code/fdroid/client/build/reports/dependency-verification/at-1603359642220/dependency-verification-report.html
```
@glennmen and @eighthave both are getting that error.
* fdroidserver uses case-sensitive naming since it is based on GNU/Linux
filesystems, which are case-sensitive by default.
* "the application ID looks like a traditional Java package name, the naming
rules for the application ID are a bit more restrictive"
https://developer.android.com/studio/build/application-id
* Java is a case-sensitive language for all names used in .java files:
"In the Java programming universe, case-sensitive String keys are ubiquitous"
"Java package names... are case-sensitive"
https://docs.oracle.com/javase/8/docs/technotes/guides/preferences/designfaq.html
Currently translated at 3.2% (1 of 31 strings)
Translated using Weblate: Central Atlas Tamazight (tzm) by Hakim Oubouali <hakim.oubouali.skr@gmail.com>
Currently translated at 29.6% (135 of 455 strings)
Translated using Weblate: Central Atlas Tamazight (tzm) by Hakim Oubouali <hakim.oubouali.skr@gmail.com>
Currently translated at 28.1% (128 of 455 strings)
Translated using Weblate: Central Atlas Tamazight (tzm) by Hakim Oubouali <hakim.oubouali.skr@gmail.com>
Currently translated at 6.5% (30 of 455 strings)
Co-authored-by: Hakim Oubouali <hakim.oubouali.skr@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/tzm/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/tzm/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: French (fr) by Ldm Public <ldmpub@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: Ldm Public <ldmpub@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fr/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (31 of 31 strings)
Translated using Weblate: Portuguese (Portugal) (pt-PT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (31 of 31 strings)
Translated using Weblate: Portuguese (pt) by ssantos <ssantos@web.de>
Currently translated at 96.7% (30 of 31 strings)
Translated using Weblate: Portuguese (pt) by ssantos <ssantos@web.de>
Currently translated at 100.0% (455 of 455 strings)
Co-authored-by: ssantos <ssantos@web.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pt_PT/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
OsmAnd will import map files from a file:// URL pointing to an OBF file,
but this currently only works for file:// and not the proper content://.
This uses a hack to disable the warning about file:// URIs but only for the
final stage of installing the .obf file.
Hopefully in the future, this can be changed to use a proper content:// URL
as I suggested to them in this merge request:
https://github.com/osmandapp/OsmAnd/pull/10043
Use Mockito to mock LocaleList rather than changing App.java. The only
reliably working emulator tests on gitlab-ci are emulator-22. The change to
App.java in 3406edefcd1807cc9352589ac86dbb725c3165b0 broke there:
E/ACRA ( 2231): Caused by: java.lang.NoClassDefFoundError: android.os.LocaleList
E/ACRA ( 2231): at libcore.reflect.InternalNames.getClass(InternalNames.java:55)
E/ACRA ( 2231): at java.lang.Class.getDexCacheType(Class.java:479)
E/ACRA ( 2231): at java.lang.reflect.ArtMethod.getDexCacheType(ArtMethod.java:191)
E/ACRA ( 2231): at java.lang.reflect.ArtMethod.getReturnType(ArtMethod.java:145)
E/ACRA ( 2231): at java.lang.reflect.Method.getReturnType(Method.java:184)
E/ACRA ( 2231): at java.lang.Class.getDeclaredMethods(Class.java:771)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.util.ClassUtil.getClassMethods(ClassUtil.java:1172)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.AnnotatedMethodCollector._addMemberMethods(AnnotatedMethodCollector.java:117)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.AnnotatedMethodCollector.collect(AnnotatedMethodCollector.java:49)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.AnnotatedMethodCollector.collectMethods(AnnotatedMethodCollector.java:40)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.AnnotatedClass._methods(AnnotatedClass.java:382)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.AnnotatedClass.memberMethods(AnnotatedClass.java:322)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addMethods(POJOPropertiesCollector.java:555)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:323)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getPropertyMap(POJOPropertiesCollector.java:287)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getProperties(POJOPropertiesCollector.java:186)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.BasicBeanDescription._properties(BasicBeanDescription.java:164)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findProperties(BasicBeanDescription.java:239)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._findCreatorsFromProperties(BasicDeserializerFactory.java:292)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:276)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:224)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:220)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:143)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:414)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:458)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.createContextual(ObjectArrayDeserializer.java:128)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:696)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:496)
E/ACRA ( 2231): at com.fasterxml.jackson.databind.Objec
In the case where a non-standard region has been set for the primary
system language, the secondary locale will be used for localized
strings when available instead of the expected primary language.
For example, set system locales to [en-SE, ja-JP], that is English
with region Sweden, and Japanese with region Japan, most apps will
display English descriptions but those which have a Japanese
translation will display that instead.
This commit adds a fallback case for when the primary locale has not
matched any translations, but it's language part does.
Currently translated at 6.6% (2 of 30 strings)
Translated using Weblate: Belarusian (be) by Zmicer Turok <nashtlumach@gmail.com>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Belarusian (be) by Zmicer Turok <nashtlumach@gmail.com>
Currently translated at 98.4% (448 of 455 strings)
Co-authored-by: Zmicer Turok <nashtlumach@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/be/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/be/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Czech (cs) by zeritti <woodenmo@posteo.de>
Currently translated at 99.5% (453 of 455 strings)
Co-authored-by: zeritti <woodenmo@posteo.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/cs/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: French (fr) by Ldm Public <ldmpub@gmail.com>
Currently translated at 99.1% (451 of 455 strings)
Co-authored-by: Ldm Public <ldmpub@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fr/
Translation: F-Droid/F-Droid
Currently translated at 3.3% (1 of 30 strings)
Translated using Weblate: Lithuanian (lt) by Kornelijus Tvarijanavičius <kornelitvari@protonmail.com>
Currently translated at 73.7% (331 of 449 strings)
Co-authored-by: Kornelijus Tvarijanavičius <kornelitvari@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/lt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/lt/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Indonesian (id) by Adiitya Andre <adiiit.and@gmail.com>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Adiitya Andre <adiiit.and@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/id/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Ukrainian (uk) by ihor_ck <igor_ck@outlook.com>
Currently translated at 100.0% (30 of 30 strings)
Translated using Weblate: Ukrainian (uk) by ihor_ck <igor_ck@outlook.com>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: ihor_ck <igor_ck@outlook.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/uk/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/uk/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Hebrew (he) by Yaron Shahrabani <sh.yaron@gmail.com>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/he/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Spanish (es) by Crisalis <tegaminorune@disroot.org>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Crisalis <tegaminorune@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/es/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Icelandic (is) by Sveinn í Felli <sv1@fellsnet.is>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Sveinn í Felli <sv1@fellsnet.is>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/is/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Japanese (ja) by ーーー <nnn1590@nnn1590.org>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: ーーー <nnn1590@nnn1590.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ja/
Translation: F-Droid/F-Droid
Currently translated at 62.5% (281 of 449 strings)
Translated using Weblate: Kabyle (kab) by Selyan Sliman Amiri <selyan.kab@gmail.com>
Currently translated at 61.9% (278 of 449 strings)
Co-authored-by: Selyan Sliman Amiri <selyan.kab@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/kab/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Portuguese (Portugal) (pt-rPT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Portuguese (pt) by ssantos <ssantos@web.de>
Currently translated at 100.0% (30 of 30 strings)
Translated using Weblate: Portuguese (pt) by ssantos <ssantos@web.de>
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Portuguese (Portugal) (pt-rPT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Portuguese (Portugal) (pt-PT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (30 of 30 strings)
Co-authored-by: ssantos <ssantos@web.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pt_PT/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt_PT/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 43.6% (196 of 449 strings)
Translated using Weblate: Macedonian (mk) by primarto24c8a9c6889c407b <prodavac3@protonmail.com>
Currently translated at 40.5% (182 of 449 strings)
Co-authored-by: primarto24c8a9c6889c407b <prodavac3@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/mk/
Translation: F-Droid/F-Droid
Currently translated at 99.5% (453 of 455 strings)
Translated using Weblate: Norwegian Bokmål (nb) by Allan Nordhøy <epost@anotheragency.no>
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Swedish (sv) by Allan Nordhøy <epost@anotheragency.no>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sv/
Translation: F-Droid/F-Droid
Currently translated at 20.7% (93 of 449 strings)
Translated using Weblate: Berber (ber) by Hakim Oubouali <hakim.oubouali.skr@gmail.com>
Currently translated at 17.5% (79 of 449 strings)
Translated using Weblate: Berber (ber) by Hakim Oubouali <hakim.oubouali.skr@gmail.com>
Currently translated at 7.3% (33 of 449 strings)
Translated using Weblate: Berber (ber) by Hakim Oubouali <hakim.oubouali.skr@gmail.com>
Currently translated at 6.6% (30 of 449 strings)
Added translation using Weblate: Berber (ber) by Hakim Oubouali <hakim.oubouali.skr@gmail.com>
Co-authored-by: Hakim Oubouali <hakim.oubouali.skr@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ber/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Swedish (sv) by Jonatan Nyberg <jonatan.nyberg.karl@gmail.com>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Jonatan Nyberg <jonatan.nyberg.karl@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sv/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Estonian (et) by Priit Jõerüüt <hwlate@joeruut.com>
Currently translated at 23.3% (7 of 30 strings)
Translated using Weblate: Estonian (et) by Priit Jõerüüt <hwlate@joeruut.com>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Priit Jõerüüt <hwlate@joeruut.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/et/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/et/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Chinese (Traditional) (zh-rTW) by Jeff Huang <s8321414@gmail.com>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Jeff Huang <s8321414@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/zh_Hant/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Romanian (ro) by Licaon Kter <licaon.kter@protonmail.com>
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Romanian (ro) by Licaon Kter <licaon.kter@protonmail.com>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Licaon Kter <licaon.kter@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ro/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (455 of 455 strings)
Translated using Weblate: Esperanto (eo) by Verdulo <tomek@disroot.org>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: Verdulo <tomek@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/eo/
Translation: F-Droid/F-Droid
It turns out that some of the dependencies in the Google Offline Components
downloadable maven repository have difference to the ones Google publishes
to maven.google.com. WTF. In any case, the new Gradle Dependency
Verification feature handles this gracefully. I manually verified the
diffs between the two using diffoscope. One just differed by timestamps in
the ZIP header, and the other just differed by linefeeds at the end of the
file. Then I generated this metadata update using:
`./gradlew --write-verification-metadata pgp,sha256`
* https://developer.android.com/studio#offline
This fully replaces gradle-witness and goes far beyond what it offered. As
far as I can tell, this actually will verify every single artifact that
gradle downloads and uses.
This was generated in two passes to get both the PGP and the SHA256 info:
```
./gradlew --write-verification-metadata pgp,sha256 build connectedFullDebugAndroidTest --export-keys
./gradlew --write-verification-metadata sha256 build connectedFullDebugAndroidTest
```
Thanks to @vlsi who made me aware of this, and helped make it possible.
closes!837
Currently translated at 99.7% (448 of 449 strings)
Translated using Weblate: Dutch (nl) by 40e3004b-a296-47bd-a073-3dd8af36f77f <40e3004b-a296-47bd-a073-3dd8af36f77f@anonaddy.me>
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Flemish (nl-rBE) by 40e3004b-a296-47bd-a073-3dd8af36f77f <40e3004b-a296-47bd-a073-3dd8af36f77f@anonaddy.me>
Currently translated at 99.7% (448 of 449 strings)
Translated using Weblate: Dutch (nl) by 40e3004b-a296-47bd-a073-3dd8af36f77f <40e3004b-a296-47bd-a073-3dd8af36f77f@anonaddy.me>
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: French (fr) by 40e3004b-a296-47bd-a073-3dd8af36f77f <40e3004b-a296-47bd-a073-3dd8af36f77f@anonaddy.me>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: 40e3004b-a296-47bd-a073-3dd8af36f77f <40e3004b-a296-47bd-a073-3dd8af36f77f@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fr/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/nl/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/nl_BE/
Translation: F-Droid/F-Droid
Currently translated at 100.0% (30 of 30 strings)
Translated using Weblate: Portuguese (pt) by ssantos <ssantos@web.de>
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Portuguese (Portugal) (pt-PT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (30 of 30 strings)
Translated using Weblate: Portuguese (Portugal) (pt-rPT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Portuguese (Portugal) (pt-PT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (30 of 30 strings)
Translated using Weblate: Portuguese (Portugal) (pt-rPT) by ssantos <ssantos@web.de>
Currently translated at 100.0% (449 of 449 strings)
Translated using Weblate: Portuguese (pt) by ssantos <ssantos@web.de>
Currently translated at 100.0% (30 of 30 strings)
Co-authored-by: ssantos <ssantos@web.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pt_PT/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt_PT/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Currently translated at 100.0% (30 of 30 strings)
Translated using Weblate: Polish (pl) by WaldiS <sto@tutanota.de>
Currently translated at 100.0% (30 of 30 strings)
Translated using Weblate: Polish (pl) by WaldiS <sto@tutanota.de>
Currently translated at 96.6% (29 of 30 strings)
Translated using Weblate: Polish (pl) by WaldiS <sto@tutanota.de>
Currently translated at 100.0% (449 of 449 strings)
Co-authored-by: WaldiS <sto@tutanota.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/pl/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pl/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
Updated by "Squash Git commits" hook in Weblate.
Translated using Weblate: Ukrainian (uk) by ihor_ck <igor_ck@outlook.com>
Currently translated at 100.0% (30 of 30 strings)
Translated using Weblate: Ukrainian (uk) by ihor_ck <igor_ck@outlook.com>
Currently translated at 83.3% (25 of 30 strings)
Translated using Weblate: Ukrainian (uk) by ihor_ck <igor_ck@outlook.com>
Currently translated at 80.0% (24 of 30 strings)
Translated using Weblate: Chinese (Simplified) (zh-CN) by kak mi <wavelake@outlook.com>
Currently translated at 100.0% (30 of 30 strings)
Translated using Weblate: Esperanto (eo) by Verdulo <tomek@disroot.org>
Currently translated at 100.0% (30 of 30 strings)
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/eo/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/uk/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/zh_Hans/
Translation: F-Droid/F-Droid metadata
- remove constants annotation
- Most @Implementation methods in shadow classes are now protected instead of public.
Tests should always prefer to call SDK methods directly on Android classes rather
than on their shadows
We need compileSdk 28 and the required AGP and gradle versions, as well
as updating to compatible support library revisions.
minSdk and targetSdk needs to move to build.gradle from manifest.
buildToolsVersion isn't used anymore.
The autoVerify function seems to require that the app only declare domain
names in the IntentFilters that are set up with the "site association"
files. For F-Droid to support the verified app link, it would have to stop
matching play.google.com, amazon.com, etc. This autoVerify function also
triggers DNS lookups at the system level, which might not be forwarded over
Tor, in certain scenarios. So this just disables the whole feature.
https://developer.android.com/training/app-links/verify-site-associations
Liberapay was originally included using a numeric ID, since they had not yet
finalized the public URLs. Now it is a username. So this logic prefers
the username in Liberapay: field, and uses the old LiberapayID: as a
fallback. LiberapayID: will not override Liberapay: if it is already set.
This reuses the old database key since it is stored and processed as a
String anyway.
This was already done for list views because of the panic uninstall list
but we can easily apply the same logic to the tile view and app detail
view as well.
Otherwise when both are enabled the metadata from the archive gets
priority over repo which is not really what we want.
It also breaks a lot of icons, featuregraphics and screenshots.
Fixesfdroid/fdroidclient#1771Fixesfdroid/fdroidclient#1772Fixesfdroid/fdroidclient#1686
We also update the default repo priorities for existing installs if we
find the default repos in the original order.
The query is pretty annoying to write in java, here is the raw sql form.
UPDATE fdroid_repo
SET priority = ( SELECT SUM(priority)
FROM fdroid_repo
WHERE address IN ('https://f-droid.org/repo', 'https://f-droid.org/archive')
) - priority
WHERE address IN ('https://f-droid.org/repo', 'https://f-droid.org/archive') AND
'TRUE' IN (
SELECT
CASE
WHEN a.priority = b.priority-1 THEN 'TRUE'
ELSE 'FALSE'
END
FROM fdroid_repo as a
INNER JOIN fdroid_repo as b ON
a.address = "https://f-droid.org/repo" and b.address = "https://f-droid.org/archive"
)
This was blocking updates being scheduled when either data or wifi
updates were disabled. We only want to completely disable the update
service when both are disbaled though.
Ref: #1623
Fixes the following crash:
05-19 22:39:55.535 1037 24513 W WindowManager: Attempted to add application window with unknown token Token{2f841 null}. Aborting.
05-19 22:39:55.536 10844 10844 D AndroidRuntime: Shutting down VM
05-19 22:39:55.540 10844 10844 E AndroidRuntime: FATAL EXCEPTION: main
05-19 22:39:55.540 10844 10844 E AndroidRuntime: Process: org.fdroid.fdroid.debug, PID: 10844
05-19 22:39:55.540 10844 10844 E AndroidRuntime: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@d8ae31 is not valid; is your activity running?
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.view.ViewRootImpl.setView(ViewRootImpl.java:891)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:372)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:128)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.app.Dialog.show(Dialog.java:454)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at org.fdroid.fdroid.views.AppDetailsActivity$7.onReceive(AppDetailsActivity.java:607)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:311)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:47)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:120)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:108)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.os.Looper.loop(Looper.java:166)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7529)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
05-19 22:39:55.540 10844 10844 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
The !isFinishing check was already in the installReceiver part, but
somehow missing in uninstallReceiver. There's also a reference to this
here: http://blackriver.to/2012/08/android-annoying-exception-unable-to-add-window-is-your-activity-running/
I don't understand this crash, especially as the dialouge still gets
shown after adding this check (possibly the parent activity is finishing
and then immediately restarting?). But this sems to realibly fix it.
This was happening when I installed an app, used a new settings entry to
unregister privext as a device owner (by calling it via binder/aidl) and
then trying to uninstall the app I just installed again, whithout
closing f-droid inbetween.
Previously everything from a repo staying inside the db when removing it
without disabling it first, the problem manifests when the repo is
readded later (or a mirror), as it would get a new id but all apk
entries still point to the original repoid.
So we now first disable a repo (which just calls
RepoProvider.Helper.purgeApps) before deleting it from the db.
closesBubu/fdroidclassic#29
This testing at the wrong point, namely in the app details where you are
already looking at the antifeatures which might be present.
In the list view there's an additional direct check with
isDisabledByAntiFeatures() anyway.
Fixfdroid/fdroidclient#1845
* Use separate receivers instead of one combined activity
to avoid showing the "Use F-Droid to handle Mass Storage"
prompt every time a drive is plugged in.
* Re-do the logic completely, and make it much more clearer.
* Also, Read external storage implies access media location
*ONLY* on apps not targetting API 29 or above, i.e <= 28
* This new permission comes courtesy of the Q December update.
* Read external storage implies access media location
References:
* ac7b10c135%5E%21/#F1
These strings are part of the install/uninstall UI which is originally
sourced from Android itself. So the translations should stay in sync with
Android's.
This is the same exact key, just the signed metadata is updated so that it
includes the new expiration date. This is the same as just updating this
key from the keyservers.
This might happen if the user denies storage permission.
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=16613, result=0, data=null} to activity {org.fdroid.fdroid/org.fdroid.fdroid.views.main.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.net.Uri android.content.Intent.getData()' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:4612)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4654)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1955)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7073)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.net.Uri android.content.Intent.getData()' on a null object reference
at org.fdroid.fdroid.nearby.TreeUriScannerIntentService.onActivityResult(TreeUriScannerIntentService.java:99)
at org.fdroid.fdroid.views.main.MainActivity.onActivityResult(MainActivity.java:270)
at android.app.Activity.dispatchActivityResult(Activity.java:7759)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4605)
... 11 more
java.lang.NullPointerException: Attempt to invoke virtual method 'android.net.Uri android.content.Intent.getData()' on a null object reference
at org.fdroid.fdroid.nearby.TreeUriScannerIntentService.onActivityResult(TreeUriScannerIntentService.java:99)
at org.fdroid.fdroid.views.main.MainActivity.onActivityResult(MainActivity.java:270)
at android.app.Activity.dispatchActivityResult(Activity.java:7759)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4605)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4654)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1955)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7073)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
In order to support Android < 21, this calls `super` rather than `this`.
RelativeLayout}'s methods just use a 0 for the fourth argument, just like
this used to.
java.lang.NullPointerException: Attempt to read from field 'java.lang.String android.net.wifi.WifiConfiguration.SSID' on a null object reference
at org.fdroid.fdroid.nearby.StartSwapView.uiUpdateWifiNetwork(StartSwapView.java:226)
at org.fdroid.fdroid.nearby.StartSwapView.uiInitWifi(StartSwapView.java:211)
at org.fdroid.fdroid.nearby.StartSwapView.onFinishInflate(StartSwapView.java:111)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:876)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at org.fdroid.fdroid.nearby.SwapWorkflowActivity.inflateSwapView(SwapWorkflowActivity.java:488)
at org.fdroid.fdroid.nearby.SwapWorkflowActivity.showIntro(SwapWorkflowActivity.java:541)
at org.fdroid.fdroid.nearby.SwapWorkflowActivity.showRelevantView(SwapWorkflowActivity.java:468)
at org.fdroid.fdroid.nearby.SwapWorkflowActivity.access$100(SwapWorkflowActivity.java:86)
at org.fdroid.fdroid.nearby.SwapWorkflowActivity$1.onServiceConnected(SwapWorkflowActivity.java:135)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1652)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1681)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
fixes:
java.lang.NullPointerException: Attempt to read from field 'java.lang.String android.net.wifi.WifiConfiguration.BSSID' on a null object reference
at org.fdroid.fdroid.nearby.WifiStateChangeService.setSsid(WifiStateChangeService.java:265)
at org.fdroid.fdroid.nearby.WifiStateChangeService.access$100(WifiStateChangeService.java:59)
at org.fdroid.fdroid.nearby.WifiStateChangeService$WifiInfoThread.run(WifiStateChangeService.java:174)
java.lang.NullPointerException: Attempt to read from field 'boolean android.net.wifi.WifiConfiguration.hiddenSSID' on a null object reference
at org.fdroid.fdroid.nearby.WifiStateChangeService.setSsid(WifiStateChangeService.java:252)
at org.fdroid.fdroid.nearby.WifiStateChangeService.access$100(WifiStateChangeService.java:59)
at org.fdroid.fdroid.nearby.WifiStateChangeService$WifiInfoThread.run(WifiStateChangeService.java:174)
java.lang.NullPointerException: null receiver
at java.lang.reflect.Method.invoke(Native Method)
at cc.mvdan.accesspoint.WifiApControl.invokeQuietly(WifiApControl.java:178)
at cc.mvdan.accesspoint.WifiApControl.isWifiApEnabled(WifiApControl.java:189)
at cc.mvdan.accesspoint.WifiApControl.isEnabled(WifiApControl.java:198)
at org.fdroid.fdroid.nearby.WifiStateChangeService.setSsid(WifiStateChangeService.java:249)
at org.fdroid.fdroid.nearby.WifiStateChangeService.access$100(WifiStateChangeService.java:59)
at org.fdroid.fdroid.nearby.WifiStateChangeService$WifiInfoThread.run(WifiStateChangeService.java:133)
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.app.AppOpsManager.checkOpNoThrow(int, int, java.lang.String)' on a null object reference
at android.provider.Settings.isCallingPackageAllowedToPerformAppOpsProtectedOperation(Settings.java:13730)
at android.provider.Settings.isCallingPackageAllowedToWriteSettings(Settings.java:13634)
at android.provider.Settings$System.canWrite(Settings.java:4793)
at cc.mvdan.accesspoint.WifiApControl.getInstance(WifiApControl.java:122)
at org.fdroid.fdroid.nearby.WifiStateChangeService.setSsid(WifiStateChangeService.java:240)
at org.fdroid.fdroid.nearby.WifiStateChangeService.access$100(WifiStateChangeService.java:59)
at org.fdroid.fdroid.nearby.WifiStateChangeService$WifiInfoThread.run(WifiStateChangeService.java:133)
This got missed in ef90fd2dfdb0b07aca21f4be34e2c418f092bf06
fdroid/fdroidclient!829
for f in `find app/src/ -type f -name \*.xml|xargs grep --no-filename -F '<org.fdroid.fdroid' | awk '{ print $1}' |sort -u`; do test -e app/src/*/java/`echo $f | sed -e 's,<,,' -e 's,\.,/,g'`.java || echo FAIL $f; done
Recursively search for index-v1.jar starting from the given directory,
looking at files first before recursing into directories. This is
"depth last" since the index file is much more likely to be shallow
than deep, and there can be a lot of files to search through starting
at 4 or more levels deep, like the fdroid icons dirs and the per-app
"external storage" dirs.
It is possible to enable the Hotspot AP on a device, and disable mobile
data. This setup will work fine for swapping, but the detection logic for
whether there is metered internet was blocking it. So this adds a new
state to represent and handle this condition.
F-Droid should be able to uninstall any app, in theory, not just the apps
that are listed in the index.
This lays some groundwork for moving swap's SelectAppsView to the standard
AppList elements used everywhere else. It also does a little bit towards
getting rid of InstalledApp in favor of just reusing App.
This will uninstall the list of apps that the user has setup in the Panic
Settings if Privileged Extension is installed. This also requires that the
user set up a trusted connection between a panic trigger app (e.g. Ripple)
and F-Droid.
It is possible for repo operators to specify a bad CurrentVersionCode for
an app that is also in another repo, and cause confusion in the suggested
version calculation. Or if one repo's index is very out of date. This
adds a fallback for these cases, so at least it'll stop the crash and
attempt the user's requested install.
Rx needs to be used as the basis of the whole system, it doesn't make sense
to just have one small part handled by Rx.
RxJava is still used in InstallAppProviderService, so that would have to be
tackled separately.
Since it is possible to connect to a peer via NFC, "Swap back", QR Code,
etc. once a peer is successfully used, it can show up in the StartSwapView
list of peers.
This also switches to always using getActivity().getSwapService() to make
it easily traceable where that is happening. It shouldn't be happening in
SwapViews...
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6128)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at org.fdroid.fdroid.localrepo.peers.BonjourPeer.equals(BonjourPeer.java:34)
at java.util.HashMap.put(HashMap.java:427)
at java.util.HashSet.add(HashSet.java:217)
at rx.internal.operators.OperatorDistinct$1.onNext(OperatorDistinct.java:62)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:202)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:162)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
https://stackoverflow.com/a/602660
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:851)
at java.util.HashMap$ValueIterator.next(HashMap.java:879)
at org.fdroid.fdroid.localrepo.LocalRepoManager.copyIconsToRepo(LocalRepoManager.java:296)
at org.fdroid.fdroid.localrepo.LocalRepoService$1.run(LocalRepoService.java:131)
SwapService is the thing that needs to be always running, and the last
thing killed. So it should start first, and stop last. So now, the user
clicking the button starts SwapService, which starts SwapWorkflowActivity.
This also eliminatings the "Loading" screen in favor of just showing the
StartSwapView with various inline progress indicators.
Instead of waiting for the user to make all the app selections, then click
next, this constantly regenerates the swap repo on each click of the app
list. This means that the swap repo is more likely to be immediately ready
when the user clicks next.
The Android back button provides a working back function, and the Swap
"close" button on the upper left already provides a reset function. So this
turns the "back" button to be a "try again" button which re-runs the
connection process.
The Receiver superclass is not reusing difficult code, but it is hiding the
simple list of UI configuration that it does.
This also eliminates the "error" TextView and just reuses the existing
TextView for error messages.
The most expensive part of this whole process is calculating the hash of the
whole APK. InstalledAppProvider already caches that, and the rest is OK to
query. If any particular part of the query is expensive, it could also be
moved to InstalledAppProviderService.
This moves all logic for setting up the local fdroid repo to its own
IntentService. That makes it much easier to interact with since things can
just use the static helper method to request it to update, and it'll do the
right thing.
Almost all of the nearby/swap view classes could be condensed into a single
base class that is instantiated in the view XML. This is the first step
towards making that happen.
It also lays the groundwork where "steps" are all SwapViews. The
original concept of "steps" put all steps together, whether
F-Droid could control them or not. For example, the Views were
mixed with the system Bluetooth prompts. This is the first step
towards converting the steps to always be SwapViews, which are
always under control of this app.
When coming back to a SwapView/step, it does not seem feasible to handle
automatically restarting things like permissions and Bluetooth prompts. If
there is a way, it should be possible to first load the proper SwapView
instance, then trigger the system prompt. The makes the SwapView a pure
View, without any Controller in it.
The date/time written to index.xml and index-v1.json should always be in
UTC format. These formats are often in the form of just a date, e.g.
2019-04-28. Those are then converted to UNIX seconds, which includes the
time. In the date only case, the time is assumed to be 00:00, which will
be different per time zone.
index-v1.json is better since it mostly uses Java-style UNIX time in millis
but the dates/times are parsed then stored in the local database in the old
format yyyy-MM-dd_HH:mm:ss which will result in different UNIX times when
the device is in different time zones.
fdroid/fdroidclient#1757
This also converts old Repo.lastUpdated values rather than just failing.
index.xml handling used to store the Repo "Last Updated" date used to store
the value as just an ISO date (2019-04-29), then the time was added. So if
date/time parsing fails, this falls back to trying to parse just the date.
null is returned when parsing fails, and the Latest Tab shows nothing if
the Last Updated is null.
Some related tests were also tweaked.
Hopefully:
closesfdroid/fdroidclient#1757
Throwable includes Errors and Exceptions. Fixes stacktraces like these:
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:325)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.NoSuchMethodError: No virtual method toPath()Ljava/nio/file/Path; in class Ljava/io/File; or its super classes (declaration of 'java.io.File' appears in /system/framework/core-oj.jar)
at org.apache.commons.io.FileUtils.isSymlink(FileUtils.java:3107)
at org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.java:1616)
at org.fdroid.fdroid.DeleteCacheService.onHandleWork(DeleteCacheService.java:32)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:391)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:382)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 3 more
java.lang.NoSuchMethodError: No virtual method toPath()Ljava/nio/file/Path; in class Ljava/io/File; or its super classes (declaration of 'java.io.File' appears in /system/framework/core-oj.jar)
at org.apache.commons.io.FileUtils.isSymlink(FileUtils.java:3107)
at org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.java:1616)
at org.fdroid.fdroid.DeleteCacheService.onHandleWork(DeleteCacheService.java:32)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:391)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:382)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
This reverts commit c5daf1981a7f00de16e19120ac42575c0e4bc424.
Turns I was confused here. Yes, the job has to be called "pages" if the
job is deploying to GitLab Pages. But in the case of `fdroid nightly`, the
thing that is deploying to GitLab Pages is the .gitlab-ci.yml that is in
the *-nightly repo, which is auto-generated by `fdroid nightly`.
fdroid/fdroidserver#649
There are soo many of these:
org.fdroid.fdroid.net.HttpDownloaderTest > downloadThenCancel[avd27(AVD) - 8.1.0] FAILED
Test failed to run to completion. Reason: 'Instrumentation run failed due to 'Process crashed.''. Check device logcat for details
When auto-updates are enabled, the app should update itself last, to ensure
that all of the other apps are completely updated before this app is killed
as part of the update process.
closes#1556
java.lang.NoSuchMethodError: No virtual method toPath()Ljava/nio/file/Path; in class Ljava/io/File; or its super classes (declaration of 'java.io.File' appears in /system/framework/core-oj.jar)
at org.apache.commons.io.FileUtils.isSymlink(FileUtils.java:3107)
at org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.java:1616)
at org.fdroid.fdroid.DeleteCacheService.onHandleWork(DeleteCacheService.java:30)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:391)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:382)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.e(Log.java:232)
at org.fdroid.fdroid.net.DownloaderService.handleIntent(DownloaderService.java:232)
at org.fdroid.fdroid.net.DownloaderService.access$000(DownloaderService.java:88)
at org.fdroid.fdroid.net.DownloaderService$ServiceHandler.handleMessage(DownloaderService.java:108)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
This is needed since this affects the onProgress broadcasts, and sending
too many can peg the device's CPU. 1k was just too small. ANd 8k works
fine for Bluetooth.
fdroid/fdroidclient#1590
In some cases (e.g. when using Firefox Klar) and copying the URL
(of a link), then only the uri is set and not the text. This
prevented (before this commit) the autofill of the
add package source dialog in such cases.
java.lang.NullPointerException: Attempt to read from field 'java.lang.String org.fdroid.fdroid.data.App.packageName' on a null object reference
at org.fdroid.fdroid.views.swap.SwapAppsView$AppListAdapter$ViewHolder$2.onChange(SwapAppsView.java:294)
at android.database.ContentObserver.onChange(ContentObserver.java:130)
at android.database.ContentObserver.onChange(ContentObserver.java:145)
at android.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:216)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:152)
at android.app.ActivityThread.main(ActivityThread.java:5497)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Normally, WifiStateChangeService finds the SSID when F-Droid starts. But if
the user hasn't granted location permissions yet, then WifiStateChangeService
won't have been able to read the SSID yet.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File java.io.File.getCanonicalFile()' on a null object reference
at android.os.storage.StorageManager.getStorageVolume(StorageManager.java:844)
at android.os.storage.StorageManager.getStorageVolume(StorageManager.java:838)
at android.os.Environment.isExternalStorageRemovable(Environment.java:725)
at org.fdroid.fdroid.views.main.NearbyViewBinder.<init>(NearbyViewBinder.java:85)
at org.fdroid.fdroid.views.main.MainViewController.bindSwapView(MainViewController.java:64)
at org.fdroid.fdroid.views.main.MainViewAdapter.onCreateViewHolder(MainViewAdapter.java:94)
at org.fdroid.fdroid.views.main.MainViewAdapter.onCreateViewHolder(MainViewAdapter.java:47)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6685)
java.lang.IllegalArgumentException: Failed to find storage device at null
at android.os.Environment.isExternalStorageRemovable(Environment.java:859)
at org.fdroid.fdroid.views.main.NearbyViewBinder.<init>(NearbyViewBinder.java:85)
at org.fdroid.fdroid.views.main.MainViewController.bindSwapView(MainViewController.java:64)
at org.fdroid.fdroid.views.main.MainViewAdapter.onCreateViewHolder(MainViewAdapter.java:94)
at org.fdroid.fdroid.views.main.MainViewAdapter.onCreateViewHolder(MainViewAdapter.java:47)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6685)
java.lang.ArrayIndexOutOfBoundsException: length=13; index=42
at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(BaseCalendar.java:454)
at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2340)
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2740)
at java.util.Calendar.updateTime(Calendar.java:2589)
at java.util.Calendar.getTimeInMillis(Calendar.java:1101)
at java.util.Calendar.getTime(Calendar.java:1074)
at java.text.SimpleDateFormat.parseInternal(SimpleDateFormat.java:1518)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1413)
at java.text.DateFormat.parse(DateFormat.java:356)
at org.fdroid.fdroid.Utils.parseDateFormat(Utils.java:577)
at org.fdroid.fdroid.Utils.parseDate(Utils.java:592)
at org.fdroid.fdroid.data.Apk.<init>(Apk.java:178)
java.lang.NumberFormatException: Not a number:
at android.icu.math.BigDecimal.bad(BigDecimal.java:3349)
at android.icu.math.BigDecimal.<init>(BigDecimal.java:526)
at android.icu.math.BigDecimal.<init>(BigDecimal.java:910)
at android.icu.text.DigitList.getBigDecimalICU(DigitList.java:278)
at android.icu.text.DecimalFormat.parse(DecimalFormat.java:2058)
at android.icu.text.DecimalFormat.parse(DecimalFormat.java:1931)
at java.text.DecimalFormat.parse(DecimalFormat.java:804)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2353)
at java.text.SimpleDateFormat.parseInternal(SimpleDateFormat.java:1615)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1528)
at java.text.DateFormat.parse(DateFormat.java:360)
at org.fdroid.fdroid.Utils.parseDateFormat(Utils.java:577)
at org.fdroid.fdroid.Utils.parseDate(Utils.java:592)
at org.fdroid.fdroid.data.App.<init>(App.java:311)
at org.fdroid.fdroid.views.whatsnew.WhatsNewAdapter.onBindViewHolder(WhatsNewAdapter.java:95)
at org.fdroid.fdroid.views.whatsnew.WhatsNewAdapter.onBindViewHolder(WhatsNewAdapter.java:19)
java.lang.ArrayIndexOutOfBoundsException: length=13; index=36
at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(BaseCalendar.java:454)
at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2411)
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2813)
at java.util.Calendar.updateTime(Calendar.java:3397)
at java.util.Calendar.getTimeInMillis(Calendar.java:1761)
at java.util.Calendar.getTime(Calendar.java:1734)
at java.text.SimpleDateFormat.parseInternal(SimpleDateFormat.java:1633)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1528)
at java.text.DateFormat.parse(DateFormat.java:360)
at org.fdroid.fdroid.Utils.parseDateFormat(Utils.java:577)
at org.fdroid.fdroid.Utils.parseDate(Utils.java:592)
at org.fdroid.fdroid.data.App.<init>(App.java:314)
at org.fdroid.fdroid.views.updates.UpdatesAdapter.onCanUpdateLoadFinished(UpdatesAdapter.java:241)
at org.fdroid.fdroid.views.updates.UpdatesAdapter.onLoadFinished(UpdatesAdapter.java:224)
at org.fdroid.fdroid.views.updates.UpdatesAdapter.onLoadFinished(UpdatesAdapter.java:67)
java.lang.NumberFormatException: For input string: "@2131034146"
at java.lang.Integer.parseInt(Integer.java:615)
at java.lang.Integer.parseInt(Integer.java:650)
at org.fdroid.fdroid.data.App.getMinTargetMaxSdkVersions(App.java:1092)
at org.fdroid.fdroid.data.App.initInstalledApk(App.java:769)
at org.fdroid.fdroid.data.App.getInstance(App.java:395)
at
org.fdroid.fdroid.localrepo.CacheSwapAppsService.onHandleIntent(CacheSwapAppsService.java:77)
at
android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:76)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.os.HandlerThread.run(HandlerThread.java:65)
AppUpdateStatusManager and InstallManagerService should be using only the
Canonical URL of the package since that is the global unique ID. The actual
URL used to download it needs to be isolated in DownloaderService, which can
entirely manage the mirror selection process. This is just a bunch of
renaming to make this all clearer.
This parses the String into a Uri once per Intent, rather than once per
broadcast. The Uri instance is also nicer to work with, since it is the
native URL format for Intents.
It should make the progress updates a bit more efficient also.
fdroid/fdroidclient#1742
Only DownloaderService really needs to know about the mirror tricks, the
rest of the process should only ever use the canonical URL to keep things
simple.
This method returns the URL that points to the canonical download
source for this package. This is also used as the unique ID for
tracking downloading, progress, and notifications throughout the
whole install process. It is guaranteed to uniquely represent
this file since it points to a file on the file system of the
canonical webserver.
* no-featured-app:
cleanup imports
fix padding of top item in Latest Tab
Remove feature graphic of first app from "Latest" view
See merge request fdroid/fdroidclient!807
This adds requirements before an app is shown on the Latest tab. It must
have all of these:
* name
* summary
* description
* license
* What's New entry
* at least some text localized
And then it must have at least one of these:
* screenshots
* feature graphic
The problem here is that oftentimes, the index fetch will happen
automatically in the background while the user is in a different app. If
the fetch fails, the warning text changed here is displayed as a toast,
but without this change there's no way to tell that it's coming from
F-Droid.
The merge_requests feature is really confusing, and doesn't seem to do
anything useful for what we need it to. Like it doesn't let new
contributors' merge requests run on the fdroid runners.
* Rename ids to something meaningful
* Remove inner layouts from constraint layout
* Use same text and button styles
* Make sure the background image doesn't overlap with the text
This also needs to handle mirror lists with 1 element, since mirrors can
now be disabled. If the user disables all mirrors, then there will be only one URL in the
list of mirrors. Asking for a random mirror in that case should not return
null, but the one enabled mirror.
closes#1696
```python
import glob
for f in glob.glob('metadata/*/*.txt'):
with open(f) as fp:
data = fp.read()
with open(f, 'w') as fp:
fp.write(data.rstrip())
fp.write('\n')
```
for f in metadata/*/short_description.txt; do data=`cat $f`; echo $data > $f; done
This spreads downloads across all available mirrors randomly. This could
definitely be improved, like choosing the fastest or nearest mirror, or
only .onion addresses on Tor. This will improve the current situation and
should reduce the load on f-droid.org a lot.
fdroidclient#1696
Remove unused code and simplify to only present args that are used. This is
remnants from:
fdroidclient#490
fdroidclient#606
fdroidclient!295
fdroidclient!242
Lots of people complain that the graphics aren't being downloaded. That's
because they never use F-Droid while on WiFi and the default prefs do not
allow downloading graphics while on Data. This sets the preference to
allow downloading graphics while on Data if only Data is enabled, and not
WiFi, when the user first starts F-Droid.
closes#1592
This makes it display nicely in RepoDetails, and is natural, since it is
the canonical URL. This also maintains the order as received from the
mirror entries in the index file.
The Read Timeout makes a SocketTimeoutException be thrown if the timeout
expires before data is available for reading from the connection's
returned InputStream. This should help the client switch to a new mirror
when the current mirror is too slow or overloaded.
This should make the timeout logic clearer, without changing the logic at
all. This does increase the timeouts, with the second pass using 1 minute
instead of 30 seconds, and the third pass using 10 minutes instead of 1
minute. Since this often or usually runs in the background, it should
allow some pretty long timeouts in the worst case.
It seems that ARM emulators timeout even when just trying to run the
assumeTrue() tests via Espresso. There needs to be one test still enabled
in the file, otherwise, the run fails with:
org.fdroid.fdroid.MainActivityEspressoTest > initializationError[Nexus_One_API_19(AVD) - 4.4.2] FAILED
java.lang.Exception: No runnable methods
at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:191)
The two excluded URLs seem to always resolve to IPv6 addresses first, then
fail since there isn't IPv6 connectivity. Donno why, but only on old android
versions, so just skip them there.
Compression seems to just give stacktraces:
HttpDownloaderTest I URL: https://en.wikipedia.org/wiki/Index.html
TestRunner I failed: downloadUninterruptedTest(org.fdroid.fdroid.net.HttpDownloaderTest)
I ----- begin exception -----
I java.io.EOFException
I at java.util.zip.GZIPInputStream.readFully(GZIPInputStream.java:206)
I at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:98)
I at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:81)
I at libcore.net.http.HttpEngine.initContentStream(HttpEngine.java:541)
I at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:844)
I at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
I at libcore.net.http.HttpURLConnectionImpl.getHeaderField(HttpURLConnectionImpl.java:139)
I at libcore.net.http.HttpsURLConnectionImpl.getHeaderField(HttpsURLConnectionImpl.java:246)
I at org.fdroid.fdroid.net.HttpDownloader.download(HttpDownloader.java:111)
I at org.fdroid.fdroid.net.HttpDownloaderTest.downloadUninterruptedTest(HttpDownloaderTest.java:74)
I at java.lang.reflect.Method.invokeNative(Native Method)
I at java.lang.reflect.Method.invoke(Method.java:511)
I at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
I at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
I at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
I at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
I at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
I at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
I at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
I at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
I at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
I at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
I at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
I at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
I at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
I at org.junit.runners.Suite.runChild(Suite.java:128)
I at org.junit.runners.Suite.runChild(Suite.java:27)
I at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
I at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
I at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
I at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
I at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
I at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
I at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
I at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
I at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
I at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
I at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1661)
This is insurance to make sure that packageNames are not abused for
exploiting F-Droid. The database queries already use SQL Prepared
Statements, but who know what else might be exploitable.
fdroid/fdroidclient#1588
Keep PRNGFixes as it is since it is security sensitive, standardized
code from Google. While F-Droid never wants to do anything with
hardware IDs at all, this code uses the Build.SERIAL as a seed for the
random number generator, so it is safe privacy-wise.
ACRA E ACRA caught a IllegalStateException for org.fdroid.fdroid.debug
E java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
E at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
E at android.os.Handler.handleCallback(Handler.java:751)
E at android.os.Handler.dispatchMessage(Handler.java:95)
E at android.os.Looper.loop(Looper.java:154)
E at android.app.ActivityThread.main(ActivityThread.java:6128)
E at java.lang.reflect.Method.invoke(Native Method)
E at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
E at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
E Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a
null object reference
E at org.fdroid.fdroid.localrepo.peers.BonjourPeer.hashCode(BonjourPeer.java:41)
E at sun.misc.Hashing.singleWordWangJenkinsHash(Hashing.java:48)
E at java.util.HashMap.put(HashMap.java:423)
E at java.util.HashSet.add(HashSet.java:217)
E at rx.internal.operators.OperatorDistinct$1.onNext(OperatorDistinct.java:62)
E at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:202)
E at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:162)
E at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
E ... 7 more
The query was trying to figure out some thing about suggestedVercode
which shouldn't at all be necessary for setting the iconUrl.
The index already contains the icon pointing to the suggested version by
that repository, so we just take that regardless.
fdroid/fdroidclient#1569
```python
import glob
import os
import re
locale_pat = re.compile(r'.*values-([a-z][a-z][a-zA-Z-]*)/strings.xml')
translation_pat = re.compile(r'.*name="settings_label"[^>]*>"?([^"<]*).*')
for f in glob.glob('/home/hans/code/android.googlesource.com/packages/apps/Settings/res/values-[a-z][a-z]*/strings.xml'):
m = locale_pat.search(f)
if m:
locale = m.group(1)
if locale.endswith('-nokeys'):
continue
#print(locale)
with open(f) as fp:
m = translation_pat.search(fp.read())
if m:
word = m.group(1)
print(locale, '\t', word)
fdroid = '/home/hans/code/fdroid/client/app/src/main/res/values-' + locale + '/strings.xml'
if os.path.exists(fdroid):
with open(fdroid) as fp:
data = fp.read()
with open(fdroid, 'w') as fp:
fp.write(re.sub(r'menu_settings">[^<]+</string', 'menu_settings">' + word + '</string', data))
```
fdroid/fdroidclient#1569fdroid/fdroidclient#887
```python
import glob
import os
import re
locale_pat = re.compile(r'.*values-([a-zA-Z-]*)/strings.xml')
translation_pat = re.compile(r'.*name="corpus_name_websearch_nearby">([^<]*).*')
for f in glob.glob('/tmp/Velvet/res/values-*/strings.xml'):
m = locale_pat.search(f)
if m:
locale = m.group(1)
with open(f) as fp:
m = translation_pat.search(fp.read())
if m:
word = m.group(1)
print(locale, '\t', word)
fdroid = '/home/hans/code/fdroid/client/app/src/main/res/values-' + locale + '/strings.xml'
if os.path.exists(fdroid):
with open(fdroid) as fp:
data = fp.read()
with open(fdroid, 'w') as fp:
fp.write(re.sub(r'main_menu__swap_nearby">[^<]+</string', 'main_menu__swap_nearby">' + word + '</string', data))
```
For many languages, there are unavoidable long words needed for the labels
on the button bar, for example, the standard word for Settings can be up to
15 characters long:
https://gitlab.com/fdroid/fdroidclient/issues/1569#note_126469088
The BottomBar was scaling the active one up, and sizing all the fields based
on that size. This removes that animation, and sets all tabs to always have
the same text size. That makes it possible to make the spacing tighter.
This also sets the text truncating mode to "middle" which sticks an elipsis
in the middle of the truncated word and shows the start and end.
closes#1569closes!756
This adds a new IntentService to pre-process Intents that request a
new repo is added. Right now, this only handles Intents that come
from the new storage scanners.
This also adds a new case to the AddRepo UI logic to cover when an
incoming Intent is for a mirror that is already included in an enabled
repo. In that case, the user is show the Repo Details screen for the
repo that includes that mirror. This is done is a hacky way right now
since the only path through is to click the button. So this clicks
the button in code.
Creates an IntentService subclass for scanning removable "external
storage" for F-Droid package repos, e.g. SD Cards. This is intented to
support sharable package repos, so it ignores non-removable storage,
like the fake emulated sdcard from devices with only built-in storage.
This method will only ever allow for reading repos, never writing. It
also will not work for removeable storage devices plugged in via USB,
since do not show up as "External Storage"
* https://stackoverflow.com/a/40201333
* https://commonsware.com/blog/2017/11/14/storage-situation-external-storage.htmlcloses#1377
This uses the new Storage Access Framework, which was required for
accessing files on the SD Card starting in android-19. But the API
was really limited until android-21, and not really complete until
android-23 or even android-26. So the levels of usability will vary a
lot based on how new the version of Android is.
The mirror logic assumes that it has a mirrors list with at least once
valid entry in it. In the index format as defined by `fdroid update`,
there is always at least one valid URL: the canonical URL. That also
means if there is only one item in the mirrors list, there are no
other URLs to try.
The initial state of the repos in the database also include the canonical
URL in the mirrors list so the mirror logic works on the first index
update. That makes it possible to do the first index update via SD Card
or USB OTG drive.
* jsonLoader: (28 commits)
fix checkstyle complaints
force DBHelperTest.canAddAdditionalRepos() to run on CI
clean up whitespace in repo descriptions
rename parseXmlRepos to parseAdditionalReposXml
rename item lists to repoItems
rename defaultReposFile to additionalReposFile
separate defaultRepos from initialRepos, which includes additionalRepos
rename REPO_XML_ARG_COUNT to REPO_XML_ITEM_COUNT
fix additional_repos.xml handling to be properly parsed
move comments to javadoc
priority is NOT ignored, just additional_repos.xml is not allowed to set
fix DBHelperTest to actually load and parse additional_repos.xml
changed the tests: now testing only DBHelper.parseXmlRepos()
removed stars from imports
finished additional repos test
some minor style changes
minor style changes
implemented creating xml file on oem partition; not sure whether it works cause gradle runs forever (>20min)
started implementing test
removed priority from additional_repos.xml
...
closesfdroid/fdroidclient!705
additional_repos.xml has 7 <item> elements per repo, while default_repos.xml
has 8. The difference is that additional_repos.xml does not have the
"priority" <item> since it is not allowed to override anything that is set
in default_repos.xml.
see spec in !705
I missed this little detail ind64a55e013882a7d6b3de646955ed68647a82e97,
the super version of this throws an exception, so it stops the downgrade.
fdroid/fdroidclient!729
fdroidserver has always written "sha256" to the index.xml file, so client
should use the same. The Java hashers will correctly respond to both
"sha256" and "SHA-256", and the only place that the hashType is read from
the DB and used is in the swap repo index.xml generation, where it should
also use "sha256".
java.lang.Throwable: Explicit termination method 'end' not called
at dalvik.system.CloseGuard.open(CloseGuard.java:180)
at java.util.zip.Deflater.<init>(Deflater.java:171)
at kellinwood.zipio.ZioEntryOutputStream.<init>(ZioEntryOutputStream.java:35)
at kellinwood.zipio.ZioEntry.getOutputStream(ZioEntry.java:482)
at kellinwood.security.zipsigner.ZipSigner.signZip(ZipSigner.java:759)
at kellinwood.security.zipsigner.ZipSigner.signZip(ZipSigner.java:664)
at org.fdroid.fdroid.localrepo.LocalRepoKeyStore.signZip(LocalRepoKeyStore.java:213)
at org.fdroid.fdroid.localrepo.LocalRepoManager.writeIndexJar(LocalRepoManager.java:492)
at org.fdroid.fdroid.views.swap.SwapWorkflowActivity$PrepareSwapRepo.doInBackground(SwapWorkflowActivity.java:759)
at org.fdroid.fdroid.views.swap.SwapWorkflowActivity$PrepareSwapRepo.doInBackground(SwapWorkflowActivity.java:709)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
E StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
The emulator runs are super crashy on gitlab-ci, so just run the emulator
tests for the "full" build flavor. Once these prove stable, the task
should be switched to connectedCheck to test all the build flavors
ARM emulators are too slow to run these tests in a useful way. The
sad thing is that it would probably work if Android didn't put up the
ANR "Process system isn't responding" on boot each time. There seems
to be no way to increase the ANR timeout.
Sometimes the test suite just totally bombs out and fails on every single
job with the same Robolectric crash. Adding this line seems to fix it.
https://github.com/robolectric/robolectric/issues/3846
Here's the error:
java.lang.VerifyError: class org.robolectric.android.fakes.RoboMonitoringInstrumentation overrides final method specifyDexMakerCacheProperty.()V
Before, it was running:
* testBasicDebugUnitTest
* testBasicReleaseUnitTest
* testFullDebugUnitTest
Since there are no Robolectric tests for only "basic", and there are no
tests specific to "release" or "debug", those three runs will be running
the same tests, except for the handful of "full" tests. So running
testFullDebugUnitTest covers all cases.
NanoHTTPD has issues with HTTP Keep-Alive, especially when other requests
are mixed in, like the /request-swap POST or perhaps the F-Droid HEAD to
fetch the ETag before the GET.
This disables gzip encoding and sets a Content Security Policy while I'm at
it. APKs, PNGs, and JARs are already compressed, so gzip would only ever
cause problems. And the index page is meant to be viewed by browsers, so
having a CSP will limit potential malicious swap activity.
The webserver was totally broken since nanohttpd had changed so much since
the swap webserver was implemented. This syncs up with the sample file and
gets rid of our hacks. The only differences now are the stuff that is
removed since it is totally unused in F-Droid. This also adds a full test
suite.
this actually closes#248
The MIME Types only need to be set on files that we are actually using to
display in the browser. All others should not be set so that they cannot
be abused.
This is a quick hack to reuse the Latest view with a slightly simpler
layout. It makes the "basic" flavor fully functional as an fdroid client.
The goal here is just to have something simpler with as little new code as
possible. It is essential that the whitelabeling and "Light" aka "basic"
flavor does not increase the maintenance load.
closesfdroid/fdroidclient#48fdroid/fdroidclient!692fdroid/fdroidclient!695
PendingInstall means that the user considers the install still in process,
like when F-Droid gets killed in the background. There is unfortunately no
reliable way currently to ensure that removePendingInstall() is called when
the app is finally installed so we can't use it here.
This reverts a small part of 1c50e2891054b629e2af6b2d0b1fc89e0b1cf18b
closesfdroid/fdroidclient#1527fdroid/fdroidclient#1532
InstalledAppProviderService also updates the AppUpdateStatus of any
package installs that are still in progress. Most importantly, this
provides the final status update to mark the end of the installation
process. It also errors out installation processes where some outside
factor uninstalled the package while the F-Droid process was underway, e.g.
uninstalling via adb, updates via Google Play, Yalp, etc.
fdroid/fdroidclient#1536fdroid/fdroidclient#1357
This could definitely use a better design treatment, but at least it is
better than showing the "click to install" button again during the install
process.
closes#1357
This adds a new PendingInstall event which broadcasts that an install
process has started, but the state of it is not yet known, like
whether it needs to be downloaded still, or is ready to install. It
marks the very first step of the whole InstallManagerService process.
Installer events should only be directly related to the install process as
managed by the Installer set of classes. The newer AppStatusUpdate stuff
now tracks the whole lifecycle of the process.
This mostly reverts f0d6acd974548e24662a64271ae57922f74c3225 since there is
now the overarching concept of "Pending Install" to mark packages that are
somewhere in the whole process.
refs #828
refs #1357
For fullstack custom builds, they'll also need a whitelabel build of
Privileged Extension, which will have a different Application ID and
signing key than F-Droid Privileged Extension.
Before, if the Data/WiFi Settings made it so the update process is not
allowed to run and the device was not offline or in Airplane Mode, it would
show this Toast then it would show the "your device is offline" Toast.
This merges the triedEmptyUpdate preference into the lastUpdateCheck pref,
and uses that to determine whether the index update has ever run. It seems
that lastUpdateCheck used to be used for that, but was semi-disabled. Then
triedEmptyUpdate was added. This merges the two into lastUpdateCheck, which
also tracks the timestamp of the last index update.
The initial start time is getting pretty slow, so hopefully this will save
a little bit. It also makes it consistent with other places in the code,
like UpdateService.
This was doing a couple of things wrong:
* the scheduled job should always require a network, NONE doesn't work
* when the preferences change, it should cancel any scheduled job first,
so that if the user chooses to disable auto-updates, that takes effect
closes#1474closes#1451closes#1457
This changes the logic to only use a SharedPreference to track pending
installs, and to set the "pending install" mark as soon as possible
while waiting until final confirmation to unmark. Before, there was a
complicated combination of a SharedPreference and the use of the APK in the
cache as a mark.
!488
refs #962closes#1311closes#1031closes#1271
Since there are many ways to uninstall an app, including from Google
Play, {@code adb uninstall}, or Settings -> Apps, this method cannot
ever be sure that the app isn't already being uninstalled. So it
needs to check that we can actually get info on the installed app,
otherwise, just call it interrupted and quit.
closes#1435
I fixed it by using the same style as a standard preference:
* the summary text size was a bit too large
* the summary text should be allowed to wrap
closes#1450
java.lang.IllegalArgumentException: Could not parse [null/24]
at org.apache.commons.net.util.SubnetUtils.calculate(SubnetUtils.java:275)
at org.apache.commons.net.util.SubnetUtils.<init>(SubnetUtils.java:51)
at org.fdroid.fdroid.net.WifiStateChangeService.setIpInfoFromNetworkInterface(WifiStateChangeService.java:261)
at org.fdroid.fdroid.net.WifiStateChangeService.access$100(WifiStateChangeService.java:50)
at org.fdroid.fdroid.net.WifiStateChangeService$WifiInfoThread.run(WifiStateChangeService.java:132)
Also, app.installedApk.sig is set in App.initInstalledApk()
from 3a5ecc5e8ec6c820dbfdb788dc06f7dbb0699c18
refs #1305
refs #855
java.lang.NullPointerException
at org.fdroid.fdroid.data.App.getInstance(App.java:390)
at org.fdroid.fdroid.localrepo.CacheSwapAppsService.onHandleIntent(CacheSwapAppsService.java:77)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
Since !705 will allow OEMs, ROM makers, etc. to add repos, there needs to
be a way for the user to prevent those from automatically installing or
uninstalling apps for users of the full F-Droid app, which guarantees user
control.
ACRA is sometimes problematic or annoying. Also, whitelabel versions might
want to disable ACRA. The setting the preference defaultValue is an easy
way to do that.
refs #1483
When debugging issues, tracking the client can be quite useful. This makes
an "Expert" preference that adds the app version and a randomly generated,
stored UUID to the query string each time it downloads an index or an app
package.
This is also useful in whitelabeling, for use cases where there needs to be
some kind of identifier to make it work.
If you quickly cycle between installing an app and uninstalling it, then
`app.installedApk` will still be null when AppDetails2.startUninstall()
calls InstallerService.uninstall(). It is better to crash earlier here,
before the Intent is sent with a null APK, because InstallerService is set
to receive Sticky Intents. That means they will automatically be resent
by the system until they successfully complete.
The notification that shows the download/parse progress of the index update
is now controled by the "Show available updates" preference. That means it
will not be shown at all in the notifications bar if that preference is
disabled. There will still be the header inside of F-Droid. Ideally, the
Updating process would be shown in the Updates tab.
This preference is meant for whitelabel builds that are meant to be
entirely controlled by the server, without user interaction, e.g.
"appliances". Some users have asked for such a thing, so it makes sense to
have it available as an expert preference. In general, we want to ensure
that installs/updates always show a notification so that the user is aware
of what is being installed on their computers. That is the same policy as
other app stores like Google Play, etc.
This should make them less scary to people who do not want to see them at
all. It also means that there can be quite a few expert preferences without
making the list super long for most users.
This labels all network, HTTP, and SSL related errors as CONNECTION_FAILED
so that the mirror selection logic will try the connection again with a new
mirror.
This removes a layer of redundancy where there were defaults set in the
Preferences class, as well as in preferences.xml. This makes it possible
for whitelabel versions to change the default values of the preferences by
changing it only in preferences.xml.
"full" is the original F-Droid app with all the features. It should still
build the exact same app after this change. "basic" is the smallest
version of F-Droid possible. It does not yet build, nor work.
This also only runs one emulator test by default, then runs 3 SDK
levels for final commits. The single default test is the optimized
F-Droid system image included in the Docker image.
Before, push requests were only supported when using index.xml. This adds
support for using push requests in index-v1.json. `fdroid update` has been
generating them in both index versions for a while now.
These calls to bouncycastle were just used because the library was
there. Now with the upcoming 'basic' build flavor, there will be no
need for bouncycastle. It is required for ZipSigner signing of swap
indexes, and TLS support in the swap NanoHTTPD webserver.
With gradle build flavors, it is possible to specify things like
'myflavorImplementation' but only if the 'dependencies' section is after
the 'android' section where the build flavors are declared. How 1982 of
them to make where things are declared in the file have meaning.
With more whitelabeling support, we need this workaround to avoid
trying to call a null instance when the whitelabeled version does not
include all of the possible preferences.
Stripping the `+` form the license link will direct to the wrong spdx
page. (This would also need changing anyway because of spdx v4.0.0)
closesfdroid/fdroidclient#1472
This changes the logic of Utils.getBinaryHash() to return null on failure
rather than only throwing exceptions. That makes it easier to handle these
failures where Utils.getBinaryHash() is called.
#1305#855
This will instead lead users with Privileged Extension to the F-Droid
uninstall screen which will probably fail. But that's better than crashing
in my opinion.
Introduced in c095a85c3dd3c505951bebb52e4ae010c69cc9f9
This gives a lot more flexibility to the user to cover bandwidth, power,
and privacy issues related to network traffic. The current implementation
does not represent these prefs as well as it should. For example, it does
not force the traffic over the preferred network type if the other type is
set to "never". Instead it just tracks the "unmetered" status of the
active network, and acts based on that.
closes#1381
This follows the Material preferred style using Switches instead of
CheckBoxes for boolean preferences. This leaves the "expert" preferences
as CheckBoxes to differentiate them, and make them stand out as something
different.
These are in fact needed:
/export/share/code/fdroid/client/app/src/main/res/values/dimens.xml:25: Error: The resource R.dimen.fixed_width_padding appears to be unused [UnusedResources]
<dimen name="fixed_width_padding">2dp</dimen>
~~~~~~~~~~~~~~~~~~~~~~~~~~
/export/share/code/fdroid/client/app/src/main/res/values/styles.xml:162: Error: The resource R.style.SwapTheme_StartSwap appears to be unused [UnusedResources]
<style name="SwapTheme.StartSwap" parent="AppThemeLight">
~~~~~~~~~~~~~~~~~~~~~~~~~~
/export/share/code/fdroid/client/app/src/main/res/values/styles.xml:166: Error: The resource R.style.SwapTheme_StartSwap_Text appears to be unused [UnusedResources]
<style name="SwapTheme.StartSwap.Text" parent="@style/SwapTheme.StartSwap">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The new JobScheduler API can opportunitistically run a job based on whether
there is good internet, connected to power, etc. This is very useful for
running updates. Ideally, updates would always happen in the background
while on unmetered internet and connected to power.
#588
Each time the device connects to a wifi network, this waits for 2 minutes,
then if the wifi is still connected, it re-schedules the index update to
happen now. The goal is to favor unmetered networks as much as possible
when downloading the index and any automatic app updates.
This is only needed on older platforms, JobScheduler handles this for us on
android-21+
This changes the flow of the update triggering so that any Intent sent to
UpdateService can potentially trigger an update, depending only on the
state of the internet and the "Only on WiFi" preference. Instead of having
a timer that checks every hour to see if it is time to run the update, just
let AlarmManager send a trigger Intent based on the timing in the
"Update Interval" setting.
The update schedule is reset each time F-Droid restarts, and also each time
the user returns from the settings, so if AlarmManager fails us in the time
being, the updates will be rescheduled next time F-Droid is restarted, the
device is rebooted, etc.
refs #662
HttpDownloaderTest doesn't get run in gitlab-ci since it was too flaky with
internet connections in the emulator. So these were missed until I manually
ran the tests.
688057b3e7e214db49566b84d5b3dcd0db30dc2b
195aaae7e52dc1c47741965904ed17bdc816a71c
df08e84e7829652d7999eee5451080a012b00a1e
Some devices send multiple copies of given events, like a Moto G often
sends three {@code CONNECTED} events. So they have to be debounced to
keep the {@link #BROADCAST} useful.
For now, swap repos are only trusted as long as swapping is active. They
should have a long lived trust based on the signing key, but that requires
that the repos are stored in the database by fingerprint, not by URL
address.
#295#703
For mirroring to work on multiple repos, this must be stored and used per-
repo. The timeout and number of tries seem fine to keep global to reduce
the total amount of mirror churn when this logic is searching.
Apps that are built as part of the ROM and signed by the platform keys
should very rarely be swapped. This removes them from the default
list by comparing the signing keys.
This filter is deliberately only included on the list function and not on
the search function. If people want to share system apps, they'll be able
to find them with the search function, but the system apps won't show up
by default.
https://source.android.com/devices/tech/ota/sign_builds#certificates-keyscloses#440
This should make swap remember if Bluetooth/WiFi was disabled when swapping
started, then automatically disable it when swapping is done. This also
makes swapping remember the swap "visibility" that the user set, and restore
that when the user starts swapping again. There are logic bugs elsewhere
in the whole thing that prevent this from always working, but the state
should be set and stored properly.
If F-Droid gets killed during the install/update process, then the install
procedure would keep getting readded and redownloaded since it is a sticky
Intent. The test is very specific so that this does not block things like
installing updates with the same versionCode, which happens sometimes, and
is allowed by Android.
#1271
The "Only on WiFi" pref originally only controlled index updates, but now
it makes sense to include all of the various files that are downloaded.
#1381
The standard pattern is to pass a Context in rather than call things like
getPackageManager in. It should only pass a PackageManager if that is
actually being reused.
This shouldn't change the logic at all.
The permissions from uses-permission and uses-permission-sdk-23 should be
combined into a single list of permissions that are being requested for the
current SDK version. The previous code was overwriting one or the other,
based on the order that Jackson happen to call setRequestedPermissions().
closes#1139#890#1394
admin#65
This completes the work started in 195aaae7e52dc1c47741965904ed17bdc816a71c
closes#1395closes#1400
# Conflicts:
# app/src/main/java/org/fdroid/fdroid/UpdateService.java
In order to save disk space and memory, at a cost of some CPU time,
this makes sure that all downloaded images are not bigger than the
device can support. A nice side effect of this process is that EXIF
information is stripped from JPEG files since they are read into a
Bitmap, then written out as a PNG. This should complete the JPEG EXIF
stripping started in 2a3aaacf2347679f30e2c8feffb92f25bb882c8b with
considerExifParams(false)
!653
This adds some case normalization to both the scheme and the host. This was
previously messing up TreeUri content:// URLs like this:
content://com.android.externalstorage.documents/tree/1AFB-2402%3A/document/1AFB-2402%3Atesty.at.or.at%2Ffdroid%2Frepo
Turning them into:
content://com.android.externalstorage.documents/tree/1AFB-2402:/document/1AFB-2402:testy.at.or.at/fdroid/repo
java.net.URL barfs on custom URL schemes, and making it handle them is
really hard. Basically, there needs to be a Handler stub class, then
URL.setURLStreamHandlerFactory() must run when F-Droid starts, since
it has to be set before any URL instance is used. This all leaves
some weird logic that gives the false impression that URLConnection
will handle these custom schemes.
Switching to Uri/urlString throughout the code matches the other
classes that use urlString as the unique ID, and this doesn't add more
lines of code.
This was int because it was written arond UrlConnection.getContentLength()
which returns an int. But that doesn't make sense since this will
definitely handle files large than 16MB.
!647#1192
This lets people add any URL as a mirror to an existing repo. The UX is
people add URLs via any of the normal ways of adding a new repo via Intents,
like clicking URLs, QRCodes, etc.
If anything wants to craft an Intent to send directly to F-Droid with an
arbitrary but valid path, that seems like a fine thing to support. The
IntentFilters will still only match on the well known paths, so that the
user doesn't see F-Droid claiming all HTTP URLs.
The repo instance variable has long since been unused, but has just been
left there as a vestige. Now its presence is blocking RepoUpdater.
getSigningCertFromJar() from being a static method that can be reused when
checking for repos on SD Cards and other removable storage devices.
This saves the levels of indirection that leads to a FileInputStream being
created in LocalFileDownloader. Since there are already special cases for
assets:// and drawable://, it seems a natural place to put the file://
case. Also, since this is used to load icons when scrolling through lists
of apps, this is particularly sensitive to inefficient loading.
This also removes custom code that UIL provides better.
This uses the total RAM that the device comes with as a rough measure of
the devices capabilities. That is then used to set how many parallel
threads UIL can use.
Instead of setting the same thing at each place its used, this puts all the
settings in one place. For the most part, they are the same everywhere.
This makes it a lot easier to optimize how UIL works since all the settings
are in one place.
No need to slow down UIL by making it do a cache check since
CleanCacheService already does that in a low priority background service.
The default FileNameGenerator just uses imageUri.hashCode() so its safe an
faster than ours. So just use the default.
Also, no need to set threadPriority() since we are using the default
This was only partially hooked up and often not even populated.
It was added in 4895e2d790ec3b91fa4271a24e1ea0ae69d362f4, but things have
changed a lot now. We should be moving towards preferring the drawable XML
vector icons, which will scale nicely for all DPIs.
The previous commit makes this issue a lot easier to see. ApkFileProvider
getSafeUri() was already making the right URI for SDK_INT < 24, but then
this bit of logic was using the original URI, which didn't work. Installing
from the app's cache dir triggered a "Parse Error". The Android default
installer API needs file:// URIs from getFiles().
closes#1310
This hopefully makes apparent which pieces are only related to APKs, and
which pieces are used for all installable file types (media, OTA ZIPs, etc)
ExtensionInstaller only works on < android-20 anyway, so that's self-
enforcing in terms of URI scheme: it'll only ever see file:// URIs.
This fixes the following crash:
* Install an app form F-Droid
* go to home screen
* uninstall app
* quickly switch to F-Droid the button will still show 'run' for a few
seconds
* launch the app you just uninstalled
This makes the build reproducible, and makes the files smaller.
metadata/en-US/images/phoneScreenshots/screenshot-dark-details.png | Bin 358916 -> 309386 bytes
metadata/en-US/images/phoneScreenshots/screenshot-dark-home.png | Bin 277413 -> 224844 bytes
metadata/en-US/images/phoneScreenshots/screenshot-dark-knownvuln.png | Bin 158903 -> 123484 bytes
metadata/en-US/images/phoneScreenshots/screenshot-knownvuln.png | Bin 66707 -> 41670 bytes
As nice as it would be to help the users, F-Droid is not well positioned to
help the user with this problem. The Android OS itself should do it. Plus
this issue has been open a long time, without much work on it, and the
existing solution is causing crashes.
#855!440!581
Utils.getBinaryHash() is used in a lot of places in the code, so its not
easy to handle this specific issue. Here's one example:
org.fdroid.fdroid.Utils$PotentialFilesystemCorruptionException: java.io.IOException: read failed: EIO (I/O error)
at org.fdroid.fdroid.Utils.getBinaryHash(Utils.java:426)
at org.fdroid.fdroid.AppUpdateStatusService.findApkMatchingHash(AppUpdateStatusService.java:159)
at org.fdroid.fdroid.AppUpdateStatusService.processDownloadedApk(AppUpdateStatusService.java:110)
at org.fdroid.fdroid.AppUpdateStatusService.onHandleIntent(AppUpdateStatusService.java:65)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
The NullPointerException fixed by the previous commit had a warning to that
effect. This fixes almost all the warnings to make the warnings clearer:
* unused method
* unused result of File.delete()
* can have reduced visibility
* single char static "" strings can be '' chars
* jif-afWarningQrCodeScan:
do not include english string in translations
Correct check style errors
Add style for the poor QR code scanning autofocus capability warning
Add 'poor QR code scanning capability' translations
Call to the camera autofocus checker in the view
Add camera characteristics checker
fdroid/fdroidclient!649
closes#260
Those classes consist of 1 abstract class, which provide a factory for
2 classes each of which implements different behaviors according to
the Android API version.
Files in the cache can be deleted at any time, without warning. F-Droid's
CleanCacheService can do it, the user can do it in Settings --> Apps, etc.
So when working with files from the cache, the methods need to be extra
defensive, checking that the file that they were given still exists.
closes#1305
Squashed commit of the following:
commit f6f528d67e9bef367cfb8a3a8eaaced06233df4a
Author: Hans-Christoph Steiner <hans@eds.org>
Date: Tue Feb 13 16:24:53 2018 +0100
remove android xml quoting
commit d7251cc20980841ca83fd27f1e4f60c5d99460ac
Author: anonymous <>
Date: Tue Feb 13 14:23:12 2018 +0000
Translated using Weblate (German)
Currently translated at 99.7% (409 of 410 strings)
commit 60f449e154fa0cd2fc986781836bad491a964866
Author: Andreas Kleinert <Andy.Kleinert@gmail.com>
Date: Tue Feb 13 14:22:48 2018 +0000
Translated using Weblate (German)
Currently translated at 99.7% (409 of 410 strings)
commit b16f2f6f58ed06264c8414c90ae9cc3dad9433d6
Author: Hans-Christoph Steiner <hans@guardianproject.info>
Date: Tue Feb 13 15:03:19 2018 +0000
Translated using Weblate (Hebrew)
Currently translated at 100.0% (410 of 410 strings)
commit 66601011e3cbdd64d9b68432bfff13b17ca90f4b
Author: Hans-Christoph Steiner <hans@eds.org>
Date: Tue Feb 13 16:15:52 2018 +0100
check for invalid mixing for format stringsj
commit cdf2e7063297d4f61259a3354a946fffdfd58114
Author: Danial Behzadi <dani.behzi@ubuntu.com>
Date: Tue Feb 13 10:46:48 2018 +0000
Translated using Weblate (Persian)
Currently translated at 100.0% (410 of 410 strings)
commit e7e37ad42c94091e2ec402caac5883272275c8c4
Author: ezjerry liao <ezjerry@gmail.com>
Date: Mon Feb 12 15:26:00 2018 +0000
Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (410 of 410 strings)
commit 0850c89e297f6256babdc7f087b242cf102ef267
Author: nautilusx <mail.ka@mailbox.org>
Date: Sat Feb 10 14:32:57 2018 +0000
Translated using Weblate (German)
Currently translated at 99.2% (407 of 410 strings)
commit 52d6426b2a413dae1ff2c33814ec9df895eac41b
Author: Kristjan Räts <kristjanrats@gmail.com>
Date: Sun Feb 11 12:25:23 2018 +0000
Translated using Weblate (Estonian)
Currently translated at 100.0% (410 of 410 strings)
commit a308ae180dbdac2fc65076e7f35ba4549ad9f6ea
Author: Allan Nordhøy <epost@anotheragency.no>
Date: Sat Feb 10 00:37:43 2018 +0000
Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.2% (407 of 410 strings)
commit fb44f4cd22f7cb6ef03265d76374646d8b554066
Author: jschwender <joachim.schwender@web.de>
Date: Fri Feb 9 21:08:25 2018 +0000
Translated using Weblate (German)
Currently translated at 99.2% (407 of 410 strings)
commit 450a30bbc18908e53cb10027a30332646a1b6224
Author: Julien Lepiller <roptat@lepiller.eu>
Date: Fri Feb 9 13:31:44 2018 +0000
Translated using Weblate (French)
Currently translated at 99.0% (406 of 410 strings)
commit 309f8b3527f176bd1cf9cd82757978ee2c3a941f
Author: Yunyang Liu <ensigma96@gmail.com>
Date: Fri Feb 9 12:50:13 2018 +0000
Translated using Weblate (Chinese (Simplified))
Currently translated at 97.0% (398 of 410 strings)
commit b4d2fbe00e7c1b276c0dde64844c18935419f3fc
Author: Rivo Zängov <rivozangov@gmail.com>
Date: Fri Feb 9 10:13:12 2018 +0000
Translated using Weblate (Estonian)
Currently translated at 98.5% (404 of 410 strings)
commit 6ec7f716405dc4efc3a12204f1ed97aaad09ba45
Author: Luiz Fernando Ranghetti <elchevive@opensuse.org>
Date: Sat Feb 10 02:58:33 2018 +0000
Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (410 of 410 strings)
commit c8af9171ac4d5fdcecb8faaabbc5c58da4053b1f
Author: Ldm Public <ldmpub@gmail.com>
Date: Fri Feb 9 13:17:30 2018 +0000
Translated using Weblate (French)
Currently translated at 99.0% (406 of 410 strings)
commit 04005a0277edca69cc6885d779e2d49673c0d97e
Author: Julien Lepiller <roptat@lepiller.eu>
Date: Fri Feb 9 13:16:05 2018 +0000
Translated using Weblate (French)
Currently translated at 99.0% (406 of 410 strings)
commit 5af1c4d24d25eeb03bffe953e4c5ce7aa8a68697
Author: monolifed <monolifed@gmail.com>
Date: Thu Feb 8 12:25:29 2018 +0000
Translated using Weblate (Turkish)
Currently translated at 100.0% (410 of 410 strings)
commit 4c56b7725905ecc6b4be49f9f4accc95859a46bc
Author: Osoitz <oelkoro@gmail.com>
Date: Fri Feb 9 10:59:06 2018 +0000
Translated using Weblate (Basque)
Currently translated at 100.0% (410 of 410 strings)
commit 7d73c299ceab39b2c674fadc2a32b2154f96e060
Author: Ajeje Brazorf <lmelonimamo@yahoo.it>
Date: Wed Feb 7 20:24:39 2018 +0000
Translated using Weblate (Sardinian)
Currently translated at 99.5% (408 of 410 strings)
commit b0027266898267619b0eb20e206a968c5e0c527e
Author: Felipe Rodrigues <bidu.pub@gmail.com>
Date: Wed Feb 7 13:41:04 2018 +0000
Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.7% (409 of 410 strings)
commit 0207c99f39fb5c43b530c6fa05c4c3f2edc278e6
Author: azumukupoe <azumukupoe1999@gmail.com>
Date: Wed Feb 7 13:19:06 2018 +0000
Translated using Weblate (Japanese)
Currently translated at 100.0% (410 of 410 strings)
commit 439b5eeee86d2dc5a7eb9d06890ff3aa62aad4d0
Author: monolifed <monolifed@gmail.com>
Date: Thu Feb 8 12:19:09 2018 +0000
Translated using Weblate (Turkish)
Currently translated at 100.0% (410 of 410 strings)
commit f3921bb42db891bf1cfa4c8e3d1699aba41f4807
Author: Yaron Shahrabani <sh.yaron@gmail.com>
Date: Wed Feb 7 08:08:20 2018 +0000
Translated using Weblate (Hebrew)
Currently translated at 100.0% (410 of 410 strings)
commit 74c0eb25e6dcc75836bb01fd96b8c04de8cd4a4c
Author: Verdulo <tomek@disroot.org>
Date: Wed Feb 7 18:04:14 2018 +0000
Translated using Weblate (Polish)
Currently translated at 100.0% (410 of 410 strings)
commit 272b00b8dfa0c530a9a51f6b980b0d311c921bfd
Author: Viktar Vauchkevich <victorenator@gmail.com>
Date: Tue Feb 6 14:06:00 2018 +0000
Translated using Weblate (Belarusian)
Currently translated at 98.2% (403 of 410 strings)
commit b28a9e57dd21c5f28dbf3555cadca0a20770a337
Author: Takumi Shoji <azumukupoe1999@gmail.com>
Date: Wed Feb 7 13:06:00 2018 +0000
Translated using Weblate (Japanese)
Currently translated at 100.0% (410 of 410 strings)
commit 56422c2d9ec3de0401793a7e0767c376925cc88f
Author: Sérgio Marques <smarquespt@gmail.com>
Date: Tue Feb 6 11:56:27 2018 +0000
Translated using Weblate (Portuguese (Portugal))
Currently translated at 98.0% (402 of 410 strings)
commit cd4ab7fdb3844f39c2f686b2ce0571b6de622cbb
Author: Licaon Kter <licaon.kter@protonmail.com>
Date: Tue Feb 6 09:05:10 2018 +0000
Translated using Weblate (Romanian)
Currently translated at 95.8% (393 of 410 strings)
commit ca68defd60db953419364758502b9a330b43598f
Author: Ldm Public <ldmpub@gmail.com>
Date: Tue Feb 6 07:38:41 2018 +0000
Translated using Weblate (French)
Currently translated at 98.2% (403 of 410 strings)
commit d0931b98aae70cfefee5e4b13f460aa7156c4270
Author: Verdulo <tomek@disroot.org>
Date: Tue Feb 6 19:35:39 2018 +0000
Translated using Weblate (Esperanto)
Currently translated at 100.0% (410 of 410 strings)
commit bf7173ca6ba9c7b3d9b6f361c2614827ee887e81
Author: Nathan Follens <nathan@email.is>
Date: Tue Feb 6 11:29:34 2018 +0000
Translated using Weblate (Dutch)
Currently translated at 100.0% (410 of 410 strings)
commit cdb4adc18c5ac818a16cb287624226093fe70a47
Author: Yaron Shahrabani <sh.yaron@gmail.com>
Date: Tue Feb 6 09:06:28 2018 +0000
Translated using Weblate (Hebrew)
Currently translated at 100.0% (410 of 410 strings)
commit 93dcc2a0ad171ab4b846e032756ca14c7bd04f04
Author: Sveinn í Felli <sv1@fellsnet.is>
Date: Tue Feb 6 07:41:40 2018 +0000
Translated using Weblate (Icelandic)
Currently translated at 100.0% (410 of 410 strings)
commit 5b359ea0fd1a5d8a5c3f67c2b448cf61c6c57424
Author: ezjerry liao <ezjerry@gmail.com>
Date: Tue Feb 6 01:45:45 2018 +0000
Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (410 of 410 strings)
commit 254dc5f0ad07349ba3f6e39fce37fc4cb17c88d1
Author: anonymous <>
Date: Fri Feb 2 16:09:15 2018 +0000
Translated using Weblate (German)
Currently translated at 100.0% (402 of 402 strings)
commit 44b823af4261f4a24b1fde8dc6bc662894583e2f
Author: Licaon Kter <licaon.kter@protonmail.com>
Date: Fri Feb 2 07:34:53 2018 +0000
Translated using Weblate (Romanian)
Currently translated at 96.7% (389 of 402 strings)
commit 0069bef97bcb4d5e87d8fd50c5023dcbe2ae563e
Author: Viktar Vauchkevich <victorenator@gmail.com>
Date: Wed Jan 31 19:20:15 2018 +0000
Translated using Weblate (Belarusian)
Currently translated at 100.0% (402 of 402 strings)
commit 92042d49087f950908a2d312a027976f44554205
Author: Марс Ямбар <mjambarmeta@gmail.com>
Date: Tue Jan 30 17:04:37 2018 +0000
Translated using Weblate (Ukrainian)
Currently translated at 97.7% (393 of 402 strings)
commit 0555d776876940629b1fc1f5fb99b98c139c5a98
Author: Xuacu Saturio <xuacusk8@gmail.com>
Date: Tue Jan 30 20:22:42 2018 +0000
Translated using Weblate (Asturian)
Currently translated at 100.0% (402 of 402 strings)
commit 2e9a284da728fc530f09640f0e33bcdf91947bce
Author: Luca D'Amico <damico.luca91@live.it>
Date: Mon Jan 29 16:40:19 2018 +0000
Translated using Weblate (Italian)
Currently translated at 100.0% (402 of 402 strings)
commit 7640aa3613cbf1d73093ee5445a21be699bfb178
Author: yamabiko <dragonfly@cryptolab.net>
Date: Mon Jan 29 16:38:41 2018 +0000
Translated using Weblate (Italian)
Currently translated at 100.0% (402 of 402 strings)
commit ffc447abaf1af07114b039c028805549e662894d
Author: Luca D'Amico <damico.luca91@live.it>
Date: Mon Jan 29 16:38:27 2018 +0000
Translated using Weblate (Italian)
Currently translated at 99.7% (401 of 402 strings)
commit 248e7df90d2aac7b3d189de0b241a44522202be0
Author: yamabiko <dragonfly@cryptolab.net>
Date: Mon Jan 29 16:38:20 2018 +0000
Translated using Weblate (Italian)
Currently translated at 99.7% (401 of 402 strings)
commit ce561bd4eff83280816322f0a74d6cf1695dd249
Author: Luca D'Amico <damico.luca91@live.it>
Date: Mon Jan 29 16:36:47 2018 +0000
Translated using Weblate (Italian)
Currently translated at 99.2% (399 of 402 strings)
commit 06d21c188e263b74fb5b1e200d207373418de1c7
Author: yamabiko <dragonfly@cryptolab.net>
Date: Mon Jan 29 16:36:14 2018 +0000
Translated using Weblate (Italian)
Currently translated at 99.2% (399 of 402 strings)
commit 2afc5deb08c8e5c41820f4a99cf82d8381eaec82
Author: リー <meluten@gmail.com>
Date: Sun Jan 28 12:15:27 2018 +0000
Translated using Weblate (German)
Currently translated at 100.0% (402 of 402 strings)
commit 28ebd01fbade7bf960a69e3cbfd88e1d32fb6b2c
Author: Yunyang Liu <ensigma96@gmail.com>
Date: Fri Jan 26 14:58:52 2018 +0000
Translated using Weblate (Chinese (Simplified))
Currently translated at 98.2% (395 of 402 strings)
This moves towards the standard Android Studio Ctrl-Alt-L code format with
only whitespace changes. This just removes this one kind of space, since
its widespread, and easy to track. I did this using:
sed -i 's," />,"/>,g' app/src/main/AndroidManifest.xml
extended info on things we already have:
* PRODUCT is another name for BRAND/PHONE_MODEL
* TOTAL_MEM_SIZE can be derived from hardware name
* DISPLAY is also available by looking up the hardware
* STACK_TRACE_HASH should make automated sorting easier
new info:
* PACKAGE_NAME is only new info if the user is using a whitelabel app
* AVAILABLE_MEM_SIZE can be used to track users, but only when provided at
high resolution, e.g. once per second or higher. Most users only send a
single crash report. High frequency reporters send under 100, which is
still orders of magnatude below what is needed to track users.
new file: app/src/main/res/drawable-hdpi/ic_az_white.png
modified: app/src/main/res/drawable-hdpi/ic_last_updated_black.png
new file: app/src/main/res/drawable-hdpi/ic_last_updated_white.png
new file: app/src/main/res/drawable-mdpi/ic_az_white.png
modified: app/src/main/res/drawable-mdpi/ic_last_updated_black.png
new file: app/src/main/res/drawable-mdpi/ic_last_updated_white.png
new file: app/src/main/res/drawable-xhdpi/ic_az_white.png
modified: app/src/main/res/drawable-xhdpi/ic_last_updated_black.png
new file: app/src/main/res/drawable-xhdpi/ic_last_updated_white.png
new file: app/src/main/res/drawable-xxhdpi/ic_az_white.png
modified: app/src/main/res/drawable-xxhdpi/ic_last_updated_black.png
new file: app/src/main/res/drawable-xxhdpi/ic_last_updated_white.png
new file: app/src/main/res/drawable-xxxhdpi/ic_az_white.png
modified: app/src/main/res/drawable-xxxhdpi/ic_last_updated_black.png
new file: app/src/main/res/drawable-xxxhdpi/ic_last_updated_white.png
modified: app/src/main/res/layout/activity_app_list.xml
new file: app/src/main/res/drawable-hdpi/ic_az_black.png
new file: app/src/main/res/drawable-hdpi/ic_last_updated_black.png
new file: app/src/main/res/drawable-mdpi/ic_az_black.png
new file: app/src/main/res/drawable-mdpi/ic_last_updated_black.png
new file: app/src/main/res/drawable-xhdpi/ic_az_black.png
new file: app/src/main/res/drawable-xhdpi/ic_last_updated_black.png
new file: app/src/main/res/drawable-xxhdpi/ic_az_black.png
new file: app/src/main/res/drawable-xxhdpi/ic_last_updated_black.png
new file: app/src/main/res/drawable-xxxhdpi/ic_az_black.png
new file: app/src/main/res/drawable-xxxhdpi/ic_last_updated_black.png
Things like permission support, locales, etc. can change when Android is
updated. So the database should be rebuilt from scratch with a fresh
download of the indexes.
closes#780
The database currently only stores the active language. So if the
user changes the system language of the phone, then the language of
all the app descriptions will be out of sync until the next update.
This forces an update when the locale is changed. This functionality
is also needed for events like OS upgrades.
closes#225
It was tried until it got an IP address, but that will only happen if there
is a wifi device configured. Since WifiStateChangeService is started when
F-Droid starts, WifiStateChangeService could run for days if someone never
connected to WiFi in that time.
WifiStateChangeService is also started by NETWORK_STATE_CHANGED_ACTION so
it should start each time there is a change to the WiFi connection.
It was already behaving like a singleton, but the code was spread around in
other classes. DBHelper does not use a private constructor though since
the tests prevent it.
Yes, this is an ugly and old style, but mixing styles only makes it worse.
Plus it breaks the tests in some cases, since it makes Preferences depend
on Resources.
This commit allows F-Droid to hide itself from the laucher.
It can be hidden either as response to a panic trigger
or as a manual action by long pressing the floating search button.
The latter needs to be explicitly enabled in the settings.
Once hidden, a semi-functional fake calculator app appears in the
launcher that can be used to bring F-Droid back by entering a
pre-defined PIN.
While a large buffer might make things slightly faster, the smaller buffer
size should play much nicer when F-Droid is doing things in the background.
Since calculating the hash is part of the update procedure, which can now
happen in the background, this method will be often running in the
background.
The tests showed no difference in time between the large and small buffer.
This gathers all files that are not tracked by git into a named ZIP file,
which is available for 1 week to download from the Pipelines page for the
fork that ran the build.
Donno how that magic number slipped in, this is the actual flag.
/builds/eighthave/fdroidclient/app/src/main/java/org/fdroid/fdroid/acra/CrashReportSender.java:31: Error: Must be one or more of: Intent.FLAG_GRANT_READ_URI_PERMISSION, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, Intent.FLAG_FROM_BACKGROUND, Intent.FLAG_DEBUG_LOG_RESOLUTION, Intent.FLAG_EXCLUDE_STOPPED_PACKAGES, Intent.FLAG_INCLUDE_STOPPED_PACKAGES, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, Intent.FLAG_ACTIVITY_NO_HISTORY, Intent.FLAG_ACTIVITY_SINGLE_TOP, Intent.FLAG_ACTIVITY_NEW_TASK, Intent.FLAG_ACTIVITY_MULTIPLE_TASK, Intent.FLAG_ACTIVITY_CLEAR_TOP, Intent.FLAG_ACTIVITY_FORWARD_RESULT, Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP, Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS, Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT, Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY, Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET, Intent.FLAG_ACTIVITY_NEW_DOCUMENT, Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET, Intent.FLAG_ACTIVITY_NO_USER_ACTION, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT, Intent.FLAG_ACTIVITY_NO_ANIMATION, Intent.FLAG_ACTIVITY_CLEAR_TASK, Intent.FLAG_ACTIVITY_TASK_ON_HOME, Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS, Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT, Intent.FLAG_RECEIVER_REGISTERED_ONLY, Intent.FLAG_RECEIVER_REPLACE_PENDING, Intent.FLAG_RECEIVER_FOREGROUND, Intent.FLAG_RECEIVER_NO_ABORT, Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS [WrongConstant]
MODE_APPEND is only for openFileOutput
/builds/eighthave/fdroidclient/app/src/main/java/org/fdroid/fdroid/localrepo/SwapService.java:105: Error: Must be one or more of: Context.MODE_PRIVATE, Context.MODE_WORLD_READABLE, Context.MODE_WORLD_WRITEABLE, Context.MODE_MULTI_PROCESS [WrongConstant]
There used to be a single loader which would get all apps which have
updates available. This was restarted when we were notified about new
apps requiring updates.
Then, in 7424220 I introduced a second loader responsible for getting
apps with known vulnerabilities. This change caused the bug in #1203,
because it changed the loaders from a single loader with ID = 0, to two
different loaders with arbitrary IDs. However, there was still a line of
code responding to when repo updates completed and we learn about new
updateable apps, and this was asking for a loader with an ID of 0 like
before. This crashed when the loader was completed and we tried to pase
the results.
This is fixed ensuring that both loaders are restarted upon learning of
new updateable apps. To prevent this disconnect in the future, they are
also extracted into the same method.
The workaround is fugly, so we really don't want to include it in the
modern code. Luckily, we have old index support there :-D
closes#1014closes#1202closes#1208#111
If a repo is set with the gitlab-ci Secret Variable DEBUG_KEYSTORE and
there is a repo named the same as this repo with -nightly appended,
then this will automatically generate an fdroid repo of each build
produced by gitlab-ci runs on the master branch.
closes fdroidserver#256
* App and index downloads fall back to a list of mirrors defined
by the repository.
* The changes have been made trying to keep the original download
code untouched, and only using the mirror logic when the download
fails due to a connection error / timeout.
* The mirrors are tried in a randomized manner, and with proper
timeouts. The download is aborted after the tries exceed the
number of mirrors, times 3 for a total of 3 different timeout
values (10s, 30s, and 1m)
* The mirror code isn't used for any images yet, most of which is
handled by an external library.
Closes: #35
The connected10 test runner has been at least as reliable as connected24,
and provides valuable coverage, especially for localization related
crashers.
Also does this with the additional field for ignoring vuln apps.
This should be safe, because there is a check for if (columnExists())
which will only pass if people don't already have this column.
Fixes#1181.
It seems that LocaleList does not necessarily return the "Language
Priority List" in the order that the user has prioritized things. So
we have to kind of fake it by first adding the default locale, then
adding the locales from LocaleList based on longest order first (e.g.
de-AT then de).
#987
The swipe-to-refresh from the latest tab is now also implemented
for the categories and updates tab. It was a bit weird before how
you could swipe to refresh on the first tab, which would show
"Updating repos" at the top. It would then also show the same
message on the categories tab, but you couldn't swipe-to-refresh
that tab. Additionally, several people have requested this on the
updates tab, the tab where it probably makes the most sense.
Fix#1079.
The controller in charge of dismissing an item will have an insight into
whether it will cause a re-query for an existing cursor or not. If a re-query
will occur in response to a `ContentResolver#notifyChange()` invokation (in this
case in response to updating `AppPrefs`), then the `UpdatesAdapter` doesn't
need to rebuild itself yet. If it is a status update, then it should update
the adapter right away.
Seeing as the controller was already returning one thing (a message to be
displayed in a `Toast` and now it also needs to return an opinion on whether
to rebuild the adapter or not, this has been extracted into a value object
which has a message and a rebuild adapter flag.
Items which can be updated (but have not yet been downloaded or queued for download)
will act as if the user selected "Ignore this update" from the app details view.
Items which represent app statuses (e.g. downloading, downloaded ready to install,
installed ready to run) will have the status removed. If required, we will also
forget that they are ready to install, so they wont be there next time.
Used to work, then the default join from `fdroid_app` to `fdroid_apk`
was removed for performance reasons. This adds the join back, but requires
queries to explicitly opt in to the join if they require it. The specific
query for known vulns is not a performance problem, because sqlite is able
to narrow the result set quite substantially before requiring a join onto the
fdroid_apk table anyway (e.g. by using the "installed app" table).
Untested because there are no apps in current repos which exhibit this
behaviour which have newer versions. Right now I'm testing with com.waze
from testy.at.or.at which only has the one version.
I'm also unsure of how important this is seeing as most the time it will
prompt people to update anyway.
Note that I don't think the query will work correctly across multiple repos,
because it is currently only querying the app with the "preferred
metadata".
Also use a newer version of testy.at.or.at index for the index-v1 test,
because it includes apks with "KnownVuln" anti features whereas the
older version did not.
When explicitly given an fdroidrepo(s) intent, it seems silly to restrict it based on
a path of /fdroid/repo, because it is plainly obvious it is an F-Droid repo.
Manifest and NewRepoConfig both had to be amended to allow this behaviour.
Fixes#1171.
There is a specific POSIX error "EIO" which seems to be the "general
purpose we don't know what went wrong but its probably bad" exception.
Our investigations in #855 resulted in the conclusion that it is likely
due to some sort of filesystem corruption or something like that.
Either way, it is annoying many people, so we need to prevent it or
ignore it, rather than prompting the user to submit a bug report.
After much investigation it was unable to be reproduced other than by
one of the original bug reporters. As such, this change ignores it.
Unfortunately Java `IOException`s don't have an API for getting the
errno of a POSIX IO error. Thus, this change results to parsing the
exception message instead :(
Fixes#855.
This improves performance when we need to decide whether or not apps are
installed or not while scrolling through large lists.
Fixes#1143.
Also change Jackson tests to properly ignore App#isApk.
This join resulted in one row for each apk in the result set (before
doing a GROUP BY), instead of one row for each apk. That is a large
difference in number of rows and resulted in much more work for sqlite.
Turns out this join wasn't required.
Some queries are deferred, and then forced to run by Android by invoking
`getCount()`. Under these circumstances, the measured speed of the query
execution is 1ms.
This adds speed logging around `getCount()` in case that is the first time
the query is run.
clbin is just for making the logs easy to read, if it fails, the build
should not be marked as failed, especially since the logs are probably
not needed if the rest of the job succeeded.
This is in the spirit of the setting, where users can see which apks are
available even though they are not installable.
Adds a message explaining why it is incompatible (i.e. because the
signature doesn't match the installed version).
PNG crunching is not a deterministic process, especially the way aapt does
it. This makes the F-Droid builds not reproducible. The easy solution to
this is to pre-crunch the PNGs and commit them to git. It also makes the
final APK a tiny amount smaller, for whatever reason.
https://medium.com/@duhroach/smaller-pngs-and-android-s-aapt-tool-4ce38a24019d
Instead of including the etag in the HTTP GET request and letting the
server set the Response Code depending on whether the etag machines, this
makes the client first issue a HEAD request, which is uses to get the etag
and the file size. We need to do the HEAD beforehand anyway to get the
file size for resumable downloads, and this approach prevents the server
from using the etag as a form of tracking cookie:
http://lucb1e.com/rp/cookielesscookies/closes#562
- Icon transition is no longer jumping in first frame (caused by different padding)
- Icon is no longer cropped at start of transition (caused by missing changeImageTransform)
- Toolbar icons are no longer animated. Introduced in !561 by changing the icons programmatically
This caused problems when users then tried to action the pending
install, where it would no longer have enough information to install the
app. Although it may be technically possible to keep enough information
around in memory to make the app installable, but it is not worth the
effort. If a user intentionally disables a repo, we should no longer be
responsible for keeping information about its apps around.
Fixes#995.
There are some ACRA reports with this IllegalStateException getting hit.
It used to be that it was only ever because we forgot to request the
correct fields from the database. However now I'm not sure that this is
the only source. Perhaps it is also possible in response to parcelling
apk instances, or maybe something else? Either way, this should provide
further info about whether the apk doesn't belong to a repo for some
reason.
There are two methods which allow callers to choose which fields to
return. These were originally added for performance, so you only ask for
what you need. However empirically the performance gain doesn't mean
anything, because it is dwarfed by the query that was just executed.
However, it does open the code up to bugs because we forget to ask for
the right fields. So now it just returns all fields when querying for
apks.
While investigating #1086 which was about swap being busted, I
discovered that we recently introduced a worse bug when working with
multi sig stuff. The swap process, when installing an app (or even when
listening for if a user started installing - before they even did
anything), would ask for an apk from any repo. This is wrong, because we
should only ask for the apks from the swap repo when presented with a
swap dialog.
By fixing this so that it asks for a specific apk, this may also
fix the issue in #1086, because that was about us not asking for enough
info from the database for each Apk which was returned. Now we just
return all columns, because the performance overhead should be minimal,
but it prevents this class of bugs, where we didn't fully populate
our value object. However, I'm not confident that it is fixed, because I
was unable to reproduce it due to the other crash fixed in this change.
Relevant crash:
```
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.fdroid.fdroid.data.Apk.getUrl()' on a null object reference
at org.fdroid.fdroid.views.swap.SwapAppsView$AppListAdapter$ViewHolder.setApp(SwapAppsView.java:311)
at org.fdroid.fdroid.views.swap.SwapAppsView$AppListAdapter.bindView(SwapAppsView.java:422)
at org.fdroid.fdroid.views.swap.SwapAppsView$AppListAdapter.newView(SwapAppsView.java:414)
at android.support.v4.widget.CursorAdapter.getView(CursorAdapter.java:269)
at android.widget.AbsListView.obtainView(AbsListView.java:2349)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillDown(ListView.java:698)
...
```
Each app insert required asking the database for the ID of each
category an app is in. Given the categories don't change (ever)
but are only appended to, we can cache the results in a static
Java variable for increased performance.
This reduced the "repo persister" logic for me from 50 seconds
for main F-Droid and 100 seconds for Archive, down to 15 seconds
and 30 seconds respectively.
Now that we need only "insert" new apps rather than"
* Identify if an app exists
* If so, update
* If not, insert
There is much less code required for all of this stuff.
When preparing a temp database to write to, don't copy all apps/apks.
Instead, only copy those _not_ belonging to the repo we are updating.
In an ideal world, we'd not even need to copy them, but we need
their IDs to be in the temp database so that we don't accidentally
use the same auto-generated ID as the main database.
This also means that we can drop the check for "does this app exist,
and hence should we UPDATE it instead of INSERTing it?" and always
just insert it.
Then, when copying the temp table back to disk, first delete all
apps/apks _belonging to the repo being updated_. Then, copy back the
apks/apps we found in the repo. This again improves performance because
we no longer need to bopy back and forth data which we know
wont change (as evidenced by the fact it belongs to a differen trepo).
I don't think this was possible earlier before we did the work to
support repo priorities properly. That is because we had a single app
which was serviced by several repositories. Now, we have multiple
entries in the `fdroid_app` table, for each repo which supports
that app.
The test files used in Issue763MultiRepo.java are signed using MD5, which
is now considered invalid. So if that test is run on any recent Java, it
will fail with a signature error. This updates the test files to be signed
with SHA1 instead.
* index.microg.jar is a new version fetched from https://microg.org
* index.antox.jar was resigned with the testy.at.or.at key, since antox
website doesn't exist anymore.
RepoUpdater.prepareRepoDetailsForSaving() was broken here because the Repo
properties were being set before calling it, and then the Repo instance was
passed to it for comparison. So the comparison was always saying the value
was unchanged. In IndexV1Updater, the flow doesn't need those checks.
This also fixes the bug where added repos never had their name/description/
icon/etc show up in ManageRepos and RepoDetails.
@cde found this bug working on mirror support, thanks!
related to #35closes#1016
This is not really a useful way to tell the user that the index might be
out of date. It just adds confusion and makes people think that F-Droid
isn't quite smart enough to know what's going on.
The install process automatically sanitizes filenames to avoid exploits
that put attack code in the filename. Media files are also installed using
this logic, so the installed check needs to use sanitized file names to be
accurate.
This will be more important as people work with media, since it is quite
common to use spaces in filenames generated by humans. Media files will
not be built by fdroid, so most likely, they will have human-generated
names.
* This installer is invoked when for non-apk/media files, and
copies them to an appropriate folder on the sdcard.
* We also introduce a FileInstallerActivity to ask for storage
permissions at runtime, as needed by Android 6.0 and above,
and handle the install/uninstall process.
* A toast is shown with the install path after installation.
TODO:
* Manage Installed Apps screen doesn't show media files.
* For non apk files, the signature column would be NULL always,
and in SQLite NULL = NULL is false, but NULL IS NULL is true.
See http://www.sqlite.org/lang_expr.html Operators
If an app is downloaded into our cache, but an app with the same hash is
already installed, don't bother notifying people about it.
Extracted the logic for finding the path to an apk on disk (given a
PackageInfo object) to also be used by AppUpdateStatusSerice.
Change logging so that if we discard a downloaded file we Log.i instead
of Utils.debugLog. This is so that when debugging a release build we can
see what is happening, because this specific problem was easier to debug
with release builds (rather than setting up a custom fdroid repo).
Before mult-signature support, the process of marking an app as
installed in the `InstalledAppProvider` didn't have any side effects
beyond its own table. Now, it is also responsible for calculating the
`suggestedVersionCode` of the associated app as well.
This means old tests around suggested versions no longer work. This is
because they would insert an App, and set the
`Cols.SUGGESTED_VERSION_CODE` using a `ContentValues`. This was then
overwritten by the `InstalledAppProvider` asking for the real
calculation for suggested versions. That is - it would check for
relevant apks and figure out which was best.
To make the old tests correct, they need:
* To be able to "install" apps with the correct signature.
* To insert the relevant apks into the database, not just depend on the
presence of an `app`.
Previously, it was only done on repo update.
Now it is done whenever an app is installed or unisntalled. The query to
update the suggested version for each app is quite slow when run at the
end of a repo update. However in this change, we are limiting the query
to only update a single app, which means that performance should not be
a problem.
When a single repo provides apks with multiple signatures, then we need
to be able to select the preferred one. This adds tests for this which
fail, because that feature has not yet been implemented.
This is a conservative fix. If we wanted to really highlight the
feature graphic functionality and reward upstream devs for keeping
metadata up to date, then we could also take apps which were recently
updated, and prioritise them over new apps if they have a feature
graphic.
Fixes#938.
Also fixed display of feature graphic in main screen by getting full
path to image, not the relative path (e.g. "en-US/featureGraphic.png").
This creates a hard dependence between `RepoUpdater` and
`UpdateService`. However this could be trivially extracted by moving the
helper methods from `UpdateService` to `RepoUpdater`, and making the
broadcasts more "repo updater" oriented. That would also require
changing the broadcasts which `UpdateService` listens for.
Reuses the "commiting" message to indicate how many apps have been
processed so far.
Refactors existing progress handling between `RepoUpdater` and
`UpdateService` to use `LocalBroadcastManager` in preference to
`ProgressListener`. Still needs to use `ProgressListener` to talk
between `RepoUpdater` and the `Downloader` +
`ProgressBufferedInputStream`.
The only change that is related to something more important than
notifications is the fact that now `IndexV1Updater` makes use of the
`indexUrl`. To do so, because it is final, the base class constructor
delegates to `getIndexUrl()` which is overriden by the v1 updater.
This is required because we want to differentiate between broadcasts
coming from different repo update processes.
Fixes#1054.
This was setup to work correctly, but for two problems:
* The `cursor.close()` in `CategoriesViewBinder` stops the cursor from
being requeried when required.
* The `AppProvider` was not notifying correctly after deleting apps
belonging to a repo.
Fixes#1028.
Moved methods around so the class is more coherent when reading from top
to bottom.
Added some comments.
Formatted lines to be under 120 chars. No longer suppress line length checkstyle messages.
This breaks out subclasses for each specific type of app list item,
allowing for code reuse, but also letting the specific business logic
belonging to each different app list item to be separate.
This is particularly helpful in the following situation:
* In the search results, it is great to be able to render "App
downloaded, ready to install" in the same manner as the update tab.
* In the installed app list, this is not desired. Indeed, the status
text which should be shown should reference the currently installed
version and whether the user has ignored any updates.
By separating the AppListItemController into subclasses, it reduced the
need to handle several different types of text view (e.g.
"installedStatus", "status", "ignoredStatus", "downloadReady"), and
replace them all with a "status" and "secondaryStatus" TextView. What is
displayed in status and secondaryStatus is up to the individual
subclasses of AppListItemController.
Previously, there were different pieces of business logic, invoked at
different times, which would touch subsets of the UI.
This change rips that out, and replaces it with a single place where the
UI is setup. This can always be called safely, and it will render the
correct data for the current state of the app (e.g. downloading, waiting
for install, etc).
The AppListItemState class is a dumb object which keeps track of what is
supposed to be displayed in the UI. The AppListItemController now
creates a different AppListItemState depending on what state the list
item is in. This AppListItemState is then used to bind the values of
each UI widget.
All of the binding code is now in the single `resetView()` method, but
all of the business logic for what the view should look like is
separated into different `getViewState*()` methods.
This separation should make it easier to make sense of the UI code, and
hopefully should be testable should somebody choose to write tests for
it in the future.
The docs say that initLoader tries to reuse existing cursors.
The error message was "IllegalStateException: attempt to re-open an
already-closed object: SQLiteQuery: ...".
There may be a bigger problem around suggested versions being null at
all, but that is getting looked at in a different feature set (i.e.
multi signature support) and will come in time. This fixes the immediate
problem some people were having and sending crash reports for in 0.104.
STACK_TRACE=java.lang.NullPointerException: Attempt to read from field 'java.lang.String org.fdroid.fdroid.data.Apk.versionName' on a null object reference
at org.fdroid.fdroid.views.AppDetailsRecyclerViewAdapter$HeaderViewHolder.bindModel(AppDetailsRecyclerViewAdapter.java:425)
at org.fdroid.fdroid.views.AppDetailsRecyclerViewAdapter.onBindViewHolder(AppDetailsRecyclerViewAdapter.java:244)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6310)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6343)
...
Introduced in 97fd3f0.
* F-Droid cannnot uninstall system apps, only their updates,
but even with the privileged extension, that can get complicated.
* Let's just not allow uninstalling system apps, the phone's settings
app can happily disable/re-enable system apps, and also uninstalls
their updates on disabling.
If the client fails due to some bug in handling index-v1.jar, then it will
be totally stuck, even if index.jar would have worked. This creates a new,
temporary "expert" preference to force the client only use the old XML
index file. Worst comes to worst, we can tell people to enable this to
upgrade.
Once everything proves stable, we can remove this.
This started with the work of @kingu, it cleans up some of the language,
including:
* upgrade --> update
* application --> app
* internet --> Internet
closes!508
... when PackageInstaller is the installer (privext).
* In the case where the Privileged Extension is installed,
but the installation happens through DefaultInstaller still
due to something like a permission mismatch,
that is set as the installer package name.
* We cannot install packages installed by that via the system methods,
so fallback to DefualtInstaller for uninstalling as well when the
app is installed by PackageInstaller
The fact that Cursors are used with the apk provider is more of an
implementation detail (to some extent). It is a crappy, leaky
implementation right now, but still an implementation detail.
This should probably be done on the database level, if purely for the
fact that we have a good set of unit tests for that. However it is still
quite clean to do so here.
This is really the intention of the method, given it used to accept
a version code and a package name. Now it optionally accepts a sig
also. If present, it will restrict the query to apks with that sig.
Also added to the multi-sig tests to ensure this method takes it into
consideration.
There is some magic conversions going on so that booleans get
converted into integers, but they are only on Android. Under
robolectric, it throws a class cast exception instead.
Some were removed and left removed if they were run during tests,
because the tests are supposed to be automated and the noise they added
would not have helped diagnose a failure.
Also removed the dead code around "uses-feature" which will never
get implemented, especially as it is in the XML index.
The main problem is that we were using an index on fdroid_apk.vercode,
when it should have been using an index on fdroid_apk.appId. There are
thousands of apks which would match based on vercode, but only two or
three which match based on appId. This improves performance of the
calculate-suggested-vercode query from 25,000ms to 100ms.
Produces the following output:
D Explain:
D SCAN TABLE fdroid_app
D EXECUTE CORRELATED SCALAR SUBQUERY 0
D SEARCH TABLE fdroid_apk USING INDEX apk_vercode
D EXECUTE CORRELATED SCALAR SUBQUERY 1
D SEARCH TABLE fdroid_app AS innerAppName USING INTEGER PRIMARY KEY (rowid=?)
D EXECUTE CORRELATED SCALAR SUBQUERY 2
D SEARCH TABLE fdroid_package AS pkg USING INTEGER PRIMARY KEY (rowid=?)
D SEARCH TABLE fdroid_installedApp AS installed USING INDEX sqlite_autoindex_fdroid_installedApp_1 (appId=?)
There are two possibilities here, one is the number of correlated sub
queries (three seems a bit excessive). Alterantively, it could be the
fact that one of the inner queries is using a string index (appId=?)
instead of an integer primary key.
The history of this is that #974 identified a problem, which was fixed
in !497. That MR added test coverage for the bug.
However, the fix for it actually added a huge performance hit, on the
order of 30 seconds or so when calculating the suggested version.
This fixes that performance problem by removing the need for a sub
query. The end goal is to take the following query:
```
UPDATE app
SET suggestedVersion = (
SELECT MAX(apk.version)
FROM apk
WHERE ...
)
```
and the `WHERE` clause needs to somehow join the outer `app` table with
the inner `apk` table, such that the repo in question does not matter.
It can't just join directly from `apk.appId -> app.rowid`, because the
`app` is specific to a given repository, but we want to select the
`MAX(apk.version)` from every related apk, regardless of repo.
This commit solves it by joining the inner `apk` table onto an
intermediate `app` table, which is used purely so that we can select
apks where their `packageId` is the same as the `packageId` of the app
being updated.
Carrie specified colours earlier, and they were added to the code.
However they were not being read correctly. This changes that so that
lowercase resource names (e.g. "category_games") are used instead.
It also adds the final category artwork, for "Games" which was
missed prior.
The rest still generate colours and patterns if they don't have a colour
or an image specified.
With a 1 second debounce, I was getting the view to refresh
several times in response to large apps being processed (e.g.
Firefox, OSMAnd, etc). This was on a (relatively) recent Moto X
2nd Gen, so it would be even more visible on an older device.
The side effect of updating frequently is that the main list
of apps flashes regularly in front of the user (see #986).
This "update the view" is only in response to a background
task that is expected to take several seconds (e.g. 30 seconds)
anyway, so waiting 3 seconds instead of 1 is not particularly
problematic.
If F-Droid was actually removed, then we wouldn't even
have an installed app cache (we aren't even on the device
any more). As such, ignore all requests to remove F-Droid
because it complicates the installed apk cache. Specifically,
there is a race condition between the "compare apk cache to
package manager" and the "package removed receiver", where
the later was overriding the former.
There is a persistent shared preference which dictates whether apps
have been successfully downloaded and are ready to install. When
the `InstallManagerService` used to receive an `ACTION_INSTALL_COMPLETE`
broadcast, it would update this preference to no longer be installing.
However, this never got received in the case of F-Droid updating itself.
In that case, we need to instead wait for the system to broadcast an
`Intent.ACTION_PACKAGE_ADDED` intent. This change waits until that
point before removing the preference.
Fixes#1027.
gitlab's diff views wrap badly when lines are longer than 118. Android
Studio places a grey line in the UI at 120.
@SuppressWarnings("LineLength") is added to a bunch of files to prevent
making this commit huge. People can remove that as they work on those
files, and fix the issues then.
I also ran Android Studio's default Ctrl-Alt-L code formatter, where it was
easy to do, and I was already in the file.
The response to receiving PendingDownload was always a more specific
case of the Downloading event. By removing it, the code which was listening
for Downloading events is capable of doing everything that the PendingDownloading
listeners were doing.
Same as how AppDetails2 was recently cleaned up to depend more on
AppUpdateStatusManager.
In addition, it also removes items from the "X apps can be updated"
lower part of the "Updates" view when they are present in the upper half
(i.e. the half showing feedback about the current download/install
progress).
No longer do we try to nicely maintain the state of the adapter in "Updates"
in order to notify the recycler view about changes to its underlying data.
Instead, we just rebuild the entire structure each time a new thing needs
to be shown/removed.
This means no more smooth scrolling to the relevant item after it is
changed, but it results in a far less buggy interface.
This means that we no longer need to receive an APK_URL and then
directly ask the status manager for the relevant status object.
This causes problems when consecutive updates happen in the same event
loop, e.g. download started + download complete. In this case, the
receiver will receive two events for the same app. When it asks for the
associated status object for the first (download started) event, it will
receive a status that says "download complete ready to install". This is
because the status object has already been updated by the second event.
Furthermore, the broadcast manager must receive a copy of the status
object, not the original object. This is because the broadcast manager
doesn't parcel the relevant extras until the end of the event loop. This
means that if the status is changed twice in one frame, then both
parcels will end up looking the same. By sending through a copy instead,
this ensures that any listener receives the statuses in the correct
order, rather than two parceled versions of the same status
notification.
Also, make sure to correctly update the app details view when te user
leaves then returns to the view. Prior to this, the user would need to
wait for a download event to be received. However even that was broken,
because the download listener was not being added correctly once the
user returned to the app details screen.
Even though the categoyr mage loader explicitly says not to cache
images on disk (because they are not coming from the network anyway),
UIL still uses the `FilenameGenerator` to come up with a disk cache name.
Because the file name generator takes the "path" of the URL being
downloaded, and the categories are loaded like "drawable://2134234",
there is no path. As such, the file name ends up being meaningless.
This results in the image loader testing for the existance of the file
on disk (even though we asked not to cache on disk), and then failing
with an IOException (that gets swallowed).
By providing a meaningful name from the file name generator, it now
works as expected.
Fixes#1039.
Lots of languages really need the <plurals> tags to make sense, so
this also makes lint exit with an error when it finds strings that
should be <plurals>
closes#883
Previously, it would either send "base.apk" (in earlier versions of
F-Droid when bluetoothing an apk from the /data/app/... dirs), or
"install-[random].apk" (if recent F-Droid when copying file to a safe
place to expose via a FileProvider.
This now writes the file to, e.g. "F-Droid-0.103.1.apk" before sending.
Note that this means files are more likely to be overridden when being
sent, if the same apk from two different repositories is either:
* Sent via bluetooth
* Prompted to install via the system package manager
However this should still never let malicious people write to that
folder.
This ensures that the `PendingIntent.FLAG_UPDATE_CURRENT` doesn't
continually override earlier intents with the last app to be notified.
This could probably equally be done by leaving the request code as 0 and
removing the FLAG_UPDATE_CURRENT out, however it seems much more
semantic to have a separate request code for each different pending
intent.
Fixes#1021.
The hack that goes through and checks whether a language is present in
the APK seems to cause random strings to switch to English when the
app is running. So this removes that hack, and instead switches the
Languages menu to a hard-coded list. Languages that are not present
or close to complete were removed from the old list.
closes#943closes#1010
Reuses the code that the installer uses, when it broadcasts to
the relevant installer that an Apk is available for install.
This used to do the following:
* Copy file to a private directory
* Make the file world readable (so that PM can access it)
* Send a file:// URI to the installer
The file:// URI is no longer supported for reasons explained in
the support lib FileProvider class. Now a content:// URI is required,
and that must explicitly grant permission to certain packages.
The existing code here used to grant permission to
org.fdroid.fdroid.privileged, and this code now also grants it to
com.android.bluetooth. I see no security threat with exposing these
files to both applications, because the .apk files only ever:
* Were downloaded from the public internet into a (potentially public)
cache dir.
* Were sourced from an `ApplicationInfo#publicSourceDir, in which
case any app can access that anyway.
Fises #837.
If the user can set the language using the Setting app, then there is
not reason to use the Languages hack. This then clears the preference
if it matches the language of the system-wide locale. This also
removes the current system-wide language from the Languages menu.
closes#943
Since we have all these lovely scripts for cleaning up the
translations, gitlab-ci is a handy way to enforce that they get used.
Since weblate merges happen via merge requests, this will work nicely
now. I can't think of any false positives that will arise, but we
shall find out!
XML namespaces are a massive pain to deal with in, and they are totally
unneeded in the translation files. xmlns:tools is only needed in the
source file to ignore some lint warnings.
All feature graphics are called `featureGraphic.png`, and so our cache
was presuming all feature graphics were the same image. By including
the full path from the server in the cached name, we don't overwrite
images any more.
Right now, org.fdroid.fdroid.privileged.ota and FFupdater do not
provide any icons and it seems that that triggers this crash:
ACRA caught a NullPointerException for org.fdroid.fdroid
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.lastIndexOf(int)' on a null object reference
at org.fdroid.fdroid.FDroidApp$5.generate(FDroidApp.java:282)
at com.nostra13.universalimageloader.cache.disc.impl.BaseDiskCache.getFile(BaseDiskCache.java:167)
at com.nostra13.universalimageloader.cache.disc.impl.BaseDiskCache.get(BaseDiskCache.java:98)
at com.nostra13.universalimageloader.cache.disc.impl.LimitedAgeDiskCache.get(LimitedAgeDiskCache.java:74)
at com.nostra13.universalimageloader.utils.DiskCacheUtils.findInCache(DiskCacheUtils.java:36)
at org.fdroid.fdroid.NotificationHelper.getLargeIconForEntry(NotificationHelper.java:506)
at org.fdroid.fdroid.NotificationHelper.createUpdateNotification(NotificationHelper.java:300)
at org.fdroid.fdroid.NotificationHelper.createNotification(NotificationHelper.java:191)
at org.fdroid.fdroid.NotificationHelper.access$400(NotificationHelper.java:37)
at org.fdroid.fdroid.NotificationHelper$1.onReceive(NotificationHelper.java:106)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46)
at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:116)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
* Avoids crashes when trying to treat non apk files, such as
privileged extension ota update.zip as apks
* Doesn't do anything at all for now.
One issue with this is the app is always in the not installed state,
so what would be appropriate here would be to change the text of the
install button to download, and update that accrodingly.
However that is outside of the scope of this change.
TODO:
Add toast indicating the user that they need to install
manually, in case of OTA update.zip
This zeros out the etag in the fdroid_repo table and then asks
the update service to perform an update.
The end result is that changing the language will result in the metadata
being shown in that language.
Note: This doesn't immediately work due to pending changes around
Locale.setDefault() and the change in case from Summary to summary in
the server metadata.
This reverts to the previous behaviour before 8faf151.
Then, the InstalledAppProviderService would queue up a series of
changes, and only notify after 1 second of nothing being added to
the queue. This was good because CursorAdapters and LoaderManagers
would not continually requery the database several times a second (only
once at the end), but it meant there was a lag in the AppDetails screen
getting updated after installing/upgrading/deleting packages.
This restores that behaviour where general events (e.g. "some misc apps
in the database were changed") are "debounced" for 1 second. However it
also emits a more specific "package org.blah.com was changed" instantly.
In the long term, it would be good to remove any dependency on
ContentObservers and `notifyChange()` altogether, in preference of
either LocalBroadcastManager or RxJava. However this will depend on how
we go about changing the database layer in the future. The fact we now
depend on ContentProviders means that it would be a big change to move
away from LoaderManager + notifyChange().
Fixes#986.
connected24 tests are frequently failing saying that while an emulator
is running, its not compatible. This is bizarre. This just adds debug
output to help troubleshoot that.
I have found no explanation of what should work and why, but language
choosers seem to always include this line. This also seems to fix the
bug:
closes#943
This makes the license a link to the spdx.org page for the app's
license. I think this is an improvement over the way the license was
displayed before 0.103 since it provides a direct link to the actual
text of the license.
The license icon is a modified version of the public domain icon:
https://commons.wikimedia.org/wiki/File:Cc-sa_white.svgcloses#960
* Addition: Try to get apk details via InstalledAppProvider too.
* In certain cases, such as the "UnifiedNlp (no GAPPS)" app on a device
with actualy GAPPS / GMS installed, apk can be null which leads
to a crash
* Ask InstalledAppProvider for the app's details too, like it
was done in the old UX AppDetails.
* Also seen when uninstalling app with a signing key different,
fixes#985
In android-24 and newer, the user can specify multiple languages in a
priority list. Therefore, the locale chooser logic here does not need
to work so hard to find a language match. For example, if the user
wanted to see country-specific variants, they would add them to the
preference list.
With older versions of Android, the pref is only a single locale. So
chances are that someone who specified de_AT would rather see de or
de_DE than en_US. Same goes for es_AR, ar_EG, etc. This could annoy
Chinese speakers, since someone who sets zh_TW could potentially see
zh_CN, which are written pretty differently.
Android 24 and later provides tons of languages, and a way to rank
multiple languages instead of choosing one. The Languages pref is a
big hack and can be problematic, so its better to disable it when its
not needed. This will make it so it is no longer possible to set
F-Droid to a language that the system does not support.
#943
There was a bug where the repo with the highest priority would be
responsible for specifying the suggested version code. When doing so, it
would only select from the list of apks available in that repo. This
improves the calculation so that when any given repos app gets a
suggested version code assigned, it selects from _all_ available apks,
not just those from the repository in question.
Fixes#974.
This allows us to test "installing" Adaway, which has a native code
dependency that the default Robolectric setup doesn't support (defaults
to armeabi-v7a).
The version check guarded against downgrades, and would not notify the
user if it found a downgrade in the apk cache. However this was from
before we could ask `AppUpdateStatusManager#isPendingInstall(hash)`. Now
we don't need to care whether it is an upgrade or a downgrade, because
there is a more authoritative source as to whether this apk is
interesting to us or not.
There may be multiple apk files with the same hash. Although it is not a
security issue to install one or the other (they are exactly the same
binary), they may have different metadata to display in the client.
Thus, it may result in weirdness if one has a different
name/description/summary etc).
This change takes each of the matching Apk objects from the database,
then asks them where they expect to be downloaded. It matches this
against the File that we are looking at and only returns if they match.
According to the following this is not supported:
* http://stackoverflow.com/a/13471695/2391921
This uses the approach in that SO answer, by extracting the attribute to
instead point at a drawable, and have one drawable for each theme.
Fixes#979.
PMD does not like manually throwing NPEs, even if they have more verbose
information than the default NPE. As such, use an
`IllegalArgumentException` instead.
Instead of showing them below the icon, it now puts the icon + name +
author + last updated into a single layout which can grow if the app
name or author wraps to a second line. The buttons are now below this
additional layout.
Although I'm unsure of exactly why this is `null`, it seems sensible
that there is a possibility of null icons (e.g. for .zip files or other
media). As such, this just adds a guard condition to ensure that the
`iconUrl` is not null.
Fixes#981.
Received the following crash report, where the user said it crashed
while trying to install the priviledged extension:
```
java.lang.NullPointerException: Attempt to read from field 'android.content.pm.Signature[] android.content.pm.PackageInfo.signatures' on a null object reference
at org.fdroid.fdroid.installer.ApkSignatureVerifier.getApkSignature(ApkSignatureVerifier.java:70)
at org.fdroid.fdroid.installer.ApkSignatureVerifier.hasFDroidSignature(ApkSignatureVerifier.java:54)
at org.fdroid.fdroid.installer.ExtensionInstaller.installPackageInternal(ExtensionInstaller.java:53)
at org.fdroid.fdroid.installer.Installer.installPackage(Installer.java:265)
at org.fdroid.fdroid.installer.InstallerService.onHandleIntent(InstallerService.java:77)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.os.HandlerThread.run(HandlerThread.java:61)
```
Not sure how to address it yet, so adding more specific excetpion for
if it happens in the future.
This pulls all the categories out of the database at once for sorting,
rather than sorting in SQLite. This is to prevent having to store the
localized category names in the database (and hence having to update
them when the locale is changed).
Fixes#967.
Previously they were left to be sorted however SQLite parsed the query.
This turned out to result in them beign sorted by repos first, then
names. For example, all of the GP apps would be at the bottom of the
list.
Fixes#965.
Use SharedPreferences to keep track of whether we are in the middle of
an install for a particular apk or not. If sothen the presence of an
.apk file in the cache means we need to tell the user (in the updates
tab) that a file is ready to install.
Previously this only worked for apps which were being upgraded to the
latest available version. Now it works for apks being upgraded from an
old version to a newer-but-not-newest version. Perhaps more importantly,
it also now works for newly installed apps.
This has a problem where if a user installs, then uninstalls an app,
they are still notified about installing it. This is because the apk
is in the cache and the code doesn't know whether it is there from
the initial install, or because it has been redownloaded by the user
to install some time after uninstalling.
The only pending intents that were not explicit were the four from
the NotificationHelper class. These now explicitly specify the
NotificationBroadcastReceiver as their destination, which is not
exported. That then forwards the intents onto relevant methods of
AppUpdateStatusManager.
With this, it was leaving the app's locale set to the last language on
the LOCALES_TO_TEST list, which is 'zu' (Zulu). For some dialogs, it
was actually using that locale, so showing OK/Cancel in Zulu despite
the app being in a different language.
#943
We've had a number of crashes due to bad formats in various
translated strings. This test runs through all of the translated
strings and tests them with the same format values that the
source strings expect. This is to ensure that the formats in the
translations are correct in number and in type (e.g. {@code s} or
{@code s}. It reads the source formats and then builds {@code
formats} to represent the position and type of the formats. Then
it runs through all of the translations with formats of the
correct number and type.
I couldn't get the Resources stuff working in Robolectric, so I
made this an emulator test.
The change to the Swedish translation included in this commit are
fixes for issues that these tests found.
closes#923
Java's Map.get() returns null if there is no match, so this was always
setting each entry to whatever value was in the highest priority
locale, whether it had contents or what null. Now, this will fall
through the priority list of locales until it finds actually contents.
A TreeSet apparently does not really maintain insertion order, while a
LinkedHashSet does. This ensures that the insertion order of locales
is preserved in localesToUse so that the prioritization is correct.
Just let the SecurityException be throwing where it originated.
From PMD: "A catch statement that catches an exception only to wrap it
in a new instance of the same type of exception and throw it should be
avoided".
This cleans up a little from !482. Ctrl-Alt-L and Ctrl-Alt-O before
committing! :-)
* On API >= 24, in cases when the installer package name is not set
to privext, the system won't let us uninstall.
* Fallback to the DefaultInstaller so that uninstall still works.
* When there's a permission mismatch (#951, #890), the fallback
DefaultInstaller is invoked, which enforces file and content schemes
for API < 24 and >= 24 respectively.
* Use content URI in that case, which allows the fallback to work.
The script checks for `<string/>` elements which have misformated
arguments in them. It Now also checks for `<plural><item /></plural>`
elements too.
closes!472
<plurals> handles the grammar needed for numbers/quantities in various
languages. Like in a number of slavic languages, numbers ending in 0,
1 or others have separate grammar. In English, there is just 1 and
then all the rest (0 days, 2 days, 3 days, etc). <plurals> does not
handle multiple strings for different quantities, like having a
different string for each number case. For that, we have to do it in
Java and have multiple <strings>
!472
Prior to this, it would only update the "Uninstall"/"Run"/"Upgrade"
buttons after a fresh install, or an uninstall.
This change is a bit more liberal in how often we try to update the
view, due to a race condition with PackageManager and AppDetails2.
AppDetails2 listens for InstalledAppProviderService in onResume, but
sometimes that is too late (the notification has already fired).
fdroidserver currently only supports a single WhatsNew field that
comes from the CurrentVersionCode of the app. Google Play and
fastlane supply support a WhatsNew field per-release, but we don't use
that data anywhere, and implementing that in the data structures would
add a lot of complexity since Apk would then need to have its own
"localized" section like App does.
The "Video" field is just a URL pointing to a video.
closes#910
I added Esperanto because someone asked, and Shqip since it is not
available in Android 5.1 and people who speak Shqip would be likely to
open the language menu to switch away from English, then they'd see
Shqip as an option. This still won't take effect until those
languages are fully translated.
closes#941
The point here is to use the English work all lowercase, so make sure
that the English lowercasing rules are always active, regardless of
the system's locale.
The original single language description gets stuck straight into
App.description by Jackson. getLocalizedEntry() might return a null,
in which case it was overriding the original description. This only
overrides the original description if there is actually a localized
description.
* Replace hardcoded color values with references to style.xml,
which in turn has different values for light and dark theme.
* Force reload the activity to get the theme applied.
TODO:
* Swap uses it's own theme, need to figure out a way to
handle that. Currently the main Nearby screen which you get
to from the bottom navigation is ok, but anything after
that is light / custom themed.
Given the only feedback available to the user that they initiated a
download once clicking the version from the list is up top, this scrolls
the recycler view to the top to show that feedback.
Also shows the selectable background when they touch the version list
items.
Previously, it assumed that featureGraphic et al. were always present if
the localised entry was present. This is not the case, so we only return
a URL if we can actually find the entry we are looking for.
Prior to this it was black, which looked broken. This also ensures that
the blue is shown behind the dynamic colour when it is time to ease in
that colour.
This is hitting a lot of plurals, causing the CI builds to fail. But
unfortunately, its getting it wrong. Its actually for a format in a string
like "Updated today" in languages like pt that need special cases for 0/1
items. In this case, it makes no sense to say "Updated 0 days ago".
Although the adapter tries to keep in sync with the app status update
manager, there may be times when this is not successful. In such
circumstances, it seems safe to just guard against invalid situations,
rather than trying to assert an error or fall over.
Fixes#922.
There was some confusion in the user tests about how to launch an app
once it was installed. Hopefully this small change goes towards fixing
some of that confusion. Instead of just showing "X installed
successfully" in the app list, it now shows a "Run" button next to it.
When navigating to Updates -> Show Apps and then downloading an item, it
shows the download progress inline for that item. After this is
complete, it then shows a tick icon next to the item. The long term goal
should be to remove the list item from under "Show Apps" so that it is
only shown at the top of the "Updates" view. However this will require
more work. In the meantime, we can alleviate some confusion by replacing
the "Tick" icon with a button that says "Update" (like the other buttons
in the Update view).
When dismissing an "X installed successfully" intent, it should also
dismiss the relevant item from the "Updates" screen. This was not
happening. Upon investigation, I noticed that when I dismissed a
notification, it was passing through the Apk which I installed over a
day ago. This is because it was reusing a previous pending intent rather
than creating a new one.
Now that we've moved the first screen to "Latest", we always want to do
our best to show something there. This preference is pretty redundant in
light of this.
Previously, the definition of "New" was whether or not the added and
last updated dates were the same. This made sense, because we only
showed apps from the past few weeks (depending on preferences) as new.
Now that we show up to 200 apps in the first screen, regardless of age,
this check is no longer helpful.
It seems pointless to only restrict "Latest" to items within the last X
days. When you only have the GP repo enabled, or other repos with less
apps that are updated less frequently than the main repo, this screen
always ends up empty. This change shows the last 200 updated items
instead of those updated in the last X days.
The text is more comprehensive on the main screen than on categories,
because this is the view that all users will see when they first open
F-Droid.
Fixes#879.
Previously this was only shown in the notifications.
This does not show the full progress of the update, but at least it
provides a rudimentary level of feedback. In the future it can be
modified to show more substantial feedback if required.
This results in a slightly larger apk (e.g. 500KiB), but it reduces the
scope for bugs greatly. We still get all the benefits of only having to
maintain a single density-independent vector (rather than several
density dependent PNGs and all the work that involves).
The class of bugs that it solves is that there are several places where
vectors cannot be used, and you wont notice when developing on a device
newer than 5.0. For example, notification icons, `TextView`
and its `android:drawableStart` attribute.
Fixes#913.
It was assuming there is always a priv ext preference. However, we
remove the priv ext preference the first time the fragment is opened. In
these circumstances, the preference no longer exists, resulting in a
NPE.
Unused for now, but like with the `LoggingQuery`, it is helpful to
be used for debugging purposes. For example, used this to quickly
figure out that it took 7 seconds to fix the PRNG stuff in FDroidApp
onCreate().
The CardView extends FrameLayout. This layout has some problems with
margins: http://stackoverflow.com/questions/5401952/framelayout-margin-not-working.
These can be overcome in most situations by swithcing from a margin to
some padding on the child view. The reason it is okay to do this in
most cases is because the child view is usually a layout such as a
ConstraintLayout anyway. For such cases, the difference between margin
and padding is not much different, because there are usually not any
background colours or borders applied (where padding vs margin would
usually make a difference).
Previously it would show a grid patter for the first five items, and
then resort to list items. This continues the grid pattern indefinetly.
Fixes#866.
Left some more unused strings which are a bit more general purpose and
perhaps should wait until after a stable release to remove. The
rationale for this is that we may want to revert to part of the old
terminology in certain places, and don't want to have to ask everyone to
translate everything again.
These are loaded dynamically at runtime based on a sanitized version
of the category names. Thus, the static lint tool cannot pick up that
they are indeed used.
We no longer prefix the list of categories with "Whats New", "Recently
Updated", and "All". The new UI doesn't require this. The only place
they were being used now were in the tests.
This was implemented before because the main screen of the three tab
layout needed to update in response to the list of installed apps being
installed. When we scan the list of installed apps upon starting
F-Droid, we didn't want to have to requery for the list of installed
apps every time we found a new installed app. For this reason, we
"debounced" these requests (accumulated them for 1 second, and then let
go of a notification only after 1 second of inactivity).
This is no longer a feature, and so we can afford to fire the
notification instantly.
We were jumping the gun before, and asking to refresh the app details
adapter before the installed app service was able to notify us of a
change to the apps installed version.
This should be refactored to use broadcast receivers instead of
content observers (which are tied to the implementation of a content
provider). However this is currently a straight port from app details 1
to app details 2.
On newer devices, it takes the icon, removes colour, and uses that. This
looks weird because:
* The head and body look too close together once you remove the shading
from the launcher icon.
* The eyes dissapear because they are white (not transparent) in the
launcher icon.
Prior to this, it would still show the "Ready to update" list item.
Now it updatpes the description to say "successfully installed" and
removes the "Update" button.
If you open AppDetails, initiate a download + install, and then navigate
away, it still pops open the install dialog for you. This is because it
never deregisters the broadcast receiver.
This change maintains the behaviour of always having the broadcast
receiver. This is because it is only added when the download
completes, and would require further refactoring to change that.
Instead, we listen for the receiver, but we ask if the AppDetails view
for the apk in question is actually visible to the user. If not, we
don't try to initiate the package manager.
Previously it showed the number of things which were eligible for
update. This will become less and less important the more people we can
switch over to automatic updates. However, given the privext vs unknown
sources thing, we will always have a lot of users who need to be
notified that they need to take further action to complete an install.
Prior to this, they were in whatever order they came from the metadata.
This resulted in weidrness because the repo which was updated last will
have its apps shown last. We are trying to move away from the repo
update order being important.
In the future, this sort order should take into account better
heuristics, but for now this is at least deterministic.
The database still treats repos with a _low_ number as _low_ priority.
This means it sounds weird when you say "Repo with priority 1 is the
least important", but other than that, everything works as expected now.
Technically we could recreate the query to update the repo metadata
within DBHelper, but that is difficult because it is sort of build into
the content providers. Unfortunately, we are unable to access content
providers from the DBHelper.
In the future if we are able to migrate away from content providers to a
more dumb data access layer, then we could reuse the query to update the
metadata priorities in the DBHelper. However that is a tomorrow problem.
To limit the possible oddness of having the installer package being
something different than F-Droid, only set it to priv ext on android-24
and newer, since its required there.
There is still quite a bit to figure out in the data format of the
per-package "What's New" entries, and its breaking the tests, so move
the placeholder code to the one spot where the placeholder whatsNew
entry is used.
App.getAllScreenshots() works nicely here, but its probably a temporary
measure until we figure out how to handle the various kinds of
screenshots (TV, Wear, etc).
This is based on @pserwlyo's work. The App and Apk classes currently
need just the public instance variables auto-filled by Jackson, so
everything else is considered opt-in, via @JsonProperty declarations.
This is currently only used for setLocalized(), setUsesPermission(),
and setUsesPermissionSdk23().
# Conflicts:
# app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java
The parser should accept additional elements to each
uses-permission entry, in case more XML attributes is added to
<uses-permission>. <uses-permission> has had two attributes
since the beginning.
Other changes to this JSON data structure are bad index-v1
format, and will cause crashes:
* Removing an element e.g. null from a uses-permission entry
would be invalid index-v1 JSON, since that structure mirrors
the uses-permission AndroidManifest.xml element, which has a
long standing fixed definition of name/maxSdkVersion. That
should crash so that fdroidserver authors know they are
generating invalid index-v1.
* setting versionCode to anything but an int is invalid index-v1
JSON, and should crash. versionCode has been defined as an
32-bit signed integer value since the beginning of Android.
* <uses-permission android:name=""> has been defined as a string
since the beginning of Android.
https://developer.android.com/guide/topics/manifest/uses-permission-element.html
repoId is used in Repo, App, and Apk instances to point to the Repo data
in the database. It does not come from the index files, but rather the
client database.
An important security protection is erroring when the index-v1.jar is
older than what is currently in the database. If the current or older
jar is allowed to be parsed, then a malicious server or
Man-In-The-Middle could replay old version of the index-v1.jar to
prevent the clients from learning about updates that fix security issues
The image loading code for the app cards was presuming that the icon
returned did indeed exist. In this case, it crashed due to trying to
decode a `null` image.
I noticed that when returning to the settings fragment (e.g. by closing
then reopening F-Droid while viewing), it will attempt to re-remove the
priviledged preference. This causes a crash, so we check to see that we
still have the preference before deciding to remove it.
index-v1 does not send empty values. The description was historically
set to "No description available" on the server side, and in
index.xml. The database then inherited this behavior, and does not
support no description. In the long run, it would be good to sync up
the database with the index-v1 metadata, but perhasp then we'd have to
add a million null guards, which wouldn't be worth it.
Tell the Jackson JSON parser to ignore App/Apk fields that should never
come from the index, but instead are set locally to keep track of the
current state of things on the device.
There are two forms of tests to enforce that the proper things get
ignored. It is not possible to do this with decorators alone, so I
chose to use @JsonIgnore and leave the variables we want filled in
undecorated. Also, all of the instance variables in Apk/App/Repo
should come directly from the index metadata so that they are pure
data classes. Currently some state info is stored in them, those are
decorated with @JsonIgnore.
The tests then include lists of accepted and ignored properties, and
anything that is not in those lists will cause the tests to fail. So
if someone is adding a new instance variable, they will get a fail
until the tests are updated. One set of tests actually writes blank
instances out as JSON since that's the easiest test to write, and
Jackson treats @JsonIgnore the same in both directions. Then there is
another test that reads a JSON file with added, unsupported values to
make sure that they are properly ignored.
Having Jackson set to ignore unknown fields in the incoming JSON data,
instead of throwing an Exception, means that we can add any fields to the
JSON without having to rev the index version, and older clients will still
parse it fine. This is basically the same as in index.xml.
This sets the App instance variables using the localized index-v1 fields.
It trys to fill as many fields as possible, falling back to locales of the
same language, then finally English.
This is based on the Jackson JSON parser's ability to map a JSON key to a
method, e.g. @JsonProperty("localized")
This adds support for parsing the new index-v1.json data as defined in
fdroidserver!221. This new index metadata format is required to
support localization, graphics, screenshots, etc.
refs #15
This adds support for the index fields: uses-permission and
uses-permission-sdk-23. For most index fields, Jackson handles directly
mapping the incoming data to the instance vars based on the matching
field/var names. For uses-permission*, methods are declared for
handling those properties in the incoming index.
These fields will be ignored when using the v0 index.xml format.
* Move the privileged extension installed check above
the check whether the apk to be installed is privext.
* This lets privext updates work when it is already installed.
* The new PackageInstaller APIs, being used by the privext on Android
7.0 and above aren't happy with uninstall being done by an app
other than the original installer.
* Set it to the privileged extension if that is enabled and being used,
to make uninstalling work
This notification is kind of weird, because the only ways it can be
dismissed is by:
* Swiping a notification away from the notification drawer.
* Closing and reopening F-Droid.
However I think the UX is still pretty nice:
* Tells the user that it worked.
* Allows them to navigate to it if desired.
In a future MR I will remove this class completely, but this just
ensures that touching a notification will not send the user to the old
AppDetails (instead sending them to AppDetails2).
Default padding specified is 12dp which is not very generous.
This reduces it to 2dp for seemingly good effect. Yet to see what it
looks like with longer translations of other languages, but time will
tell.
Move logic which parses intent and forceably sets the text of our search
input to onCreate(), not onResume(). onCreate() is invoked each time a
new intent is sent to open up this activity. That is, each time a new
category is opened or a new search request is received. onResume() is
called much more often than this, including when the user is directed to
a new activity and then returns to the search screen after hitting back.
In this case we don't want to remove the search query the user had and
replace it with the data in the original intent.
The previous language hinted at the fact we auto download and install
updates like Google Play. This is not the case (unless you have
priv-ext). To clarify, now we "Automatically _fetch_ updates", ready to
install when the user initiates the install.
Fixes#839.
Locale.getDefault() returns the default for the current JVM (or whatever
runtime Android calls it these days). By asking the configuration, we
will get the Locale that the user has selected from within the F-Droid
preferences.
Replicant is committed to follow the GNU Free System Distribution
Guidelines (FSDG)[1]. Apps with certain anti-feature flags in F-Droid
violate these guidelines and thus shouldn't be available in the
F-Droid client on Replicant[2].
Issue #564 discusses this, although only the case of having apps with
anti-features optionally filtered. To be compliant with the FSDG
guidelines, all violating apps must not be accessible and there
shouldn't be a setting to make them visible. Not all anti-features in
F-Droid violate the FSDG guidelines, so no need to filter all of them.
Signed-off-by: Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de>
[1] https://www.gnu.org/distros/free-system-distribution-guidelines.html
[2] https://redmine.replicant.us/issues/1629
The default behaviour of gradle when encountering a transitive
dependency which is the same as an explicit dependency, but where the
transitive dependency has a higher version, is to bump the depdendency
which was explicitly added. This meant that the addition of the
bottom navigation library implicitly bumped our support lib to 25.3.0
due to its dependence on it.
The options are:
* Change the 3rd party lib to support 25.2.0 instead of 25.3.0.
* Explicitly exclude the transitive support lib dependency in our build
script (what we have done in the past, e.g. with acra).
* Bump our explicit dependency.
Given the nature of the changes from 25.2.0 and 25.3.0, it seemed like
it was simplest to bump our dep. However, there is a bug
https://code.google.com/p/android/issues/detail?id=251302 which causes
a function we depend on in SwitchCompat to require API 14. Therefore,
this change excludes the 25.3.0 transitive dependencies, allowing our
25.2.0 dep to get used.
In the process, I've noted that there were a few places we opted for
excluding the transitive dependency in the past. These have now been
removed because we have a higher version than they do, and thus they
will no longer drag our old version forward.
The previous dependency extended the support library bottom nav. It did
this at the expense of lots of reflection. This is pretty brittle and
likely to break in future releases as the support lib gets updated. In
the mean time we need to have a fully working bottom nav, so this commit
includes a different dependency.
Most 3rd party bottom navigation panes look great. All that I found
require at least API 11, mostly API 14 (due to animations I suspect).
I've forked one of the most popular ones on GitHub and made it support
back down to API 10. My fork is added as a dependency until upstream
accepts the PR.
If they don't ever, then we can reconsider what our options are.
The two times I've swapped the bottom nav implementation have both been
trivial. The code generally only touches the MainActivity and its
layout.
Shows a red badge over the "Updates" menu item.
The updates badge is a bit hacky. There are indeed libraries which
implement a bottom nav which have support for badges built into
them. However they target API 14. There are also other badge
libraries which just deal with rendering, but for the cost of
another dependency, it is not particularly difficult to create a
`TextView` with a background and position it ourselves.
Right now, it will allow us to set the selected item more nicely.
In the near future, we will use this dependency to control the visual
display of the bottom nav better (e.g. icons/text appearance/animation).
Note that there is a bit of development going on at the Android team,
and the official bottom navigation view may oneday support all of these
features. In that case, we should probably switch back.
* Show selectable background behind "Show/Hide apps" button.
* Scroll to the relevant place in the list when showing/hiding apps.
* Only show one line (ellipsized) of the apps to update in header.
This will read downloaded .apk files from the disk cache in the background.
For each apk that corresponds to an app which can be updated, the status
manager is notified.
Even though it doesn't matter here because it is going from one side of
the parent all the way to the other. I hope it makes it easier if we
completely avoid right/left and only ever use start/end. Then searching
for RTL problems will be easier.
Alows for more flexibility in what we are able to display, including:
* Prompting users to donate to frequently updated apps
* Showing messages from package maintainers to users
* Marking apps for later installation when offline
Most of these are not yet implemented, but will be able to when
required, whereas they were not able to in the previous UI.
There were a few different options around, but some of the best ones
which provided the most flexibility when adding diverse/complex
viewTypes to a recycler view target a minsdk above 10.
The "adapterdelegates" library still offers a big improvement on vanila
adapters, especially for the Updates view.
This is in response to identifying a bug with the way priorities work
with categories. Two repos may both specify different categories for
the same package. In this case, F-Droid should only select the
categories from the highest priority repo. Well, it is not to say that
this is the most preferable option, but it is consistent with other ways
that repo priorities are used.
Doing this required tweaking our `IconDownloader` which we give to the
UIL init method in FDroidApp. It only knew how to load from HTTP, but we
needed it to fetch `drawable://` images too (which the library
supports). In addition, it has been renamed `ImageDownloader` as it also
is now used for screenshots/feature images.
This is currently needed for screenshot placeholders, but might be
useful in the future as well. Note that the default BaseImageDownloaded
supports this, as well as content:// and drawable:// protocols.
This was not updating the versions expand icon correctly when the user
clicked on it. It was working when they scrolled away and returned to
the versions list. Now it works for both.
Although these didn't used to fail at all, they now _always_ fail due to
the Docker setup we run on GitLab. Until we get that fixed, the CI is
not very helpful if it fails every time, and we merge anyway. This
allows us to at least correctly use the "Merge when succeeds" behaviour.
Fixes#882.
Couldn't figure out the exact cause of going from Inkscape .svg to
Android VectorDrawable, so redrew it in inkscape and this time it works.
*shrug*.
This is as per the mockup in issue #840, and does the following:
* Adds a new `PreferencesCategory` of "My Apps" at the top of the
preferences screen.
* Adds a "Manage Installed Apps" preference, and moves the
"Repositories" preference into this category.
* Repeals an existing change which prevented "updateable" apps from
appearing in the list of "installed" apps. This is because the two
lists of apps are no longer displayed alongside eachother.
* Enhances the `AppListItemController` to also be able to display
whether or not the currently installed version is the recommended
version or not.
* Also adds option to display whether the user has asked to ignore any
updates for any specific apps.
Moved intent-filter from FDroid to MainActivity. Can test from the
command line with:
```
adb shell am start -a android.nfc.action.NDEF_DISCOVERED \
-d fdroidrepo://10.0.1.10:8888/fdroid/repo
```
Show an install button after the download is complete so the user can
click it to initiate an install. This is in preference to popping up
install manager activities on their behalf, because they may have queued
up several apps to update.
Things that are still not right:
* BottomNavigationView doesn't read out the title of items when selected.
Created this issue: https://code.google.com/p/android/issues/detail?id=230595&thanks=230595&ts=1482125499
* TTS reader combines the app name and summary without a pause which is jarring.
* Touching the background of the recycler view in the categories view reads all category names.
* Likely other problems too.
No longer bind the views as they become visible. This resulted in
the same view being bound multiple times, but that was unneccesary.
Given that there is only five types of view, and each view type only
ever gets used once, the binding can happen when the view holder is
created, rather than each time it is shown. This fixed a few bugs to
do with views being inflated multiple times.
Shows progress and download complete now, but left a few TODOs
lying around. These are mainly around the ability to then deal with
installing an app once download is complete.
The styles used by the app details showed good padding on either
side of the buttons text. This was because they had a certain amount
of screen space to fill up which resulted in nice empty space on either
side of the text. Other buttons do not have this type of layout, so
need to have a minimum amount of padding thrust upon them.
Required breaking out into values-v17 too, so refactored common styles
into base style to make this easier.
As per the main screens feature image behind the "Recently added"
items, also use the same abstract artwork as a placeholder for the
feature image in app details.
Draws two rows of triangles, each coloured randomly according to
the dominant colour in the apps icon.
Given that the colour is probably assigned to the FeatureImage in response to
a network request finally downloading an image, there is a period of no feature
image. After the colour is provided, then if it is set instantly it tends to
look jerky. This eases in the colouring of the feature image.
Happy to discuss whether this is a good idea or not, but right now
there is no way to update repositories so often you are left with
an empty first screen.
This doesn't worry about state management (e.g. remembering
whether we are refreshing or not and showing this when we resume the
activity). Instead, it listens for the refresh listener, and when
triggered it will set the refreshing state to not refreshing. For now
the notification can act as the feedback that something is happening.
This is a little bit flakey at this point, because the weird asynchronous nature of
adding fragments. If swiping to the second-to-last entry on the bottom navigation view,
it will populate the settings fragment in the UI and then it will dissapear. Need to
fix this.
Show a "Chip" in the search box whcih indicates the user is viewing
a particular category. This chip:
* Gets remtoved when the user presses backspace from in front of it.
* Can be re-added by typing the name of a category and then a colon.
* Follows the material design guidelines.
* Has an accessibility hint that tells screen readers it is a category name.
This is different to the old categories drop down, because that also
included meta-categories of "Whats New" and "Recently Updated". Given
we now show them on the first page, this categories screen can do away
with them.
Each category entry loads a few apps to show to the user.
Note: The "View all" button next to each category doesn't currently
go anywhere. It will soon be hooked up to an app list that is filtered
to the selected category.
Not fully featured yet, because it doesn't listen for broadcasts
from the installers, but it is shows the correct list of apps and
allows users to queue up downloads of all updateable apps.
Smooshes the recently updated and recently added lists into one,
and adds a status line under each app saying which of the two it
is (i.e. "Recnelty Updated" or "Whats New".
It doesn't load up the entire swap activity at this point. Instead it
is an entry point to direct the user to that activity.
Also added stubs for the remaining screens which need to be implemented
to the MainAdapter and MainController.
The fragment was quite straightforward to roll into the activity. Most
of the code moved across almost exactly as is.
Also added a theme for the toolbar so that in the future it will be
easier to support dark/night themes as well.
The following official Android support libraries were added:
* recyclerview-v7
* cardview-v7
* design
* support-vector-drawable
* constraint-layout
* palette
Also, add code to AppDetails2 to match AppDetails, keeping track of
currently viewed app. Moved the nulling of this info to onStop instead
of onPause, since alerts may be shown on top of the details page, while
still visible.
The `setApkInternal` method had to infer the intent of the caller
based on the arguments which were passed on, and then do specific
things depending on the input. Instead, this change has three
distinct actions which can happen (add/remove/update). Each of
these methods does only one thing, and doesn't have to guess
the intent of the caller. The only exception may be "add", which
will (for convenience) delegate to "update" if it already knows
about the apk in question.
The only time `status == null` was when coming from `removeApk()`. By
moving the logic out of `setApkInternal()` into `removeApk()` it makes
it easier to reason about `setApkInternal()` as it now does less. Also,
it was doubling up on the `syncrhonized (appMapping)` and `if (entry !=
null)` logic which is no longer required, because `removeApk()` was
already doing that.
While here, also make explicit the fact that `status` can no longer be
`null`.
Because of the way that this can be misused without the compiler knowing
(e.g. by forgetting to call `endBatchUpdates()`) it may be safer to move
it to an internal implementation detail of the class.
It could probably be done away with completely if the `notify*` methods
were moved out of the respective `*ApkInternal()` methods, but that
requires more significant refactoring to get right without code
duplication.
It seems that `setContentIntent()` will do fine if we pass it a null
argument. The default value is `null` anyway, and it doesn't mandate
a non-null argument.
Given that none of the callers need the functionality of the builder,
lets make it explicit that we don't expect the builder to be further
customized once it is returned. Instead, return a notification to hint
that no further customization is required/desired.
Given that some places where this method is invoked does a null check,
it seems reasonable to make this assumption explicit. That way if devs
use the method in the future, then they will be aware of the contract.
Neither pmd/checkstyle/many-devs are particularly precious about
hard rules of when to wrap a line. In this case we could've brought the
`ErrorDialogActivity` onto the same line as `putExtra`, but instead
opted to chain the method calls as per the `getAppDetailsIntent` method.
Whether a category is "available" or not is not a function of whether it
is in the category table or not. Rather, it is a function of whether there
are any active apps/apks which are in that category. Thus, don't notify
after inserting a category (the notification was wrong anyway as it was
trying to notify the AppProvider Uri instead of the ContentProvider one).
Instead, do it after a repo update is complete.
This adds support for the index fields: icon, mirrors, and antiFeatures.
icon and mirrors are for Repo, they've been around a while on the server
side, but just never used on the client side.
For Apk, this adds a new per-APK antiFeatures field so that each APK can
be individually marked. For example, when tracking is added or removed,
vulnerabilities are discovered and fixed, etc.
These fields will be ignored when using the v0 index.xml format, they
will be used by the upcoming index-v1 format: !422
In the v0 index format, empty descriptions were filled in with boilerplate
text. The v1 index format instead leaves empty descriptions empty, and
lets the various consumers (fdroidclient, web interfaces, etc) decide what
to show. The database and code still assume that the description will not
be null, so instead this ensures there is something in the database, but it
will be an empty string instead of a null. In the future, it would
probably make sense to standardize empty values on null or something.
This makes the name of the instance variables in the App class match the
names of the metadata fields in the new fdroidserver .yml YAML format. This
means that the Jackson parser can automatically instantiate instances for
us, which will be more efficient and maintainable.
These names aren't great, but it would a ton of work to rename the field
names in all of the metadata files, the docs, fdroidserver code, etc.
RequiresRoot is obsolete as a metadata field since there is the SUPER_USER
permission. This `requirements` array was set up to handle other things,
but that was never implemented.
APKs installed in /system} will often have zeroed out timestamps, like
2008-01-01 (ziptime) or 2009-01-01. So instead anything older than 2010
every time since we have no way to know whether an APK wasn't changed as
part of an OTA update. An OTA update could change the APK without changing
the versionCode or lastUpdateTime.
closes#819
gitlab-ci used to run all of our jobs in parallel, now it mostly seems
to run them sequentially. So splitting up the various parts of the CI
suite into separate jobs mostly slows things down. This combines the
static tests into one job (lint, pmd, checkstyle, tools) with the JVM
tests aka Robolectric. That makes three jobs from the previous six.
[ant:checkstyle] [ERROR]
/export/share/code/fdroid/client/app/src/main/java/com/geecko/QuickLyric/view/AppCompatListPreference.java:35:29:
Name 'mDialog' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9]*$'. [MemberName]
Introduced in 79ecffc91c8856e7ceb6a65441d19a6272195426
Also ensure it shows this animation correctly when expanding "Versions".
This is done by changing from `notifyDataSetChanged()` to the more
specific `notifyItemRange(Inserted|Removed)`, which ensures the
"Versions" item doesn't get rebuilt midway through an animation.
Fixes#817.
As discussed in #817, this preference is not useful on Android >= 5.0.
As such, the preference should just be removed. However, it should stay
if the privileged installer is already installed (e.g. via update.zip or
included as part of the ROM).
Translators:
Ahmad Zafrullah Indonesian
Allan Nordhøy Norwegian Bokmål
Balázs Úr Hungarian
Hasan İlingi Kurdish
Jonatan Nyberg Swedish
Juraj Harasta Czech
Michalis Greek
Michalis Spanish
Nick Bishop Greek
Verdulo Esperanto
yiannakis Greek
Fixes Issue #750.
This new class makes sure to use the correct `AlertDialog.Builder` from
the support lib. This in turn ensures the correct styles get applied to
the result alert dialog.
Doesn't change anything, just removes a deprecation warning.
AppCompatActivity currently extends ActionBarActivity and doesn't
provide any further imnplementation.
Translators:
Adrià García-Alzórriz Catalan
Ajeje Brazorf Sardinian
Alaa Issa Arabic
Alberto Moshpirit Spanish
Alexander Georgievskiy Russian
András Lengyel-Nagy Hungarian
André Marcelo Alvarenga Portuguese (Brazil)
Anteri Finnish
Athmane MOKRAOUI Arabic
Claus Rüdinger German
Cyxae Dexyc French
dark159123 Danish
Dmitriy Bogdanov Russian
Enol P Asturian
ezjerry liao Chinese (Traditional)
Gregor Santner German
Hsiu-Ming Chang Chinese (Traditional)
Jean-Baptiste French
John Doe Turkish
Jonatan Nyberg Swedish
Kheireddine Mkh Arabic
Lari Oesch Finnish
Luca Bianchi Italian
Marcelo Santana Portuguese (Brazil)
Marian Hanzel Slovak
Michael German
Mladen Pejaković Serbian
msrn Finnish
naofum Japanese
Olexandr Nesterenko Ukrainian
Osoitz Basque
Raphaël Barman French
Sveinn í Felli Icelandic
Sylvia van Os Dutch
Tobias Bannert German
Verdulo Esperanto
Verdulo Polish
Yaron Shahrabani Hebrew
zmni Indonesian
Also tried a more specific naming scheme for dimens to make it clearer where
they are to be used. This increased the padding on the left/right of the collapsable
lists. It also decreased the padding above/below.
Still needs some better assets for the actual donate buttons, but now it includes
the relevant text about donating to developers. It also puts the donation options
in a grid layout and lets them flow across so that if there is more than three, they
will end up on the second line.
Correct meeting time
With the discussion on IRC [starting here](https://botbot.me/freenode/fdroid-dev/2016-11-14/?msg=76442333&page=1), the time in `README.md` is wrong.
> We are on `#fdroid` and `#fdroid-dev` on Freenode. We hold weekly dev meetings on `#fdroid-dev` on Tuesdays at 20h UTC, which usually last half an hour.
[It should be](https://botbot.me/freenode/fdroid-dev/2016-11-15/?msg=76516527&page=1) be:
> We are on `#fdroid` and `#fdroid-dev` on Freenode. We hold weekly dev meetings on `#fdroid-dev` on Thursdays at 8:30h UTC, which usually last half an hour.
See merge request !424
Required changing some local variable names to prevent the same
`view` variable being declared multiple times. Otherwise it should
be a verbatim change from if statements to switch statements.
Required a couple of undesirable changes, such as:
* sCollated -> collated
* mFDroidApp -> fdroidApp (note the lower case 'd')
Otherwise it was relatively minor given how many member variables there are
in the code base.
Allows the two menu items "Ignore All Updates" and "Ignore This Update"
to be checked and save the relevant preferences to the database in response.
The old code waited until the activity was paused before saving the
preferences to the database. This code does not, and as such incurs
a database write on the main UI thread as soon as the user checks the
menu items. However that database code has recently been refactored so
it should be much more performant. If it turns out to still be problematic
then we can revert to the old behaviour of hodling onto any state changes until
onPause then persisting to the database.
Allows the type checking to be done by the compiler rather than the developer.
It was possible here because there is only two types of view, and the first type
will only have one or zero entries in the adapter. Thus, I've swapped the usage
of a `String` type for a `null` and checked for null instead of `instanceof String`.
Changed the helpful comments to a Javadoc comment, as tooling such as editors
will be more likely to make use of it like that.
Renamed to emphasise that only trailing new lines are stripped.
Added a basic test for this function to ensure it only strips trailing,
and also that it does actually strip trailing slashes.
Although the `textView` in `DonateViewHolder is currently not used, it was
pointing to an id which was not in the layout. This has been fixed in case
future devs choose to use this text view. Alternatively, we could remove it
completely if we don't think it is going to be used in this upcoming UI work.
Similar to the litecoin/bitcoin/flattr stuff, we need to check that a
proper URI can be handled via an intent. This previously just checked
whether the email address could be handled without the mailto: prefix.
Doesn't do anything except create an app with no versions,
no donate links, anything like that, and ensure that the adapter
is able to create the view holders for each resulting item.
In the future we can beef this up to check more exotic conditions,
such as calling `updateItems(App)` with different apps, each
with different combinations of versions, donation links, permissions,
etc.
This extracts the functionality from the old AppDetails which prefixes
donation links with the relevant scheme (bitcoin: or litecoin:) or URL
(https://flattr.com/thing/) into the App class.
The adapter has a hard coded assumption that mApp is never null.
This documents it as such by making the member variable @NonNull.
This is not perfect, because the consumer of this class doesn't quite
seem to check this constraing properly, however at least within the
class it adds some explicit documentation that is understood by editors
and lint that this is a non-nullable field.
Each call site of the `getHeaderView()` method needed to do a null
check and then it would call `setProgress()`. This has been replaced
with two methods `setProgress()` and `clearProgress()` to make it a
bit less repetative and harder to accidentally get a NPE in the future
by invoking `getHeaderView()` incorrectly.
Translators:
Ajeje Brazorf Sardinian
Alberto Moshpirit Spanish
Andreas Nordal Norwegian Bokmål
Clara Chido Shona
Enol P Asturian
E T Turkish
ezjerry liao Chinese (Traditional)
Licaon Kter Romanian
naofum Japanese
Nebojsa Tausanov Macedonian
Nutchanon Wetchasit Thai
Osoitz Basque
Sylvia van Os Dutch
Tawanda Mugari Shona
Verdulo Esperanto
Verdulo Polish
Yaron Shahrabani Hebrew
YFdyh000 Chinese (Simplified)
zmni Indonesian
Ensure categories are not shown unless there are apps in them
**Note: To be hot fixed into 0.102.1 also when merged.**
Fixes#806. Also adds tests to hopefully prevent this from regressing in the future.
Ensure app-category join table is cleared out properly upon disabling repo.
There are certain things we can leave in the database even when they are not being used. The criteria for this is:
* Could it be used again in the future?
* Can it be excluded from queries easily while it is unused?
Examples are entries in the package table, and entries in the category table.
This fixes a problem where entries in the category-app join table stayed in the database, causing categories to be considered as "in use" when really there were no apps in those categories. These rows need to be removed, because when new apps are added again in the future, they will have different primary keys. These different primary keys mean that the rows in the category-app table will never be useful again, and thus should be removed.
See merge request !418
Unfortunately, something in the way that the docker image is created is
making it impossible to run `android update sdk`. Even though it runs as
root, it cannot upgrade things, and in the process, it seems to break the
Android SDK bits that are there.
Installing Android Support Repository, revision 40
Failed to rename directory /android-sdk/extras/android/m2repository to /android-sdk/temp/ExtraPackage.old01.
Failed to create directory /android-sdk/extras/android/m2repository
Done. Nothing was installed.
A problem occurred configuring project ':app'.
> Failed to notify project evaluation listener.
> You have not accepted the license agreements of the following SDK components:
[Android Support Repository].
Before building your project, you need to accept the license agreements and complete the installation of the missing components using the Android Studio SDK Manager.
Alternatively, to learn how to transfer the license agreements from one workstation to another, go to http://d.android.com/r/studio-ui/export-licenses.html
> Could not resolve all dependencies for configuration ':app:compile'.
> Could not find com.android.support:support-v4:24.2.1.
Required by:
project :app
> Could not find com.android.support:appcompat-v7:24.2.1.
Required by:
project :app
> Could not find com.android.support:support-annotations:24.2.1.
Required by:
project :app
There are certain things we can leave in the database even when they
are not being used. The criteria for this is:
* Could it be used again in the future?
* Can it be excluded from queries easily while it is unused?
Examples are entries in the package table, and entries in the category table.
This fixes a problem where entries in the category-app join table stayed in
the database, causing categories to be considered as "in use" when really there
were no apps in those categories. These rows need to be removed, because when
new apps are added again in the future, they will have different primary keys.
These different primary keys mean that the rows in the category-app table will
never be useful again, and thus should be removed.
Fixes#806.
Fixed long version overriding app name (issue #322)
Also, fixed deprecated "singleLine" property to "maxLines="1"".
Also removed reduntant (legacy) padding declarations, for the files used exclusively by newer APIs which override those declarations with new ones.
See merge request !417
Rework net for 0.102
This is a collection of targeted fixes for the %"0.102" release. Most of them are quite narrowly targeted bug fixes. I couldn't avoid reworking the update scheduling in order to fix some of the listed bugs. This is the only part that seems possible to have regressions. In any case, if there are regressions, they will be in a very limited chunk of the code, in `UpdateService`, which we have no plans to touch in %"0.103 - UX Overhaul" so it'll be easy to do a 0.102.1 release.
See merge request !415
Also, fixed deprecated "singleLine" property to "maxLines="1"".
Also removed reduntant (legacy) padding declarations, for the files
used exclusively by newer APIs which override those declarations with new ones.
This introduces three network states:
1. completely disconnected
2. connected only via metered networks
3. connected via unlimited networks
This allows the update process to use bandwidth better, especially when the
user has enabled the "Only on WiFi" setting. It also helps prevent silly,
cryptic error messages in the update process is triggered when there isn't
internet available.
I tested this with:
* 4G only, but not set up for internet
* 4G only, with internet
* 4G + WiFi
* WiFi only airplane mode
* no internet at all, full airplane mode
closes#793closes#774
Its really easy to use USB Ethernet devices with ChromeOS and some Android
devices like Android TV. ChromeOS now supports Android apps. Since really
the goal is to avoid metered networks, and ethernet is very rarely metered,
this fits in with the user expectations around the preference. And if it
doesn't, there are very few people using Ethernet with F-Droid right now,
so whatever harm does happen will affect an extremely limited number of
people.
First, this is more honest than just using the default since it is saying
what the actual software is. Second, it protects identity, since the
default User Agent on Android can have a lot of info in it, for example:
"Dalvik/2.1.0 (Linux; U; Android 5.1; XT1039 Build/LPBS23.13-17.3-1)"
The real solution would involve figuring out where to handle this in the
right spot in the lifecycle. Since AppDetails is being totally replaced,
this is just to stop the crashing.
closes#802
InstalledAppProviderService tries to keep a running log of what is actually
installed on the device. It seems that ApplicationInfo.sourceDir and
related things sometimes returns a dir rather than an APK. So try to find
an APK in that folder.
closes#801
Store categories in separate category table
Currently, the category that an app is in is recorded in the database via the `fdroid_app.categories` column, containing a comma separated list of strings. This makes it hard to query. The existing code to get a list of categories was pretty bad as a result.
This moves to a different data model whereby categories are stored in a separate table. Each repo is free to specify that an app is in arbitray caregories (as with before). This is represented by a join table between categories and app metadata.
The end result is that categories are much more a first class citizen than before, and they will be able to be queried easier - which is important for the new UI.
Note that the categories table need never be emptied, it can keep being appended to. The reason is that if there are no apps in a particular category (represented by no corresponding rows in the join table) then the category will not be shown to the user.
See merge request !409
Improve performance when changing "Unstable Updates" preference
This is only a partial solution to #520.
It does as I suggested in the issue comments, by doing less work when the preference is checked. The proper solution is an `IntentService` which queues requests to update these details, but that is a (slightly) larger change for the future.
I also noticed it wasn't correctly notifying the UI of the change, so this now notifies the list of apps which can be updated. That was hard to test though, so not sure if it updates the UI correctly or not. It shouldn't do it _incorrectly_, but it may not work. The reason it should work is because the `AppListFragment` (baseclass of `CanUpdateAppsFragment`) uses a cursor loader with the `AppProvider.getCanUpdateUri()` URI. This `CursorLoader` should automatically attach an observer for that URI and requery if required.
See merge request !414
Fall back to InstalledAppProvider when trying to identify the apk to uninstall.
Extracted `getInstalledApk()` method so that it could be better documented, and
makes the `uninstallApk()` more consise. It will now throw an `IllegalStateException`
if no apk is found, because as issue #800 shows we will end up with a NPE otherwise.
Fixes issue #800.
See merge request !413
Extracted `getInstalledApk()` method so that it could be better documented, and
makes the `uninstallApk()` more consise. It will now throw an `IllegalStateException`
if no apk is found, because as issue #800 shows we will end up with a NPE otherwise.
Fixes issue #800.
During development of a new feature, I noticed a bug occuring only after using
the new feature for several days. This was because the metadata only infrequently
changes in ways which cause certain code paths to be hit. By having the f-droid.org
metadata from several days apart in the test suite, it allows for testing more
of these cases. In the future, even later versions of the metadata can be added
to ensure that we can update happily from old to new metadata.
This ensures that all of the relevant joins are in place, so that when
the updater asks to `queryPackageName()` then it can assume that we have
already joined onto the `Schema.PackageTable`.
Renamed the `Schema.AppMetadata.Categories.CATEGORIES` constant into the
`Schema.AppMetadata.ForWriting.Categories.CATEGORIES` constant. This is
to make it very clear that it is not for reading from the database.
When updating existing apps or inserting new apps, instead of splatting
a comma separated list into a single sqlite3 column, we now put it into
several rows in the `CatJoinTable`. This is done after deleting existing
categories, to make sure that if the app has been removed from a category,
then this is reflected during the update.
It was hidden some time ago, and nobody seems to miss it.
Also, we will be redoing this view soon anyway. In the meantime,
this category stuff is changing and this view should be removed.
2016-11-10 08:09:49 +11:00
1958 changed files with 90869 additions and 34130 deletions
description="Copies .jar and .aar files from subproject dependencies in extern/ to app/libs. Requires the sourceDeps property to be set (\"gradle -PsourceDeps binaryDeps\")"
thrownewProjectConfigurationException("Cannot find android sdk. Make sure sdk.dir is defined in local.properties or the environment variable ANDROID_HOME is set.",null)
*@see<ahref="https://artemzin.com/blog/easiest-way-to-give-set_animation_scale-permission-for-your-ui-tests-on-android/>EASIEST WAY TO GIVE SET_ANIMATION_SCALE PERMISSION FOR YOUR UI TESTS ON ANDROID</a>
*@see<ahref="https://gist.github.com/xrigau/11284124>Disable animations for Espresso tests</a>
elsethrownewIllegalStateException(String.format("EOF reached while copying %s with %d bytes left to go",filename,compressedSize-totalCount));
}else
thrownewIllegalStateException(String.format(Locale.ENGLISH,"EOF reached while copying %s with %d bytes left to go",filename,compressedSize-totalCount));
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.