Compare commits

...

182 Commits
1.12 ... master

Author SHA1 Message Date
karl.hudgell
c5fa250331 new icons and settings. 2021-06-23 09:09:07 +01:00
karl.hudgell
a51588ddd2 get working for bobStore 2021-06-22 19:33:08 +01:00
Hans-Christoph Steiner
b066c40176 Merge branch 'immersive-status-bar' into 'master'
Use transparent status bar color

Closes #2203

See merge request fdroid/fdroidclient!1029
2021-06-17 06:38:02 +00:00
proletarius101
bbc2c6b35a Use transparent status bar color 2021-06-17 06:37:31 +00:00
Hans-Christoph Steiner
42b0b576d1
Merge 'Use_ActivityCompat_recreate' into 'master'
* Use_ActivityCompat_recreate:
  resync gradle verification metadata
  Use ActivityCompat.recreate().

fdroid/fdroidclient!1028
2021-06-16 14:37:07 +02:00
Hans-Christoph Steiner
39f680bb24
resync gradle verification metadata 2021-06-16 14:35:10 +02:00
Isira Seneviratne
19ffd2b491 Use ActivityCompat.recreate(). 2021-06-16 12:29:32 +00:00
Hans-Christoph Steiner
a8efa1ac07 Merge branch 'mainline' into 'master'
Read additional_repos.xml from /product as well

See merge request fdroid/fdroidclient!1026
2021-06-16 12:26:29 +00:00
Chirayu Desai
240b7af585 Read additional_repos.xml from /product as well
Change-Id: Id4a99204e4be467f4e3b1d6684eeb86a19a614f2
2021-06-16 11:55:29 +00:00
Hans-Christoph Steiner
345915cdf4 Merge branch '2126-scroll-search' into 'master'
Scroll to first item when search term changes

Closes #2126

See merge request fdroid/fdroidclient!1027
2021-06-16 09:32:49 +00:00
mueller-ma
d7fb1e0044 Scroll to first item when search term changes
Fixes #2126
2021-06-16 09:32:07 +00:00
Hans-Christoph Steiner
0d8018b10e Merge branch 'Replace_AsyncTask_with_RxJava_3' into 'master'
Replace AsyncTask implementations with RxJava 3.

See merge request fdroid/fdroidclient!947
2021-06-15 09:36:55 +00:00
Hans-Christoph Steiner
d9b443429d bump to latest io.reactivex.rxjava3:rxjava 2021-06-15 11:04:22 +02:00
Hans-Christoph Steiner
e698f4f8a3
revert unneeded/unrelated changes 2021-06-15 10:55:22 +02:00
Hans-Christoph Steiner
c27e1a697e
format imports using default Android Studio 4.1.2 settings 2021-06-15 10:55:20 +02:00
Isira Seneviratne
d549fb905d
fix checkstyle LineLength 2021-06-15 10:55:17 +02:00
Isira Seneviratne
c758cb60d9 Fix checkstyle issues. 2021-06-15 08:51:16 +00:00
Isira Seneviratne
eab5ef59b9 Use RxJava instead of AsyncTask to handle updates. 2021-06-15 08:51:16 +00:00
Isira Seneviratne
c0a699e21e Handle server swapping using RxJava instead of AsyncTask. 2021-06-15 08:51:16 +00:00
Isira Seneviratne
242662d02a Create new repos using RxJava instead of AsyncTask. 2021-06-15 08:51:16 +00:00
Isira Seneviratne
e1ca1552f7 Generate a QR bitmap using RxJava instead of AsyncTask. 2021-06-15 08:51:16 +00:00
Isira Seneviratne
93a160b40d Use RxJava 3 types in InstalledAppProviderService. 2021-06-15 08:51:16 +00:00
Isira Seneviratne
5fad229dbe Update RxJava to version 3. 2021-06-15 08:51:16 +00:00
Hans-Christoph Steiner
43a809490c use synchronized for methods that override synchronized methods 2021-06-14 16:36:42 +02:00
Hans-Christoph Steiner
a02ba42cf9
version code 1013001 2021-06-02 22:55:24 +02:00
Hans-Christoph Steiner
3ca9d47aae
update CHANGELOG 2021-06-02 22:55:22 +02:00
Hans-Christoph Steiner
c3e81e0f45
document constant that is used externally
refs #2147
2021-06-02 22:55:20 +02:00
Hans-Christoph Steiner
c7fd1f186b
Android Studio Ctrl-Alt-L code formatting 2021-06-02 22:55:18 +02:00
Hans-Christoph Steiner
ed2b119f33
update PGP key for new expiration date
closes admin#220
closes fdroidclient#2093
2021-06-02 22:55:14 +02:00
Hans-Christoph Steiner
465e92f8bc Merge branch 'TLSv1.2-min' into 'master'
bump netcipher to 2.2.0-alpha to get TorServices and TLSv1.2 min

See merge request fdroid/fdroidclient!1023
2021-06-02 20:33:33 +00:00
Hans-Christoph Steiner
09c7b21fd8
bump netcipher to 2.2.0-alpha to get TorServices and TLSv1.2 min
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.
2021-06-02 22:02:29 +02:00
Hans-Christoph Steiner
6671683d08
fix format strings 2021-06-02 22:02:27 +02:00
Hans-Christoph Steiner
9e6d931e3b
fix lint Typo: "internett" is usually capitalized as "Internett"
sed -i 's,internett,Internett,g' app/src/main/res/values-nb/strings.xml
2021-06-02 22:02:20 +02:00
Kristoffer Grundström
64c349e39a Translated using Weblate: Swedish (sv) by Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Currently translated at 99.7% (467 of 468 strings)

Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sv/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Klemen Skerbiš
bea8b77538 Translated using Weblate: Slovenian (sl) by Klemen Skerbiš <klemen.skerbis1@gmail.com>
Currently translated at 96.7% (453 of 468 strings)

Co-authored-by: Klemen Skerbiš <klemen.skerbis1@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sl/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Слободан Симић(Slobodan Simić)
480e98144d Translated using Weblate: Serbian (sr) by Слободан Симић(Slobodan Simić) <slsimic@gmail.com>
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
2021-06-02 20:05:42 +02:00
Roman Leo
7037bc3e9c Translated using Weblate: German (de) by Roman Leo <roman.leo@gmx.de>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Roman Leo <roman.leo@gmx.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/de/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Software In Interlingua
4e241f9b1b Added translation using Weblate: Interlingua (ia) by Software In Interlingua <softinterlingua@gmail.com>
Co-authored-by: Software In Interlingua <softinterlingua@gmail.com>
2021-06-02 20:05:42 +02:00
GnuPGを使うべきだ
79ea0a08c3 Translated using Weblate: Japanese (ja) by GnuPGを使うべきだ <dieeeazpnnqbpddh@cock.email>
Currently translated at 97.0% (454 of 468 strings)

Co-authored-by: GnuPGを使うべきだ <dieeeazpnnqbpddh@cock.email>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ja/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
vancha
e02b8cd80e Translated using Weblate: Frisian (fy) by vancha <tjipke@tutanota.com>
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
2021-06-02 20:05:42 +02:00
Translator
ba56933e87 Translated using Weblate: Hindi (hi) by Translator <pahatih716@to200.com>
Currently translated at 99.3% (465 of 468 strings)

Co-authored-by: Translator <pahatih716@to200.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/hi/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Myeongjin Lee
45ad90bfbc Translated using Weblate: Korean (ko) by Myeongjin Lee <aranet100@gmail.com>
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
2021-06-02 20:05:42 +02:00
random r
35f6e25d18 Translated using Weblate: Italian (it) by random r <epsilin@yopmail.com>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: random r <epsilin@yopmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/it/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Besnik Bleta
b031cf3d07 Translated using Weblate: Albanian (sq) by Besnik Bleta <besnik@programeshqip.org>
Currently translated at 100.0% (468 of 468 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
2021-06-02 20:05:42 +02:00
moar pics
3821b9e6d6 Translated using Weblate: Albanian (sq) by moar pics <m0arpicsss@gmail.com>
Currently translated at 99.5% (466 of 468 strings)

Co-authored-by: moar pics <m0arpicsss@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sq/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Jonas Matisen
21354b76ff Translated using Weblate: Norwegian Bokmål (nb) by Jonas Matisen <hdsumo@protonmail.ch>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Jonas Matisen <hdsumo@protonmail.ch>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/nb_NO/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
nautilusx
602c203495 Translated using Weblate: German (de) by nautilusx <translate@disroot.org>
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
2021-06-02 20:05:42 +02:00
Watson15683
0ead57926c Translated using Weblate: German (de) by Watson15683 <peter.parker2@tutanota.com>
Currently translated at 100.0% (36 of 36 strings)

Co-authored-by: Watson15683 <peter.parker2@tutanota.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/de/
Translation: F-Droid/F-Droid metadata
2021-06-02 20:05:42 +02:00
Keunes
002b01823e Translated using Weblate: Dutch (nl) by Keunes <koen.glotzbach@gmail.com>
Currently translated at 99.7% (467 of 468 strings)

Co-authored-by: Keunes <koen.glotzbach@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/nl/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Karl Ove Hufthammer
45ed83501e Translated using Weblate: Norwegian Nynorsk (nn) by Karl Ove Hufthammer <karl@huftis.org>
Currently translated at 100.0% (36 of 36 strings)

Translated using Weblate: Norwegian Nynorsk (nn) by Karl Ove Hufthammer <karl@huftis.org>

Currently translated at 100.0% (468 of 468 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
2021-06-02 20:05:42 +02:00
WaldiS
2c69c5ccf3 Translated using Weblate: Polish (pl) by WaldiS <sto@tutanota.de>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: WaldiS <sto@tutanota.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pl/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Manuela Silva
e52b8a27d6 Translated using Weblate: Portuguese (Portugal) (pt-rPT) by Manuela Silva <mmsrs@sky.com>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Manuela Silva <mmsrs@sky.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt_PT/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Nicolas Mariniello
2dc8deca59 Translated using Weblate: Italian (it) by Nicolas Mariniello <seldon1000@tutanota.com>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Nicolas Mariniello <seldon1000@tutanota.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/it/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
J. Lavoie
25392dd8bd Translated using Weblate: English (United Kingdom) (en-rGB) by J. Lavoie <j.lavoie@net-c.ca>
Currently translated at 100.0% (468 of 468 strings)

Translated using Weblate: Italian (it) by J. Lavoie <j.lavoie@net-c.ca>

Currently translated at 99.7% (467 of 468 strings)

Translated using Weblate: French (fr) by J. Lavoie <j.lavoie@net-c.ca>

Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: J. Lavoie <j.lavoie@net-c.ca>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/en_GB/
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
2021-06-02 20:05:42 +02:00
Oymate
60a8eccb5f Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
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
2021-06-02 20:05:42 +02:00
Priit Jõerüüt
6cf9e9d105 Translated using Weblate: Estonian (et) by Priit Jõerüüt <hwlate@joeruut.com>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Priit Jõerüüt <hwlate@joeruut.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/et/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Francesc Sanjuán farré
5489f0a089 Translated using Weblate: Catalan (ca) by Francesc Sanjuán farré <fran@franer.systems>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Francesc Sanjuán farré <fran@franer.systems>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ca/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Rafael Ruiz
cc12359ba6 Translated using Weblate: Catalan (ca) by Rafael Ruiz <rafael.ruiz@upc.edu>
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
2021-06-02 20:05:42 +02:00
Milo Ivir
173aa6792a Translated using Weblate: Croatian (hr) by Milo Ivir <mail@milotype.de>
Currently translated at 92.7% (434 of 468 strings)

Co-authored-by: Milo Ivir <mail@milotype.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/hr/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Ranjith Kumar
72c0c6f4a6 Translated using Weblate: Tamil (ta) by Ranjith Kumar <sranjith096@gmail.com>
Currently translated at 36.1% (169 of 468 strings)

Co-authored-by: Ranjith Kumar <sranjith096@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ta/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
whenwesober
5e8948b534 Translated using Weblate: Indonesian (id) by whenwesober <naomi16i_1298q@cikuh.com>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: whenwesober <naomi16i_1298q@cikuh.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/id/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
ssantos
19b7b57b43 Translated using Weblate: Portuguese (pt) by ssantos <ssantos@web.de>
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
2021-06-02 20:05:42 +02:00
Andrey
ae37d587d4 Translated using Weblate: Russian (ru) by Andrey <andrey@mailbox.org>
Currently translated at 100.0% (36 of 36 strings)

Translated using Weblate: Russian (ru) by Andrey <andrey@mailbox.org>

Currently translated at 100.0% (468 of 468 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
2021-06-02 20:05:42 +02:00
Licaon Kter
0f635d6e80 Translated using Weblate: Romanian (ro) by Licaon Kter <licaon.kter@protonmail.com>
Currently translated at 100.0% (468 of 468 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
2021-06-02 20:05:42 +02:00
Wellington Terumi Uemura
eeb5f5f2ec Translated using Weblate: Portuguese (Brazil) (pt-rBR) by Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt_BR/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
alefvanoon
4342d87b37 Translated using Weblate: Persian (fa) by alefvanoon <alefvanoon@tuta.io>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: alefvanoon <alefvanoon@tuta.io>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fa/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Sina Carnelious
27ddf42897 Translated using Weblate: Persian (fa) by Sina Carnelious <sinacarnelious@protonmail.com>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Sina Carnelious <sinacarnelious@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fa/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
C. Rüdinger
b642b14d5a Translated using Weblate: German (de) by C. Rüdinger <Mail-an-CR@web.de>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: C. Rüdinger <Mail-an-CR@web.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/de/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
zeritti
b2a9854e1a Translated using Weblate: Czech (cs) by zeritti <woodenmo@posteo.de>
Currently translated at 100.0% (468 of 468 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
2021-06-02 20:05:42 +02:00
Rex_sa
9d738f0d9d Translated using Weblate: Arabic (ar) by Rex_sa <rex.sa@pm.me>
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
2021-06-02 20:05:42 +02:00
André Marcelo Alvarenga
d32d866393 Translated using Weblate: Portuguese (Brazil) (pt-rBR) by André Marcelo Alvarenga <andrealvarenga@gmx.net>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: André Marcelo Alvarenga <andrealvarenga@gmx.net>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt_BR/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Athanasios Plastiras
f09434869e Translated using Weblate: Greek (el) by Athanasios Plastiras <admin@plastiras.org>
Currently translated at 99.7% (467 of 468 strings)

Co-authored-by: Athanasios Plastiras <admin@plastiras.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/el/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Jeff Huang
f12f6694c4 Translated using Weblate: Chinese (Traditional) (zh-rTW) by Jeff Huang <s8321414@gmail.com>
Currently translated at 100.0% (468 of 468 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
2021-06-02 20:05:42 +02:00
Eric
6a3d989778 Translated using Weblate: Chinese (Simplified) (zh-CN) by Eric <spice2wolf@gmail.com>
Currently translated at 100.0% (36 of 36 strings)

Translated using Weblate: Chinese (Simplified) (zh-rCN) by Eric <spice2wolf@gmail.com>

Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Eric <spice2wolf@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/zh_Hans/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
2021-06-02 20:05:42 +02:00
bruh
de1b05d307 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)

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
2021-06-02 20:05:42 +02:00
Ihor Hordiichuk
16ab3672cd Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk <igor_ck@outlook.com>
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
2021-06-02 20:05:42 +02:00
Oğuz Ersen
108b9e4bf4 Translated using Weblate: Turkish (tr) by Oğuz Ersen <oguzersen@protonmail.com>
Currently translated at 100.0% (36 of 36 strings)

Translated using Weblate: Turkish (tr) by Oğuz Ersen <oguzersen@protonmail.com>

Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/tr/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/tr/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
2021-06-02 20:05:42 +02:00
Ajeje Brazorf
82d1fe8815 Translated using Weblate: Sardinian (sc) by Ajeje Brazorf <lmelonimamo@yahoo.it>
Currently translated at 5.5% (2 of 36 strings)

Translated using Weblate: Sardinian (sc) by Ajeje Brazorf <lmelonimamo@yahoo.it>

Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/sc/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sc/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
2021-06-02 20:05:42 +02:00
S3aBreeze
ecc017845d Translated using Weblate: Russian (ru) by S3aBreeze <paperwork@evilcorp.ltd>
Currently translated at 100.0% (36 of 36 strings)

Translated using Weblate: Russian (ru) by S3aBreeze <paperwork@evilcorp.ltd>

Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: S3aBreeze <paperwork@evilcorp.ltd>
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
2021-06-02 20:05:42 +02:00
Wellington Terumi Uemura
6b2157fc1c Translated using Weblate: Portuguese (Brazil) (pt-rBR) by Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt_BR/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Yaron Shahrabani
b8b4da7ac9 Translated using Weblate: Hebrew (he) by Yaron Shahrabani <sh.yaron@gmail.com>
Currently translated at 100.0% (36 of 36 strings)

Translated using Weblate: Hebrew (he) by Yaron Shahrabani <sh.yaron@gmail.com>

Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Yaron Shahrabani <sh.yaron@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/he/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/he/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
2021-06-02 20:05:42 +02:00
Deleted User
0b3edc812c Translated using Weblate: French (fr) by Deleted User <noreply+26956@weblate.org>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Deleted User <noreply+26956@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fr/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
Ldm Public
30521f00cd Translated using Weblate: French (fr) by Ldm Public <ldmpub@gmail.com>
Currently translated at 100.0% (468 of 468 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
2021-06-02 20:05:42 +02:00
Kkai
4eea2cb4e1 Translated using Weblate: Spanish (es) by Kkai <kaieltroll@gmail.com>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Kkai <kaieltroll@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/es/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
☆Verdulo
aa2537eb6d Translated using Weblate: Esperanto (eo) by ☆Verdulo <tomek@disroot.org>
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
2021-06-02 20:05:42 +02:00
Hans-Christoph Steiner
1747a0a737 Translated using Weblate: German (de) by Hans-Christoph Steiner <hans@guardianproject.info>
Currently translated at 100.0% (468 of 468 strings)

Co-authored-by: Hans-Christoph Steiner <hans@guardianproject.info>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/de/
Translation: F-Droid/F-Droid
2021-06-02 20:05:42 +02:00
VfBFan
60c41783cc 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)

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
2021-06-02 20:05:42 +02:00
Chirayu Desai
3d53b22e37 Merge branch 'master' into 'master'
Fix Trichrome Library installation status mismatch

Closes #2184

See merge request fdroid/fdroidclient!1002
2021-06-02 18:05:23 +00:00
Hans-Christoph Steiner
719a599c41 Merge branch 'theme_screenshot_placeholder' into 'master'
theme the screenshot placeholder

Closes #2127

See merge request fdroid/fdroidclient!1007
2021-06-02 16:32:52 +00:00
Conny Duck
10111b2beb theme the screenshot placeholder 2021-06-02 16:32:51 +00:00
Hans-Christoph Steiner
1fd3b308e9 Merge branch 'remove_mainactivity_saved_state' into 'master'
remove unneeded saved state handling in MainActivity

See merge request fdroid/fdroidclient!1017
2021-06-02 12:33:01 +00:00
Konrad Pozniak
ee5c2b6632 remove unneeded saved state handling in MainActivity 2021-06-02 10:24:26 +00:00
Hans-Christoph Steiner
6155bdbe20 Merge branch 'crane-shape-theming' into 'master'
Consistent round shape theming by parameters from Crane

See merge request fdroid/fdroidclient!1013
2021-06-02 10:21:14 +00:00
proletarius101
8ffbd0b44d Consistent round shape theming by parameters from Crane 2021-06-02 10:21:14 +00:00
Hans-Christoph Steiner
a5d678b72e Merge branch 'fix-bottom-navigation-bar-dark-theme-color' into 'master'
Change the bottom navigation bar to the material component one

See merge request fdroid/fdroidclient!1008
2021-05-18 12:39:58 +00:00
proletarius101
e48c49ce0c Change the bottom navigation bar to the material component one 2021-05-18 12:39:58 +00:00
Hans-Christoph Steiner
7993b04cf4 Merge branch 'mdc-text-fields' into 'master'
Migrate to MDC text fields

See merge request fdroid/fdroidclient!1012
2021-05-18 12:01:16 +00:00
proletarius101
ca54511cf6 Migrate to MDC text fields 2021-05-18 12:01:15 +00:00
Hans-Christoph Steiner
fc463810f6 Merge branch 'mdc-switches' into 'master'
Migrate to MDC switches

See merge request fdroid/fdroidclient!1014
2021-05-18 11:37:53 +00:00
proletarius101
a1369cdd67 Migrate to MDC switches 2021-05-18 11:35:52 +00:00
Hans-Christoph Steiner
3178624b4b Merge branch 'mdc-cards' into 'master'
Migrate CardView to MaterialCardView

See merge request fdroid/fdroidclient!1011
2021-05-18 10:53:43 +00:00
proletarius101
2530487483 Migrate CardView to MaterialCardView 2021-05-18 10:53:17 +00:00
Hans-Christoph Steiner
03c16e3f1b Merge branch 'fix-sort-botton-tint' into 'master'
Fix sort button tint

See merge request fdroid/fdroidclient!1010
2021-05-18 10:48:20 +00:00
proletarius101
fee35fe285 Fix sort button tint 2021-05-17 17:34:24 +00:00
Hans-Christoph Steiner
b310032cf5 Merge branch 'fix-pipeline-badge' into 'master'
Fix pipeline badge in README

See merge request fdroid/fdroidclient!1009
2021-05-17 16:55:55 +00:00
Benedikt Brückmann
07aae0674f Fix pipeline badge in README
relates to fdroid/fdroidclient#2173
2021-05-17 11:05:34 +02:00
Hans-Christoph Steiner
cbea1539f8 Merge branch 'fix_opencollective_badge' into 'master'
improve opencollective badge

See merge request fdroid/fdroidclient!1006
2021-05-13 22:02:32 +00:00
Konrad Pozniak
90d514ac6a improve opencollective badge 2021-05-13 21:32:21 +00:00
Hans-Christoph Steiner
97bc77b03a Merge branch 'fix_opencollective_link_not_shown' into 'master'
fix opencollective badge not shown when it is the only donation option

See merge request fdroid/fdroidclient!1005
2021-05-13 21:30:54 +00:00
Konrad Pozniak
02ee182508 fix opencollective badge not shown when it is the only donation option 2021-05-12 20:40:35 +02:00
Hans-Christoph Steiner
6e2b258eee Merge branch 'change-link-icon' into 'master'
Use the Material Design link icon (chain) for links

See merge request fdroid/fdroidclient!1004
2021-05-06 13:11:53 +00:00
proletarius101
5a183d27d1 Use the Material Design link icon for links 2021-05-05 22:21:03 +08:00
Oliver Scott
b52c7ca39a Remove duplicate entries from installed packages list 2021-04-30 13:27:19 +00:00
Oliver Scott
e677d815d4 Sync installed app database with package manager on PACKAGE_CHANGED for shared libraries 2021-04-30 13:27:19 +00:00
Hans-Christoph Steiner
471d2b86c7 Merge branch 'update-material-componnets-library' into 'master'
Update material components library to 1.3.0

See merge request fdroid/fdroidclient!1003
2021-04-28 16:34:47 +00:00
proletarius101
aaf08fea0c Update material components library to 1.3.0 2021-04-28 19:17:05 +08:00
Hans-Christoph Steiner
37275e2c7c
version code 1013000 2021-04-22 11:59:10 +02:00
Hans-Christoph Steiner
723a4996fb
update CHANGELOG 2021-04-22 11:59:06 +02:00
Hans-Christoph Steiner
cb53c8bbd6 Merge 'fix-icon' into master
* 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
2021-04-22 11:58:18 +02:00
Hans-Christoph Steiner
cc37dab980 Merge branch 'weblate' into 'master'
weblate

See merge request fdroid/fdroidclient!1000
2021-04-22 09:53:24 +00:00
Hans-Christoph Steiner
24ed554b1d use Android Studio default Ctrl-Alt-L to format all AndroidManifest.xml 2021-04-22 11:24:38 +02:00
Hans-Christoph Steiner
deea4bd696 fully separate "Last Updated" icon from "Versions"
These two are the same shape, but different sizes, and this is an easy way
to manage the sizes.

closes #2148
2021-04-22 11:24:38 +02:00
Hans-Christoph Steiner
7db4456aae purge unused AboutActivity
!963 made it an AlertDialog
2021-04-22 11:24:38 +02:00
Hans-Christoph Steiner
98c204e74e rename: update_notification_title --> banner_updating_repositories
sed -i 's,update_notification_title,banner_updating_repositories,g' app/src/main/res/values*/strings.xml
2021-04-22 11:00:53 +02:00
Sérgio Morais
028d5f5a4f Translated using Weblate: Portuguese (pt) by Sérgio Morais <lalocas@protonmail.com>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Sérgio Morais <lalocas@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
j.kemu
4716e77e6d Translated using Weblate: Burmese (my) by j.kemu <zartlike@mailinator.com>
Currently translated at 51.2% (239 of 466 strings)

Co-authored-by: j.kemu <zartlike@mailinator.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/my/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Aryan L
c1f8862128 Translated using Weblate: Hindi (hi) by Aryan L <aryan.landge@icloud.com>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Aryan L <aryan.landge@icloud.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/hi/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Aputsiaĸ Niels Janussen
05564afdec Translated using Weblate: Danish (da) by Aputsiaĸ Niels Janussen <aj@isit.gl>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Aputsiaĸ Niels Janussen <aj@isit.gl>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/da/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
whenwesober
b1856022c6 Translated using Weblate: Indonesian (id) by whenwesober <naomi16i_1298q@cikuh.com>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: whenwesober <naomi16i_1298q@cikuh.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/id/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Jonatan Nyberg
b201a4ed0c Translated using Weblate: Swedish (sv) by Jonatan Nyberg <jonatan.nyberg.karl@gmail.com>
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
2021-04-22 10:44:23 +02:00
mondstern
a34c6e316b Translated using Weblate: Italian (it) by mondstern <mondstern@snopyta.org>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: mondstern <mondstern@snopyta.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/it/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
J. Lavoie
f6a630c5c9 Translated using Weblate: English (United Kingdom) (en-rGB) 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)

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
2021-04-22 10:44:23 +02:00
Christian Eichert
6bc82c3cff Translated using Weblate: German (de) by Christian Eichert <c@zp1.net>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Christian Eichert <c@zp1.net>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/de/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Wellington Terumi Uemura
a0e33276b6 Translated using Weblate: Portuguese (Brazil) (pt-rBR) by Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pt_BR/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
سهیل خانعلی‌پور
42754339db Translated using Weblate: Persian (fa) by سهیل خانعلی‌پور <soheil@disroot.org>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: سهیل خانعلی‌پور <soheil@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fa/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
FintasticMan
a8a6dfc802 Translated using Weblate: Dutch (nl) by FintasticMan <finlay.davidson@coderclass.nl>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: FintasticMan <finlay.davidson@coderclass.nl>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/nl/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Line
29c608b176 Translated using Weblate: Latvian (lv) by Line <LineAirline@protonmail.com>
Currently translated at 86.9% (405 of 466 strings)

Co-authored-by: Line <LineAirline@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/lv/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
janne ojanperä
2be3c0509b Translated using Weblate: Finnish (fi) by janne ojanperä <janne.ojanpera@iki.fi>
Currently translated at 97.8% (456 of 466 strings)

Co-authored-by: janne ojanperä <janne.ojanpera@iki.fi>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fi/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
peylight
86f0891321 Translated using Weblate: Persian (fa) by peylight <peylight@riseup.net>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: peylight <peylight@riseup.net>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/fa/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Besnik Bleta
72757fd653 Translated using Weblate: Albanian (sq) by Besnik Bleta <besnik@programeshqip.org>
Currently translated at 100.0% (466 of 466 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
2021-04-22 10:44:23 +02:00
Baptiste H
a534f37efb Translated using Weblate: French (fr) by Baptiste H <baptiste.huchon@bechamail.fr>
Currently translated at 94.4% (34 of 36 strings)

Co-authored-by: Baptiste H <baptiste.huchon@bechamail.fr>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/fr/
Translation: F-Droid/F-Droid metadata
2021-04-22 10:44:23 +02:00
Shashank Pujari
246936ede7 Translated using Weblate: Kannada (kn) by Shashank Pujari <shashankppujari@gmail.com>
Currently translated at 100.0% (466 of 466 strings)

Translated using Weblate: Hindi (hi) by Shashank Pujari <shashankppujari@gmail.com>

Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Shashank Pujari <shashankppujari@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/hi/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/kn/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Michał
dd69feac52 Translated using Weblate: Polish (pl) by Michał <matmatyk@protonmail.com>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Michał <matmatyk@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/pl/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Jeff Huang
36fc7a4eed Translated using Weblate: Chinese (Traditional) (zh-rTW) by Jeff Huang <s8321414@gmail.com>
Currently translated at 100.0% (466 of 466 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
2021-04-22 10:44:23 +02:00
Priit Jõerüüt
fb5c273c8e Translated using Weblate: Estonian (et) by Priit Jõerüüt <hwlate@joeruut.com>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Priit Jõerüüt <hwlate@joeruut.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/et/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Ihor Hordiichuk
d8f9aa7bd7 Translated using Weblate: Ukrainian (uk) by Ihor Hordiichuk <igor_ck@outlook.com>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/uk/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Ajeje Brazorf
5b2af1b0c8 Translated using Weblate: Sardinian (sc) by Ajeje Brazorf <lmelonimamo@yahoo.it>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/sc/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
rhyte
97ee9bf5fe Translated using Weblate: Romanian (ro) by rhyte <vmhl.ph@gmail.com>
Currently translated at 100.0% (466 of 466 strings)

Co-authored-by: rhyte <vmhl.ph@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/ro/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
Yaron Shahrabani
4f789c560d Translated using Weblate: Hebrew (he) by Yaron Shahrabani <sh.yaron@gmail.com>
Currently translated at 100.0% (466 of 466 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
2021-04-22 10:44:23 +02:00
Ldm Public
aca7faa3fa Translated using Weblate: French (fr) by Ldm Public <ldmpub@gmail.com>
Currently translated at 100.0% (466 of 466 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
2021-04-22 10:44:23 +02:00
Verdulo
422bba662f Translated using Weblate: Esperanto (eo) by Verdulo <tomek@disroot.org>
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
2021-04-22 10:44:23 +02:00
Malte Jürgens
b2687ca1d6 Translated using Weblate: German (de) by Malte Jürgens <maltejur@web.de>
Currently translated at 99.5% (464 of 466 strings)

Co-authored-by: Malte Jürgens <maltejur@web.de>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/de/
Translation: F-Droid/F-Droid
2021-04-22 10:44:23 +02:00
random r
edff08c3c2 Translated using Weblate: Italian (it) by random r <epsilin@yopmail.com>
Currently translated at 100.0% (36 of 36 strings)

Co-authored-by: random r <epsilin@yopmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/it/
Translation: F-Droid/F-Droid metadata
2021-04-22 10:44:23 +02:00
Oymate
e7014bf7ac Translated using Weblate: Bengali (bn) by Oymate <dhruboadittya96@gmail.com>
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
2021-04-22 10:44:23 +02:00
bruh
5c8c46f3ad Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>
Currently translated at 100.0% (466 of 466 strings)

Translated using Weblate: Vietnamese (vi) by bruh <quangtrung02hn16@gmail.com>

Currently translated at 8.3% (3 of 36 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
2021-04-22 10:44:23 +02:00
Allan Nordhøy
6b73ed74ed Translated using Weblate: Norwegian Bokmål (nb) by Allan Nordhøy <epost@anotheragency.no>
Currently translated at 100.0% (464 of 464 strings)

Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/nb_NO/
Translation: F-Droid/F-Droid
2021-04-22 10:43:32 +02:00
Eric
7912f12cf5 Translated using Weblate: Chinese (Simplified) (zh-rCN) by Eric <spice2wolf@gmail.com>
Currently translated at 100.0% (466 of 466 strings)

Translated using Weblate: Chinese (Simplified) (zh-CN) by Eric <spice2wolf@gmail.com>

Currently translated at 100.0% (36 of 36 strings)

Co-authored-by: Eric <spice2wolf@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/zh_Hans/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
2021-04-22 10:43:32 +02:00
Oğuz Ersen
001a337994 Translated using Weblate: Turkish (tr) by Oğuz Ersen <oguzersen@protonmail.com>
Currently translated at 100.0% (466 of 466 strings)

Translated using Weblate: Turkish (tr) by Oğuz Ersen <oguzersen@protonmail.com>

Currently translated at 100.0% (36 of 36 strings)

Co-authored-by: Oğuz Ersen <oguzersen@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid-metadata/tr/
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/tr/
Translation: F-Droid/F-Droid
Translation: F-Droid/F-Droid metadata
2021-04-22 10:43:32 +02:00
Andrey
f7895cea87 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% (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
2021-04-22 10:43:32 +02:00
Nikolai Ommundsen
f91728b081 Translated using Weblate: Norwegian Bokmål (nb) by Nikolai Ommundsen <post@niikoo.net>
Currently translated at 100.0% (464 of 464 strings)

Co-authored-by: Nikolai Ommundsen <post@niikoo.net>
Translate-URL: https://hosted.weblate.org/projects/f-droid/f-droid/nb_NO/
Translation: F-Droid/F-Droid
2021-04-22 10:43:32 +02:00
Chirayu Desai
c9fbb97018 Merge branch 'only-update-local-repos-without-internet' into 'master'
when no internet and local repos, only update local repos

Closes #2146

See merge request fdroid/fdroidclient!997
2021-04-21 20:32:08 +00:00
Hans-Christoph Steiner
18a43ac471 ignore system partition repos when checking for local repos
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.
2021-04-13 22:46:11 +02:00
Hans-Christoph Steiner
908921e978 show banner when Over Data/WiFi Settings disable updating from internet 2021-04-13 16:26:23 +02:00
Hans-Christoph Steiner
8773d6205c rename BannerUpdatingRepos --> StatusBanner 2021-04-13 16:26:23 +02:00
Hans-Christoph Steiner
a505850110 "No internet" banner on main, categories, and updates screen
An alternate implementation of @pserwylo's fdroidclient!724

closes #884
2021-04-13 16:26:08 +02:00
Hans-Christoph Steiner
d9a86d4c16 rename: update_notification_title --> banner_updating_repositories 2021-04-13 13:59:08 +02:00
Hans-Christoph Steiner
5acc87c405 LocalHTTPDManagerTest is flaky, use 10 minute timeout 2021-04-13 13:17:56 +02:00
Hans-Christoph Steiner
f39fc1386a synchronized getNewMirrorOnError() for safe writing of numTries
`volatile` allows for safe multi-threaded reading, `synchronized` allows
for safe multi-threaded writing.
2021-04-13 13:17:56 +02:00
Hans-Christoph Steiner
1758c2c9f1 when no internet and local repos, only update local repos
closes #2146
2021-04-13 13:17:56 +02:00
Hans-Christoph Steiner
35cc9bce42
reformat all layout/ui XML with Android Studio Ctrl-Alt-L 2021-04-13 10:32:25 +02:00
Hans-Christoph Steiner
cf94cfb543
run Android Studio's Ctrl-Alt-O Organize Imports on all .java files 2021-04-13 10:23:59 +02:00
Hans-Christoph Steiner
9d5af90c61 Merge branch 'material-components' into 'master'
feat: rebase app themes to material themes

Closes #2145

See merge request fdroid/fdroidclient!963
2021-04-12 16:36:18 +00:00
proletarius101
755588202f feat: rebase app themes to material themes 2021-04-12 16:36:17 +00:00
Hans-Christoph Steiner
5af693265f Merge branch 'master' into 'master'
fix trove4j verification error

See merge request fdroid/fdroidclient!998
2021-04-12 15:42:22 +00:00
Hans-Christoph Steiner
1cd02f02e0
fix trove4j verification error
trove4j-20160824.pom uploaded to mavenCentral has more info in it, so a
different sha256.
2021-04-12 15:57:40 +02:00
Hans-Christoph Steiner
4bf168eedd
Merge branch 'migrate-to-appcompat'
* deleteme:
  update gradle verification metadata
  Replace deprecated methods introduced
  Remove duplicated xml properties
  Fix missing text messages in preference_seekbar
  fix: linting
  Extensively use appcompat

fdroid/fdroidclient!975
2021-04-07 22:02:11 +02:00
Hans-Christoph Steiner
04ab3aefa4
update gradle verification metadata
./gradlew --write-verification-metadata pgp,sha256 assemble
./gradlew --write-verification-metadata sha256 assemble
2021-04-07 22:00:20 +02:00
proletarius101
f8f48e1be4 Replace deprecated methods introduced 2021-04-07 14:02:48 +00:00
proletarius101
b5ab4eb978 Remove duplicated xml properties 2021-04-07 14:02:48 +00:00
proletarius101
1a1a06b499 Fix missing text messages in preference_seekbar 2021-04-07 14:02:48 +00:00
proletarius101
96cf03b277 fix: linting 2021-04-07 14:02:48 +00:00
proletarius101
528eecb63c Extensively use appcompat 2021-04-07 14:02:48 +00:00
533 changed files with 6685 additions and 7106 deletions

View File

@ -1,3 +1,27 @@
### 1.13-alpha1 (2021-06-02)
* Stop repeated updates of Trichrome Library
* More changes to follow Material Design (@proletarius101)
* Improve OpenCollective badge (@ConnyDuck)
### 1.13-alpha0 (2021-04-22)
* Theme support tied to built-in Android themes (@proletarius101)
* New top banner notifications: "No Internet" and "No Data or WiFi enabled"
* Improved handling of USB-OTG and SD Card repos and mirrors
### 1.12.1 (2021-04-12)
* Fix trove4j verification error
### 1.12 (2021-04-06)
* Sync translations
### 1.12-alpha3 (2021-03-10) ### 1.12-alpha3 (2021-03-10)
* Opt-in F-Droid Metrics * Opt-in F-Droid Metrics

View File

@ -1,6 +1,6 @@
# F-Droid Client # F-Droid Client
[![build status](https://gitlab.com/fdroid/fdroidclient/badges/master/build.svg)](https://gitlab.com/fdroid/fdroidclient/builds) [![build status](https://gitlab.com/fdroid/fdroidclient/badges/master/pipeline.svg)](https://gitlab.com/fdroid/fdroidclient/-/jobs)
[![Translation status](https://hosted.weblate.org/widgets/f-droid/-/svg-badge.svg)](https://hosted.weblate.org/engage/f-droid/) [![Translation status](https://hosted.weblate.org/widgets/f-droid/-/svg-badge.svg)](https://hosted.weblate.org/engage/f-droid/)
Client for [F-Droid](https://f-droid.org), the Free Software repository system Client for [F-Droid](https://f-droid.org), the Free Software repository system

View File

@ -21,16 +21,16 @@ def basicApplicationId = "org.fdroid.basic"
def privilegedExtensionApplicationId = '"org.fdroid.fdroid.privileged"' def privilegedExtensionApplicationId = '"org.fdroid.fdroid.privileged"'
android { android {
compileSdkVersion 29 compileSdkVersion 30
defaultConfig { defaultConfig {
versionCode 1012050 versionCode 1013001
versionName getVersionName() versionName getVersionName()
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
minSdkVersion 14 minSdkVersion 24
//noinspection ExpiredTargetSdkVersion //noinspection ExpiredTargetSdkVersion
targetSdkVersion 25 targetSdkVersion 28
/* /*
The Android Testing Support Library collects analytics to continuously improve the testing The Android Testing Support Library collects analytics to continuously improve the testing
experience. More specifically, it uploads a hash of the package name of the application experience. More specifically, it uploads a hash of the package name of the application
@ -38,6 +38,7 @@ android {
passing the following argument to the test runner: disableAnalytics "true". passing the following argument to the test runner: disableAnalytics "true".
*/ */
testInstrumentationRunnerArguments disableAnalytics: 'true' testInstrumentationRunnerArguments disableAnalytics: 'true'
vectorDrawables.useSupportLibrary = true
} }
buildTypes { buildTypes {
@ -141,10 +142,9 @@ android {
} }
dependencies { dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0' implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
@ -152,18 +152,19 @@ dependencies {
implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.palette:palette:1.0.0'
implementation 'androidx.work:work-runtime:2.4.0' implementation 'androidx.work:work-runtime:2.4.0'
implementation 'com.google.android.material:material:1.1.0' implementation 'com.google.android.material:material:1.3.0'
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation 'com.google.zxing:core:3.3.3' implementation 'com.google.zxing:core:3.3.3'
implementation 'info.guardianproject.netcipher:netcipher:2.0.0-beta1' implementation 'info.guardianproject.netcipher:netcipher:2.2.0-alpha'
implementation 'info.guardianproject.panic:panic:1.0' implementation 'info.guardianproject.panic:panic:1.0'
implementation 'commons-io:commons-io:2.6' implementation 'commons-io:commons-io:2.6'
implementation 'commons-net:commons-net:3.6' implementation 'commons-net:commons-net:3.6'
implementation 'ch.acra:acra:4.9.1' implementation 'ch.acra:acra:4.9.1'
implementation 'io.reactivex:rxjava:1.1.0'
implementation 'com.hannesdorfmann:adapterdelegates3:3.0.1' implementation 'com.hannesdorfmann:adapterdelegates3:3.0.1'
implementation 'com.ashokvarma.android:bottom-navigation-bar:2.0.5'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.9'
implementation 'com.fasterxml.jackson.core:jackson-core:2.11.1' implementation 'com.fasterxml.jackson.core:jackson-core:2.11.1'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.11.1' implementation 'com.fasterxml.jackson.core:jackson-annotations:2.11.1'

View File

@ -31,13 +31,6 @@
public *; public *;
} }
# The rxjava library depends on sun.misc.Unsafe, which is unavailable on Android
# The rxjava team is aware of this, and mention in the docs that they only use
# the unsafe functionality if the platform supports it.
# - https://github.com/ReactiveX/RxJava/issues/1415#issuecomment-48390883
# - https://github.com/ReactiveX/RxJava/blob/1.x/src/main/java/rx/internal/util/unsafe/UnsafeAccess.java#L23
-dontwarn rx.internal.util.**
-keepattributes *Annotation*,EnclosingMethod,Signature -keepattributes *Annotation*,EnclosingMethod,Signature
-keepnames class com.fasterxml.jackson.** { *; } -keepnames class com.fasterxml.jackson.** { *; }
-dontwarn com.fasterxml.jackson.databind.ext.** -dontwarn com.fasterxml.jackson.databind.ext.**

View File

@ -1,18 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us --> <!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="org.fdroid.fdroid.tests" package="org.fdroid.fdroid.tests"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0"> android:versionName="1.0">
<uses-sdk tools:overrideLibrary="android_libs.ub_uiautomator" /> <uses-sdk tools:overrideLibrary="android_libs.ub_uiautomator" />
<!-- We add an application tag here just so that we can indicate that <!-- We add an application tag here just so that we can indicate that
this package needs to link against the android.test library, this package needs to link against the android.test library,
which is needed when building test cases. --> which is needed when building test cases. -->
<application> <application>
<uses-library android:name="android.test.runner" <uses-library
android:name="android.test.runner"
android:required="false" /> android:required="false" />
</application> </application>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest> </manifest>

View File

@ -21,7 +21,7 @@ import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector; import androidx.test.uiautomator.UiSelector;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import org.fdroid.fdroid.views.BannerUpdatingRepos; import org.fdroid.fdroid.views.StatusBanner;
import org.fdroid.fdroid.views.main.MainActivity; import org.fdroid.fdroid.views.main.MainActivity;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.After; import org.junit.After;
@ -267,7 +267,7 @@ public class MainActivityEspressoTest {
if (!BuildConfig.FLAVOR.startsWith("full")) { if (!BuildConfig.FLAVOR.startsWith("full")) {
return; return;
} }
onView(Matchers.<View>instanceOf(BannerUpdatingRepos.class)).check(matches(not(isDisplayed()))); onView(Matchers.<View>instanceOf(StatusBanner.class)).check(matches(not(isDisplayed())));
onView(allOf(withText(R.string.menu_settings), isDisplayed())).perform(click()); onView(allOf(withText(R.string.menu_settings), isDisplayed())).perform(click());
onView(allOf(withText(R.string.main_menu__latest_apps), isDisplayed())).perform(click()); onView(allOf(withText(R.string.main_menu__latest_apps), isDisplayed())).perform(click());
onView(allOf(withId(R.id.swipe_to_refresh), isDisplayed())) onView(allOf(withId(R.id.swipe_to_refresh), isDisplayed()))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -1,13 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen android:title="@string/about_title"> <PreferenceScreen android:title="@string/about_title"
<intent android:key="pref_about" />
android:action="android.intent.action.MAIN"
android:targetPackage="@string/applicationId"
android:targetClass="org.fdroid.fdroid.AboutActivity"/>
</PreferenceScreen>
<PreferenceCategory android:title="@string/preference_category__my_apps"> <PreferenceCategory android:title="@string/preference_category__my_apps">
<PreferenceScreen android:title="@string/preference_manage_installed_apps"> <PreferenceScreen android:title="@string/preference_manage_installed_apps">
@ -47,7 +42,7 @@
android:title="@string/over_data" android:title="@string/over_data"
android:defaultValue="@integer/defaultOverData" android:defaultValue="@integer/defaultOverData"
android:layout="@layout/preference_seekbar"/> android:layout="@layout/preference_seekbar"/>
<SwitchPreference <SwitchPreferenceCompat
android:title="@string/update_auto_download" android:title="@string/update_auto_download"
android:summary="@string/update_auto_download_summary" android:summary="@string/update_auto_download_summary"
android:key="updateAutoDownload"/> android:key="updateAutoDownload"/>
@ -56,7 +51,7 @@
android:title="@string/update_interval" android:title="@string/update_interval"
android:defaultValue="@integer/defaultUpdateInterval" android:defaultValue="@integer/defaultUpdateInterval"
android:layout="@layout/preference_seekbar"/> android:layout="@layout/preference_seekbar"/>
<SwitchPreference <SwitchPreferenceCompat
android:title="@string/notify" android:title="@string/notify"
android:defaultValue="true" android:defaultValue="true"
android:key="updateNotify"/> android:key="updateNotify"/>
@ -77,26 +72,26 @@
<PreferenceCategory android:title="@string/appcompatibility" <PreferenceCategory android:title="@string/appcompatibility"
android:key="pref_category_appcompatibility"> android:key="pref_category_appcompatibility">
<SwitchPreference <SwitchPreferenceCompat
android:title="@string/show_incompat_versions" android:title="@string/show_incompat_versions"
android:defaultValue="false" android:defaultValue="false"
android:key="incompatibleVersions"/> android:key="incompatibleVersions"/>
<SwitchPreference <SwitchPreferenceCompat
android:title="@string/show_anti_feature_apps" android:title="@string/show_anti_feature_apps"
android:defaultValue="false" android:defaultValue="false"
android:key="showAntiFeatureApps"/> android:key="showAntiFeatureApps"/>
<SwitchPreference <SwitchPreferenceCompat
android:title="@string/force_touch_apps" android:title="@string/force_touch_apps"
android:defaultValue="false" android:defaultValue="false"
android:key="ignoreTouchscreen"/> android:key="ignoreTouchscreen"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/proxy"> <PreferenceCategory android:title="@string/proxy">
<SwitchPreference <SwitchPreferenceCompat
android:key="useTor" android:key="useTor"
android:summary="@string/useTorSummary" android:summary="@string/useTorSummary"
android:title="@string/useTor"/> android:title="@string/useTor"/>
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="false"
android:key="enableProxy" android:key="enableProxy"
android:title="@string/enable_proxy_title" android:title="@string/enable_proxy_title"
@ -116,12 +111,12 @@
<PreferenceCategory <PreferenceCategory
android:key="pref_category_privacy" android:key="pref_category_privacy"
android:title="@string/privacy"> android:title="@string/privacy">
<SwitchPreference <SwitchPreferenceCompat
android:key="promptToSendCrashReports" android:key="promptToSendCrashReports"
android:title="@string/prompt_to_send_crash_reports" android:title="@string/prompt_to_send_crash_reports"
android:summary="@string/prompt_to_send_crash_reports_summary" android:summary="@string/prompt_to_send_crash_reports_summary"
android:defaultValue="true"/> android:defaultValue="true"/>
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="false"
android:key="preventScreenshots" android:key="preventScreenshots"
android:summary="@string/preventScreenshots_summary" android:summary="@string/preventScreenshots_summary"
@ -137,7 +132,7 @@
android:defaultValue="86400000" android:defaultValue="86400000"
android:entries="@array/keepCacheNames" android:entries="@array/keepCacheNames"
android:entryValues="@array/keepCacheValues"/> android:entryValues="@array/keepCacheValues"/>
<SwitchPreference <SwitchPreferenceCompat
android:title="@string/expert" android:title="@string/expert"
android:defaultValue="false" android:defaultValue="false"
android:key="expert"/> android:key="expert"/>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- This file should be outside of release manifest (in this case app/src/mock/Manifest.xml --> <!-- This file should be outside of release manifest (in this case app/src/mock/Manifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!--required to enable/disable system animations from the app itself during Espresso test runs--> <!--required to enable/disable system animations from the app itself during Espresso test runs-->
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE"/> <uses-permission android:name="android.permission.SET_ANIMATION_SCALE" />
</manifest> </manifest>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
* Copyright (C) 2010-2012 Ciaran Gultnieks * Copyright (C) 2010-2012 Ciaran Gultnieks
* Copyright (C) 2013-2017 Peter Serwylo * Copyright (C) 2013-2017 Peter Serwylo
@ -23,91 +24,128 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.fdroid.fdroid" package="org.fdroid.fdroid"
android:installLocation="auto"> android:installLocation="auto">
<uses-feature android:name="android.hardware.nfc" android:required="false"/> <uses-feature
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/> android:name="android.hardware.nfc"
<uses-feature android:name="android.hardware.usb.host" android:required="false"/> android:required="false" />
<uses-feature
android:name="android.hardware.bluetooth"
android:required="false" />
<uses-permission android:name="android.permission.INTERNET"/> <uses-feature
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> android:name="android.hardware.usb.host"
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> android:required="false" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.USB_PERMISSION"
android:maxSdkVersion="22"/> <!-- maybe unnecessary -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission
android:name="android.permission.USB_PERMISSION"
android:maxSdkVersion="22" /><!-- maybe unnecessary -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application> <application>
<activity <activity
android:label="@string/swap" android:name=".nearby.SwapWorkflowActivity"
android:name=".nearby.SwapWorkflowActivity" android:configChanges="orientation|keyboardHidden"
android:parentActivityName=".views.main.MainActivity" android:label="@string/swap"
android:launchMode="singleTask" android:launchMode="singleTask"
android:theme="@style/SwapTheme.Wizard" android:parentActivityName=".views.main.MainActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait">
android:configChanges="orientation|keyboardHidden">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity"/> android:value=".views.main.MainActivity" />
</activity> </activity>
<activity
android:name=".panic.PanicPreferencesActivity"
android:label="@string/panic_settings"
android:parentActivityName=".views.main.MainActivity">
<intent-filter>
<action android:name="info.guardianproject.panic.action.CONNECT" />
<action android:name="info.guardianproject.panic.action.DISCONNECT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity" />
</activity>
<activity
android:name=".panic.SelectInstalledAppsActivity"
android:parentActivityName=".panic.PanicPreferencesActivity" />
<activity
android:name=".panic.PanicResponderActivity"
android:noHistory="true"
android:theme="@android:style/Theme.NoDisplay">
<!-- this can never have launchMode singleTask or singleInstance! -->
<intent-filter>
<action android:name="info.guardianproject.panic.action.TRIGGER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".panic.ExitActivity"
android:theme="@android:style/Theme.NoDisplay" />
<activity
android:name=".panic.CalculatorActivity"
android:enabled="false"
android:icon="@mipmap/ic_calculator_launcher"
android:label="@string/hiding_calculator">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".nearby.WifiStateChangeReceiver"> <receiver android:name=".nearby.WifiStateChangeReceiver">
<intent-filter> <intent-filter>
<action android:name="android.net.wifi.STATE_CHANGE"/> <action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receiver.DeviceStorageReceiver"> <receiver android:name=".receiver.DeviceStorageReceiver">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.DEVICE_STORAGE_LOW"/> <action android:name="android.intent.action.DEVICE_STORAGE_LOW" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<service <receiver android:name=".nearby.UsbDeviceAttachedReceiver">
android:name=".nearby.WifiStateChangeService"
android:exported="false"/>
<service android:name=".nearby.SwapService"/>
<service
android:name=".nearby.LocalRepoService"
android:exported="false"/>
<service
android:name=".nearby.TreeUriScannerIntentService"
android:exported="false"/>
<service
android:name=".nearby.SDCardScannerService"
android:exported="false"/>
<receiver
android:name=".nearby.UsbDeviceAttachedReceiver">
<intent-filter> <intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter> </intent-filter>
<meta-data <meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter"/> android:resource="@xml/device_filter" />
</receiver> </receiver>
<receiver <receiver android:name=".nearby.UsbDeviceDetachedReceiver">
android:name=".nearby.UsbDeviceDetachedReceiver">
<intent-filter> <intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/> <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter> </intent-filter>
<meta-data <meta-data
android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"
android:resource="@xml/device_filter"/> android:resource="@xml/device_filter" />
</receiver> </receiver>
<receiver android:name=".nearby.UsbDeviceMediaMountedReceiver"> <receiver android:name=".nearby.UsbDeviceMediaMountedReceiver">
<intent-filter> <intent-filter>
@ -121,52 +159,20 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<activity <service
android:name=".panic.PanicPreferencesActivity" android:name=".nearby.WifiStateChangeService"
android:label="@string/panic_settings" android:exported="false" />
android:parentActivityName=".views.main.MainActivity"> <service android:name=".nearby.SwapService" />
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity"/>
<intent-filter> <service
<action android:name="info.guardianproject.panic.action.CONNECT"/> android:name=".nearby.LocalRepoService"
<action android:name="info.guardianproject.panic.action.DISCONNECT"/> android:exported="false" />
<service
<category android:name="android.intent.category.DEFAULT"/> android:name=".nearby.TreeUriScannerIntentService"
</intent-filter> android:exported="false" />
</activity> <service
<activity android:name=".nearby.SDCardScannerService"
android:name=".panic.SelectInstalledAppsActivity" android:exported="false" />
android:parentActivityName=".panic.PanicPreferencesActivity"/>
<activity
android:name=".panic.PanicResponderActivity"
android:noHistory="true"
android:theme="@android:style/Theme.NoDisplay">
<!-- this can never have launchMode singleTask or singleInstance! -->
<intent-filter>
<action android:name="info.guardianproject.panic.action.TRIGGER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name=".panic.ExitActivity"
android:theme="@android:style/Theme.NoDisplay"/>
<activity
android:name=".panic.CalculatorActivity"
android:enabled="false"
android:icon="@mipmap/ic_calculator_launcher"
android:label="@string/hiding_calculator"
android:theme="@style/AppThemeLight">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application> </application>

View File

@ -4,12 +4,13 @@ import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.text.TextUtils; import android.text.TextUtils;
import javax.jmdns.ServiceInfo;
import javax.jmdns.impl.util.ByteWrangler;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import javax.jmdns.ServiceInfo;
import javax.jmdns.impl.util.ByteWrangler;
/** /**
* The ServiceInfo class needs to be serialized in order to be sent as an Android broadcast. * The ServiceInfo class needs to be serialized in order to be sent as an Android broadcast.
* In order to make it Parcelable (or Serializable for that matter), there are some package-scope * In order to make it Parcelable (or Serializable for that matter), there are some package-scope

View File

@ -10,15 +10,17 @@ import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.Message; import android.os.Message;
import android.os.Process; import android.os.Process;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.nearby.peers.BluetoothPeer; import org.fdroid.fdroid.nearby.peers.BluetoothPeer;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/** /**
* Manage the {@link android.bluetooth.BluetoothAdapter}in a {@link HandlerThread}. * Manage the {@link android.bluetooth.BluetoothAdapter}in a {@link HandlerThread}.
* The start process is in {@link HandlerThread#onLooperPrepared()} so that it is * The start process is in {@link HandlerThread#onLooperPrepared()} so that it is

View File

@ -5,7 +5,7 @@ import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothSocket;
import android.util.Log; import android.util.Log;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import fi.iki.elonen.NanoHTTPD;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.nearby.httpish.Request; import org.fdroid.fdroid.nearby.httpish.Request;
import org.fdroid.fdroid.nearby.httpish.Response; import org.fdroid.fdroid.nearby.httpish.Response;
@ -20,6 +20,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import fi.iki.elonen.NanoHTTPD;
/** /**
* Act as a layer on top of LocalHTTPD server, by forwarding requests served * Act as a layer on top of LocalHTTPD server, by forwarding requests served
* over bluetooth to that server. * over bluetooth to that server.

View File

@ -10,9 +10,6 @@ import android.os.Process;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
@ -28,6 +25,9 @@ import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceInfo; import javax.jmdns.ServiceInfo;
import javax.jmdns.ServiceListener; import javax.jmdns.ServiceListener;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/** /**
* Manage {@link JmDNS} in a {@link HandlerThread}. The start process is in * Manage {@link JmDNS} in a {@link HandlerThread}. The start process is in
* {@link HandlerThread#onLooperPrepared()} so that it is always started before * {@link HandlerThread#onLooperPrepared()} so that it is always started before

View File

@ -35,11 +35,9 @@ package org.fdroid.fdroid.nearby;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoHTTPD.Response.IStatus;
import org.fdroid.fdroid.BuildConfig; import org.fdroid.fdroid.BuildConfig;
import javax.net.ssl.SSLServerSocketFactory;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -62,6 +60,11 @@ import java.util.Map;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.TimeZone; import java.util.TimeZone;
import javax.net.ssl.SSLServerSocketFactory;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoHTTPD.Response.IStatus;
/** /**
* A HTTP server for serving the files that are being swapped via WiFi, etc. * A HTTP server for serving the files that are being swapped via WiFi, etc.
* The only changes were to remove unneeded extras like {@code main()}, the * The only changes were to remove unneeded extras like {@code main()}, the

View File

@ -6,8 +6,8 @@ import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.Message; import android.os.Message;
import android.os.Process; import android.os.Process;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.util.Log; import android.util.Log;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
@ -15,6 +15,8 @@ import java.io.IOException;
import java.net.BindException; import java.net.BindException;
import java.util.Random; import java.util.Random;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/** /**
* Manage {@link LocalHTTPD} in a {@link HandlerThread}; * Manage {@link LocalHTTPD} in a {@link HandlerThread};
*/ */

View File

@ -2,7 +2,7 @@ package org.fdroid.fdroid.nearby;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import kellinwood.security.zipsigner.ZipSigner;
import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralName;
@ -19,9 +19,6 @@ import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.X509KeyManager;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -49,6 +46,12 @@ import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.Locale; import java.util.Locale;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.X509KeyManager;
import kellinwood.security.zipsigner.ZipSigner;
// TODO Address exception handling in a uniform way throughout // TODO Address exception handling in a uniform way throughout
@SuppressWarnings("LineLength") @SuppressWarnings("LineLength")

View File

@ -12,8 +12,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Hasher; import org.fdroid.fdroid.Hasher;
import org.fdroid.fdroid.IndexUpdater; import org.fdroid.fdroid.IndexUpdater;
@ -50,6 +49,9 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/** /**
* The {@link SwapService} deals with managing the entire workflow from selecting apps to * The {@link SwapService} deals with managing the entire workflow from selecting apps to
* swap, to invoking this class to prepare the webroot, to enabling various communication protocols. * swap, to invoking this class to prepare the webroot, to enabling various communication protocols.

View File

@ -4,7 +4,7 @@ import android.app.IntentService;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Process; import android.os.Process;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
@ -15,6 +15,8 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/** /**
* Handles setting up and generating the local repo used to swap apps, including * Handles setting up and generating the local repo used to swap apps, including
* the {@code index.jar}, the symlinks to the shared APKs, etc. * the {@code index.jar}, the symlinks to the shared APKs, etc.

View File

@ -29,7 +29,7 @@ import android.os.Build;
import android.os.Environment; import android.os.Environment;
import android.os.Process; import android.os.Process;
import android.util.Log; import android.util.Log;
import androidx.core.content.ContextCompat;
import org.fdroid.fdroid.IndexUpdater; import org.fdroid.fdroid.IndexUpdater;
import org.fdroid.fdroid.IndexV1Updater; import org.fdroid.fdroid.IndexV1Updater;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
@ -44,6 +44,8 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import androidx.core.content.ContextCompat;
/** /**
* An {@link IntentService} subclass for scanning removable "external storage" * An {@link IntentService} subclass for scanning removable "external storage"
* for F-Droid package repos, e.g. SD Cards. This is intended to support * for F-Droid package repos, e.g. SD Cards. This is intended to support

View File

@ -4,7 +4,6 @@ import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@ -21,6 +20,10 @@ import android.widget.ImageView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.InstalledAppProvider;
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
@ -29,10 +32,6 @@ import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader; import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader; import androidx.loader.content.Loader;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.InstalledAppProvider;
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
public class SelectAppsView extends SwapView implements LoaderManager.LoaderCallbacks<Cursor> { public class SelectAppsView extends SwapView implements LoaderManager.LoaderCallbacks<Cursor> {
public SelectAppsView(Context context) { public SelectAppsView(Context context) {
@ -200,8 +199,6 @@ public class SelectAppsView extends SwapView implements LoaderManager.LoaderCall
} }
}); });
} }
updateCheckedIndicatorView(view, listView.isItemChecked(listPosition));
} }
public void updateCheckedIndicatorView(int position, boolean checked) { public void updateCheckedIndicatorView(int position, boolean checked) {
@ -210,24 +207,6 @@ public class SelectAppsView extends SwapView implements LoaderManager.LoaderCall
if (position >= firstListItemPosition && position <= lastListItemPosition) { if (position >= firstListItemPosition && position <= lastListItemPosition) {
final int childIndex = position - firstListItemPosition; final int childIndex = position - firstListItemPosition;
updateCheckedIndicatorView(listView.getChildAt(childIndex), checked);
}
}
private void updateCheckedIndicatorView(View view, boolean checked) {
ImageView imageView = (ImageView) view.findViewById(R.id.checked);
if (imageView != null) {
int resource;
int colour;
if (checked) {
resource = R.drawable.ic_check_circle;
colour = ContextCompat.getColor(getContext(), R.color.swap_bright_blue);
} else {
resource = R.drawable.ic_add_circle_outline;
colour = 0xFFD0D0D4;
}
imageView.setImageDrawable(ContextCompat.getDrawable(getContext(), resource));
imageView.setColorFilter(colour, PorterDuff.Mode.MULTIPLY);
} }
} }
} }

View File

@ -20,11 +20,6 @@ import android.widget.ListView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
@ -32,6 +27,10 @@ import org.fdroid.fdroid.nearby.peers.Peer;
import java.util.ArrayList; import java.util.ArrayList;
import androidx.annotation.Nullable;
import com.google.android.material.switchmaterial.SwitchMaterial;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import cc.mvdan.accesspoint.WifiApControl; import cc.mvdan.accesspoint.WifiApControl;
@SuppressWarnings("LineLength") @SuppressWarnings("LineLength")
@ -80,7 +79,7 @@ public class StartSwapView extends SwapView {
@Nullable /* Emulators typically don't have bluetooth adapters */ @Nullable /* Emulators typically don't have bluetooth adapters */
private final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter(); private final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
private SwitchCompat bluetoothSwitch; private SwitchMaterial bluetoothSwitch;
private TextView viewBluetoothId; private TextView viewBluetoothId;
private TextView textBluetoothVisible; private TextView textBluetoothVisible;
private TextView viewWifiId; private TextView viewWifiId;
@ -176,7 +175,7 @@ public class StartSwapView extends SwapView {
textBluetoothVisible = findViewById(R.id.bluetooth_visible); textBluetoothVisible = findViewById(R.id.bluetooth_visible);
bluetoothSwitch = (SwitchCompat) findViewById(R.id.switch_bluetooth); bluetoothSwitch = (SwitchMaterial) findViewById(R.id.switch_bluetooth);
bluetoothSwitch.setOnCheckedChangeListener(onBluetoothSwitchToggled); bluetoothSwitch.setOnCheckedChangeListener(onBluetoothSwitchToggled);
bluetoothSwitch.setChecked(SwapService.getBluetoothVisibleUserPreference()); bluetoothSwitch.setChecked(SwapService.getBluetoothVisibleUserPreference());
bluetoothSwitch.setEnabled(true); bluetoothSwitch.setEnabled(true);

View File

@ -1,6 +1,5 @@
package org.fdroid.fdroid.nearby; package org.fdroid.fdroid.nearby;
import android.annotation.SuppressLint;
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
@ -13,17 +12,17 @@ import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.IBinder; import android.os.IBinder;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.core.app.ServiceCompat; import androidx.core.app.ServiceCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import cc.mvdan.accesspoint.WifiApControl;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.NotificationHelper; import org.fdroid.fdroid.NotificationHelper;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
@ -36,7 +35,6 @@ import org.fdroid.fdroid.data.Schema;
import org.fdroid.fdroid.nearby.peers.Peer; import org.fdroid.fdroid.nearby.peers.Peer;
import org.fdroid.fdroid.net.Downloader; import org.fdroid.fdroid.net.Downloader;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
@ -47,6 +45,12 @@ import java.util.Set;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import cc.mvdan.accesspoint.WifiApControl;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
/** /**
* Central service which manages all of the different moving parts of swap which are required * Central service which manages all of the different moving parts of swap which are required
* to enable p2p swapping of apps. * to enable p2p swapping of apps.
@ -107,46 +111,6 @@ public class SwapService extends Service {
UpdateService.updateRepoNow(this, peer.getRepoAddress()); UpdateService.updateRepoNow(this, peer.getRepoAddress());
} }
@SuppressLint("StaticFieldLeak")
private void askServerToSwapWithUs(final Repo repo) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... args) {
String swapBackUri = Utils.getLocalRepoUri(FDroidApp.repo).toString();
HttpURLConnection conn = null;
try {
URL url = new URL(repo.address.replace("/fdroid/repo", "/request-swap"));
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream outputStream = conn.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(outputStream);
writer.write("repo=" + swapBackUri);
writer.flush();
writer.close();
outputStream.close();
int responseCode = conn.getResponseCode();
Utils.debugLog(TAG, "Asking server at " + repo.address + " to swap with us in return (by " +
"POSTing to \"/request-swap\" with repo \"" + swapBackUri + "\"): " + responseCode);
} catch (IOException e) {
Log.e(TAG, "Error while asking server to swap with us", e);
Intent intent = new Intent(Downloader.ACTION_INTERRUPTED);
intent.setData(Uri.parse(repo.address));
intent.putExtra(Downloader.EXTRA_ERROR_MESSAGE, e.getLocalizedMessage());
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
} finally {
if (conn != null) {
conn.disconnect();
}
}
return null;
}
}.execute();
}
private Repo ensureRepoExists(@NonNull Peer peer) { private Repo ensureRepoExists(@NonNull Peer peer) {
// TODO: newRepoConfig.getParsedUri() will include a fingerprint, which may not match with // TODO: newRepoConfig.getParsedUri() will include a fingerprint, which may not match with
// the repos address in the database. Not sure on best behaviour in this situation. // the repos address in the database. Not sure on best behaviour in this situation.
@ -340,12 +304,15 @@ public class SwapService extends Service {
@Nullable @Nullable
private Timer timer; private Timer timer;
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
public class Binder extends android.os.Binder { public class Binder extends android.os.Binder {
public SwapService getService() { public SwapService getService() {
return SwapService.this; return SwapService.this;
} }
} }
@Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
startForeground(NOTIFICATION, createNotification()); startForeground(NOTIFICATION, createNotification());
@ -395,6 +362,45 @@ public class SwapService extends Service {
BonjourManager.setVisible(this, getWifiVisibleUserPreference() || getHotspotActivatedUserPreference()); BonjourManager.setVisible(this, getWifiVisibleUserPreference() || getHotspotActivatedUserPreference());
} }
private void askServerToSwapWithUs(final Repo repo) {
compositeDisposable.add(
Completable.fromAction(() -> {
String swapBackUri = Utils.getLocalRepoUri(FDroidApp.repo).toString();
HttpURLConnection conn = null;
try {
URL url = new URL(repo.address.replace("/fdroid/repo", "/request-swap"));
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
try (OutputStream outputStream = conn.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(outputStream)) {
writer.write("repo=" + swapBackUri);
writer.flush();
}
int responseCode = conn.getResponseCode();
Utils.debugLog(TAG, "Asking server at " + repo.address + " to swap with us in return (by " +
"POSTing to \"/request-swap\" with repo \"" + swapBackUri + "\"): " + responseCode);
} finally {
if (conn != null) {
conn.disconnect();
}
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(e -> {
Intent intent = new Intent(Downloader.ACTION_INTERRUPTED);
intent.setData(Uri.parse(repo.address));
intent.putExtra(Downloader.EXTRA_ERROR_MESSAGE, e.getLocalizedMessage());
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
})
.subscribe()
);
}
/** /**
* This is for setting things up for when the {@code SwapService} was * This is for setting things up for when the {@code SwapService} was
* started by the user clicking on the initial start button. The things * started by the user clicking on the initial start button. The things
@ -418,6 +424,8 @@ public class SwapService extends Service {
@Override @Override
public void onDestroy() { public void onDestroy() {
compositeDisposable.dispose();
Utils.debugLog(TAG, "Destroying service, will disable swapping if required, and unregister listeners."); Utils.debugLog(TAG, "Destroying service, will disable swapping if required, and unregister listeners.");
Preferences.get().unregisterLocalRepoHttpsListeners(httpsEnabledListener); Preferences.get().unregisterLocalRepoHttpsListeners(httpsEnabledListener);
localBroadcastManager.unregisterReceiver(onWifiChange); localBroadcastManager.unregisterReceiver(onWifiChange);

View File

@ -1,7 +1,6 @@
package org.fdroid.fdroid.nearby; package org.fdroid.fdroid.nearby;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
@ -12,14 +11,6 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.cursoradapter.widget.CursorAdapter;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
@ -32,7 +23,9 @@ import android.widget.ListView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService; import org.fdroid.fdroid.UpdateService;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
@ -49,6 +42,16 @@ import org.fdroid.fdroid.net.DownloaderService;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.cursoradapter.widget.CursorAdapter;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/** /**
* This is a view that shows a listing of all apps in the swap repo that this * This is a view that shows a listing of all apps in the swap repo that this
* just connected to. The app listing and search should be replaced by * just connected to. The app listing and search should be replaced by

View File

@ -6,12 +6,12 @@ import android.content.res.TypedArray;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import org.fdroid.fdroid.R;
import androidx.annotation.ColorInt; import androidx.annotation.ColorInt;
import androidx.annotation.LayoutRes; import androidx.annotation.LayoutRes;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import org.fdroid.fdroid.R;
/** /**
* A {@link android.view.View} that registers to handle the swap events from * A {@link android.view.View} that registers to handle the swap events from
* {@link SwapService}. * {@link SwapService}.

View File

@ -1,7 +1,6 @@
package org.fdroid.fdroid.nearby; package org.fdroid.fdroid.nearby;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import androidx.appcompat.app.AppCompatActivity;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
@ -42,11 +41,11 @@ import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.SwitchCompat;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult; import com.google.zxing.integration.android.IntentResult;
@ -66,7 +65,6 @@ import org.fdroid.fdroid.net.BluetoothDownloader;
import org.fdroid.fdroid.net.Downloader; import org.fdroid.fdroid.net.Downloader;
import org.fdroid.fdroid.net.HttpDownloader; import org.fdroid.fdroid.net.HttpDownloader;
import org.fdroid.fdroid.qr.CameraCharacteristicsChecker; import org.fdroid.fdroid.qr.CameraCharacteristicsChecker;
import org.fdroid.fdroid.qr.QrGenAsyncTask;
import org.fdroid.fdroid.views.main.MainActivity; import org.fdroid.fdroid.views.main.MainActivity;
import java.util.Date; import java.util.Date;
@ -78,6 +76,7 @@ import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import cc.mvdan.accesspoint.WifiApControl; import cc.mvdan.accesspoint.WifiApControl;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import static org.fdroid.fdroid.views.main.MainActivity.ACTION_REQUEST_SWAP; import static org.fdroid.fdroid.views.main.MainActivity.ACTION_REQUEST_SWAP;
@ -107,7 +106,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private static final int REQUEST_WRITE_SETTINGS_PERMISSION = 5; private static final int REQUEST_WRITE_SETTINGS_PERMISSION = 5;
private static final int STEP_INTRO = 1; // TODO remove this special case, only use layoutResIds private static final int STEP_INTRO = 1; // TODO remove this special case, only use layoutResIds
private Toolbar toolbar; private MaterialToolbar toolbar;
private SwapView currentView; private SwapView currentView;
private boolean hasPreparedLocalRepo; private boolean hasPreparedLocalRepo;
private boolean newIntent; private boolean newIntent;
@ -120,6 +119,8 @@ public class SwapWorkflowActivity extends AppCompatActivity {
@LayoutRes @LayoutRes
private int currentSwapViewLayoutRes = STEP_INTRO; private int currentSwapViewLayoutRes = STEP_INTRO;
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
public static void requestSwap(Context context, String repo) { public static void requestSwap(Context context, String repo) {
requestSwap(context, Uri.parse(repo)); requestSwap(context, Uri.parse(repo));
} }
@ -201,7 +202,11 @@ public class SwapWorkflowActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
((FDroidApp) getApplication()).setSecureWindow(this); FDroidApp fdroidApp = (FDroidApp) getApplication();
fdroidApp.setSecureWindow(this);
fdroidApp.applyPureBlackBackgroundInDarkTheme(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
currentView = new SwapView(this); // dummy placeholder to avoid NullPointerExceptions; currentView = new SwapView(this); // dummy placeholder to avoid NullPointerExceptions;
@ -214,10 +219,8 @@ public class SwapWorkflowActivity extends AppCompatActivity {
setContentView(R.layout.swap_activity); setContentView(R.layout.swap_activity);
toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar = findViewById(R.id.toolbar);
toolbar.setTitleTextAppearance(getApplicationContext(), R.style.SwapTheme_Wizard_Text_Toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
container = (ViewGroup) findViewById(R.id.container); container = (ViewGroup) findViewById(R.id.container);
@ -235,6 +238,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
compositeDisposable.dispose();
localBroadcastManager.unregisterReceiver(downloaderInterruptedReceiver); localBroadcastManager.unregisterReceiver(downloaderInterruptedReceiver);
unbindService(serviceConnection); unbindService(serviceConnection);
super.onDestroy(); super.onDestroy();
@ -495,7 +499,6 @@ public class SwapWorkflowActivity extends AppCompatActivity {
currentView.setLayoutResId(viewRes); currentView.setLayoutResId(viewRes);
currentSwapViewLayoutRes = viewRes; currentSwapViewLayoutRes = viewRes;
toolbar.setBackgroundColor(currentView.getToolbarColour());
toolbar.setTitle(currentView.getToolbarTitle()); toolbar.setTitle(currentView.getToolbarTitle());
toolbar.setNavigationOnClickListener(new View.OnClickListener() { toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override @Override
@ -776,7 +779,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private final BroadcastReceiver bluetoothScanModeChanged = new BroadcastReceiver() { private final BroadcastReceiver bluetoothScanModeChanged = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
SwitchCompat bluetoothSwitch = container.findViewById(R.id.switch_bluetooth); SwitchMaterial bluetoothSwitch = container.findViewById(R.id.switch_bluetooth);
TextView textBluetoothVisible = container.findViewById(R.id.bluetooth_visible); TextView textBluetoothVisible = container.findViewById(R.id.bluetooth_visible);
if (bluetoothSwitch == null || textBluetoothVisible == null if (bluetoothSwitch == null || textBluetoothVisible == null
|| !BluetoothManager.ACTION_STATUS.equals(intent.getAction())) { || !BluetoothManager.ACTION_STATUS.equals(intent.getAction())) {
@ -930,18 +933,23 @@ public class SwapWorkflowActivity extends AppCompatActivity {
ImageView qrImage = container.findViewById(R.id.wifi_qr_code); ImageView qrImage = container.findViewById(R.id.wifi_qr_code);
if (qrUriString != null && qrImage != null) { if (qrUriString != null && qrImage != null) {
Utils.debugLog(TAG, "Encoded swap URI in QR Code: " + qrUriString); Utils.debugLog(TAG, "Encoded swap URI in QR Code: " + qrUriString);
new QrGenAsyncTask(SwapWorkflowActivity.this, R.id.wifi_qr_code).execute(qrUriString);
// Replace all blacks with the background blue. compositeDisposable.add(Utils.generateQrBitmap(this, qrUriString)
qrImage.setColorFilter(new LightingColorFilter(0xffffffff, ContextCompat.getColor(this, .subscribe(qrBitmap -> {
R.color.swap_blue))); qrImage.setImageBitmap(qrBitmap);
final View qrWarningMessage = container.findViewById(R.id.warning_qr_scanner); // Replace all blacks with the background blue.
if (CameraCharacteristicsChecker.getInstance(this).hasAutofocus()) { qrImage.setColorFilter(new LightingColorFilter(0xffffffff,
qrWarningMessage.setVisibility(View.GONE); ContextCompat.getColor(this, R.color.swap_blue)));
} else {
qrWarningMessage.setVisibility(View.VISIBLE); final View qrWarningMessage = container.findViewById(R.id.warning_qr_scanner);
} if (CameraCharacteristicsChecker.getInstance(this).hasAutofocus()) {
qrWarningMessage.setVisibility(View.GONE);
} else {
qrWarningMessage.setVisibility(View.VISIBLE);
}
})
);
} }
} }
@ -988,7 +996,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
} }
}); });
SwitchCompat wifiSwitch = findViewById(R.id.switch_wifi); SwitchMaterial wifiSwitch = findViewById(R.id.switch_wifi);
wifiSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { wifiSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@ -1112,7 +1120,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private final BroadcastReceiver bluetoothStatus = new BroadcastReceiver() { private final BroadcastReceiver bluetoothStatus = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
SwitchCompat bluetoothSwitch = container.findViewById(R.id.switch_bluetooth); SwitchMaterial bluetoothSwitch = container.findViewById(R.id.switch_bluetooth);
TextView textBluetoothVisible = container.findViewById(R.id.bluetooth_visible); TextView textBluetoothVisible = container.findViewById(R.id.bluetooth_visible);
TextView textDeviceIdBluetooth = container.findViewById(R.id.device_id_bluetooth); TextView textDeviceIdBluetooth = container.findViewById(R.id.device_id_bluetooth);
TextView peopleNearbyText = container.findViewById(R.id.text_people_nearby); TextView peopleNearbyText = container.findViewById(R.id.text_people_nearby);

View File

@ -29,7 +29,7 @@ import android.os.Build;
import android.os.Process; import android.os.Process;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import androidx.documentfile.provider.DocumentFile;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.fdroid.fdroid.AddRepoIntentService; import org.fdroid.fdroid.AddRepoIntentService;
@ -49,6 +49,8 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.jar.JarInputStream; import java.util.jar.JarInputStream;
import androidx.documentfile.provider.DocumentFile;
/** /**
* An {@link IntentService} subclass for handling asynchronous scanning of a * An {@link IntentService} subclass for handling asynchronous scanning of a
* removable storage device like an SD Card or USB OTG thumb drive using the * removable storage device like an SD Card or USB OTG thumb drive using the

View File

@ -8,13 +8,13 @@ import android.os.Build;
import android.os.storage.StorageManager; import android.os.storage.StorageManager;
import android.provider.DocumentsContract; import android.provider.DocumentsContract;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import java.io.File; import java.io.File;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
/** /**
* @see <a href="https://stackoverflow.com/a/36162691">Android 5.0 DocumentFile from tree URI</a> * @see <a href="https://stackoverflow.com/a/36162691">Android 5.0 DocumentFile from tree URI</a>

View File

@ -31,9 +31,11 @@ import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.annotation.RequiresApi;
import org.fdroid.fdroid.views.main.NearbyViewBinder; import org.fdroid.fdroid.views.main.NearbyViewBinder;
import androidx.annotation.RequiresApi;
/** /**
* This is just a shim to receive {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED} * This is just a shim to receive {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED}

View File

@ -29,11 +29,13 @@ import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.annotation.RequiresApi;
import org.fdroid.fdroid.views.main.NearbyViewBinder; import org.fdroid.fdroid.views.main.NearbyViewBinder;
import java.util.HashMap; import java.util.HashMap;
import androidx.annotation.RequiresApi;
/** /**
* This is just a shim to receive {@link UsbManager#ACTION_USB_DEVICE_DETACHED} * This is just a shim to receive {@link UsbManager#ACTION_USB_DEVICE_DETACHED}
* events. * events.

View File

@ -4,6 +4,7 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Environment; import android.os.Environment;
import org.fdroid.fdroid.views.main.NearbyViewBinder; import org.fdroid.fdroid.views.main.NearbyViewBinder;
public class UsbDeviceMediaMountedReceiver extends BroadcastReceiver { public class UsbDeviceMediaMountedReceiver extends BroadcastReceiver {

View File

@ -4,6 +4,7 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
public class WifiStateChangeReceiver extends BroadcastReceiver { public class WifiStateChangeReceiver extends BroadcastReceiver {

View File

@ -10,12 +10,13 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo; import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.Build; import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
import cc.mvdan.accesspoint.WifiApControl;
import org.apache.commons.net.util.SubnetUtils; import org.apache.commons.net.util.SubnetUtils;
import org.fdroid.fdroid.BuildConfig; import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
@ -34,6 +35,9 @@ import java.security.cert.Certificate;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Locale; import java.util.Locale;
import cc.mvdan.accesspoint.WifiApControl;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
/** /**
* Handle state changes to the device's wifi, storing the required bits. * Handle state changes to the device's wifi, storing the required bits.
* The {@link Intent} that starts it either has no extras included, * The {@link Intent} that starts it either has no extras included,
@ -68,6 +72,8 @@ public class WifiStateChangeService extends IntentService {
private static int previousWifiState = Integer.MIN_VALUE; private static int previousWifiState = Integer.MIN_VALUE;
private static int wifiState; private static int wifiState;
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
public WifiStateChangeService() { public WifiStateChangeService() {
super("WifiStateChangeService"); super("WifiStateChangeService");
} }
@ -80,6 +86,12 @@ public class WifiStateChangeService extends IntentService {
context.startService(intent); context.startService(intent);
} }
@Override
public void onDestroy() {
compositeDisposable.dispose();
super.onDestroy();
}
@Override @Override
protected void onHandleIntent(Intent intent) { protected void onHandleIntent(Intent intent) {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_LOWEST); android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_LOWEST);
@ -107,7 +119,7 @@ public class WifiStateChangeService extends IntentService {
} }
if (Build.VERSION.SDK_INT < 21 && wifiState == WifiManager.WIFI_STATE_ENABLED) { if (Build.VERSION.SDK_INT < 21 && wifiState == WifiManager.WIFI_STATE_ENABLED) {
UpdateService.scheduleIfStillOnWifi(this); compositeDisposable.add(UpdateService.scheduleIfStillOnWifi(this).subscribe());
} }
} }
} }

View File

@ -5,10 +5,10 @@ import android.bluetooth.BluetoothDevice;
import android.os.Parcel; import android.os.Parcel;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.Nullable;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import androidx.annotation.Nullable;
public class BluetoothPeer implements Peer { public class BluetoothPeer implements Peer {
private static final String BLUETOOTH_NAME_TAG = "FDroid:"; private static final String BLUETOOTH_NAME_TAG = "FDroid:";

View File

@ -2,13 +2,15 @@ package org.fdroid.fdroid.nearby.peers;
import android.net.Uri; import android.net.Uri;
import android.os.Parcel; import android.os.Parcel;
import androidx.annotation.Nullable;
import android.text.TextUtils; import android.text.TextUtils;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import javax.jmdns.ServiceInfo; import javax.jmdns.ServiceInfo;
import javax.jmdns.impl.FDroidServiceInfo; import javax.jmdns.impl.FDroidServiceInfo;
import androidx.annotation.Nullable;
public class BonjourPeer extends WifiPeer { public class BonjourPeer extends WifiPeer {
private static final String TAG = "BonjourPeer"; private static final String TAG = "BonjourPeer";

View File

@ -1,6 +1,7 @@
package org.fdroid.fdroid.nearby.peers; package org.fdroid.fdroid.nearby.peers;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
/** /**

View File

@ -1,17 +1,21 @@
package org.fdroid.fdroid.panic; package org.fdroid.fdroid.panic;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.material.appbar.MaterialToolbar;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
/** /**
* A very hacky calculator which is barely functional. * A very hacky calculator which is barely functional.
* It is just meant to pass a very casual inspection. * It is just meant to pass a very casual inspection.
@ -35,10 +39,13 @@ public class CalculatorActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
FDroidApp fdroidApp = (FDroidApp) getApplication();
fdroidApp.applyPureBlackBackgroundInDarkTheme(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator); setContentView(R.layout.activity_calculator);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); MaterialToolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
textView = (TextView) findViewById(R.id.textView); textView = (TextView) findViewById(R.id.textView);

View File

@ -3,13 +3,13 @@ package org.fdroid.fdroid.panic;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.preference.CheckBoxPreference; import androidx.preference.CheckBoxPreference;
import androidx.preference.PreferenceViewHolder; import androidx.preference.PreferenceViewHolder;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R;
public class DestructiveCheckBoxPreference extends CheckBoxPreference { public class DestructiveCheckBoxPreference extends CheckBoxPreference {
public DestructiveCheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr) { public DestructiveCheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);

View File

@ -3,13 +3,13 @@ package org.fdroid.fdroid.panic;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder; import androidx.preference.PreferenceViewHolder;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R;
public class DestructivePreference extends Preference { public class DestructivePreference extends Preference {
public DestructivePreference(Context context, AttributeSet attrs, int defStyleAttr) { public DestructivePreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);

View File

@ -3,6 +3,7 @@ package org.fdroid.fdroid.panic;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
public class ExitActivity extends AppCompatActivity { public class ExitActivity extends AppCompatActivity {

View File

@ -7,12 +7,14 @@ import android.content.Intent;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo;
import androidx.core.app.NotificationManagerCompat;
import androidx.appcompat.app.AlertDialog;
import org.fdroid.fdroid.BuildConfig; import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.main.MainActivity; import org.fdroid.fdroid.views.main.MainActivity;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.NotificationManagerCompat;
/** /**
* This class is encapsulating all methods related to hiding the app from the launcher * This class is encapsulating all methods related to hiding the app from the launcher
* and restoring it. * and restoring it.

View File

@ -1,37 +1,32 @@
package org.fdroid.fdroid.panic; package org.fdroid.fdroid.panic;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.ActionBar; import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import com.google.android.material.appbar.MaterialToolbar;
import android.view.MenuItem;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import androidx.appcompat.app.AppCompatActivity;
public class PanicPreferencesActivity extends AppCompatActivity { public class PanicPreferencesActivity extends AppCompatActivity {
@Override @Override
public void onCreate(Bundle bundle) { public void onCreate(Bundle bundle) {
((FDroidApp) getApplication()).applyTheme(this); FDroidApp fdroidApp = (FDroidApp) getApplication();
fdroidApp.applyPureBlackBackgroundInDarkTheme(this);
super.onCreate(bundle); super.onCreate(bundle);
setContentView(R.layout.activity_panic_settings); setContentView(R.layout.activity_panic_settings);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); MaterialToolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() {
ActionBar ab = getSupportActionBar(); @Override
if (ab != null) { public void onClick(View view) {
ab.setDisplayShowHomeEnabled(true); // Handle navigation icon press
ab.setDisplayHomeAsUpEnabled(true); onBackPressed();
} }
});
} }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
} }

View File

@ -1,6 +1,5 @@
package org.fdroid.fdroid.panic; package org.fdroid.fdroid.panic;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
@ -16,16 +15,6 @@ import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.TypedValue; import android.util.TypedValue;
import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.preference.CheckBoxPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.installer.PrivilegedInstaller; import org.fdroid.fdroid.installer.PrivilegedInstaller;
@ -33,6 +22,16 @@ import org.fdroid.fdroid.installer.PrivilegedInstaller;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Set; import java.util.Set;
import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.preference.CheckBoxPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import info.guardianproject.panic.Panic; import info.guardianproject.panic.Panic;
import info.guardianproject.panic.PanicResponder; import info.guardianproject.panic.PanicResponder;

View File

@ -1,17 +1,13 @@
package org.fdroid.fdroid.panic; package org.fdroid.fdroid.panic;
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log; import android.util.Log;
import info.guardianproject.panic.Panic;
import info.guardianproject.panic.PanicResponder;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.DBHelper; import org.fdroid.fdroid.data.DBHelper;
@ -31,6 +27,11 @@ import java.util.List;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import info.guardianproject.panic.Panic;
import info.guardianproject.panic.PanicResponder;
/** /**
* This {@link AppCompatActivity} is purely to run events in response to a panic trigger. * This {@link AppCompatActivity} is purely to run events in response to a panic trigger.
* It needs to be an {@code AppCompatActivity} rather than a {@link android.app.Service} * It needs to be an {@code AppCompatActivity} rather than a {@link android.app.Service}

View File

@ -1,9 +1,8 @@
package org.fdroid.fdroid.panic; package org.fdroid.fdroid.panic;
import androidx.appcompat.app.AppCompatActivity;
import androidx.annotation.NonNull;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.installed.InstalledAppListAdapter; import org.fdroid.fdroid.views.installed.InstalledAppListAdapter;
@ -11,6 +10,9 @@ import org.fdroid.fdroid.views.installed.InstalledAppListItemController;
import java.util.Set; import java.util.Set;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
public class SelectInstalledAppListAdapter extends InstalledAppListAdapter { public class SelectInstalledAppListAdapter extends InstalledAppListAdapter {
private final Set<String> selectedApps; private final Set<String> selectedApps;

View File

@ -1,9 +1,7 @@
package org.fdroid.fdroid.panic; package org.fdroid.fdroid.panic;
import androidx.appcompat.app.AppCompatActivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.View; import android.view.View;
import org.fdroid.fdroid.AppUpdateStatusManager; import org.fdroid.fdroid.AppUpdateStatusManager;
import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.views.apps.AppListItemState; import org.fdroid.fdroid.views.apps.AppListItemState;
@ -11,6 +9,10 @@ import org.fdroid.fdroid.views.installed.InstalledAppListItemController;
import java.util.Set; import java.util.Set;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
/** /**
* Shows the currently installed apps as a selectable list. * Shows the currently installed apps as a selectable list.
*/ */

View File

@ -27,15 +27,7 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import com.google.android.material.appbar.MaterialToolbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
@ -43,6 +35,14 @@ import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.InstalledAppProvider; import org.fdroid.fdroid.data.InstalledAppProvider;
import org.fdroid.fdroid.views.installed.InstalledAppListAdapter; import org.fdroid.fdroid.views.installed.InstalledAppListAdapter;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class SelectInstalledAppsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> { public class SelectInstalledAppsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private InstalledAppListAdapter adapter; private InstalledAppListAdapter adapter;
@ -54,13 +54,14 @@ public class SelectInstalledAppsActivity extends AppCompatActivity implements Lo
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
FDroidApp fdroidApp = (FDroidApp) getApplication();
fdroidApp.applyPureBlackBackgroundInDarkTheme(this);
((FDroidApp) getApplication()).applyTheme(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.installed_apps_layout); setContentView(R.layout.installed_apps_layout);
Toolbar toolbar = findViewById(R.id.toolbar); MaterialToolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(getString(R.string.panic_add_apps_to_uninstall)); toolbar.setTitle(getString(R.string.panic_add_apps_to_uninstall));
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);

View File

@ -6,15 +6,9 @@ import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService; import org.fdroid.fdroid.UpdateService;
@ -31,6 +25,15 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
/** /**
* Responsible for ensuring that the categories view is inflated and then populated correctly. * Responsible for ensuring that the categories view is inflated and then populated correctly.
* Will start a loader to get the list of categories from the database and populate a recycler * Will start a loader to get the list of categories from the database and populate a recycler

View File

@ -2,15 +2,15 @@ package org.fdroid.fdroid.views.main;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.PreferencesFragment;
import org.fdroid.fdroid.views.updates.UpdatesViewBinder;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.PreferencesFragment;
import org.fdroid.fdroid.views.updates.UpdatesViewBinder;
/** /**
* Decides which view on the main screen to attach to a given {@link FrameLayout}. This class * Decides which view on the main screen to attach to a given {@link FrameLayout}. This class
* doesn't know which view it will be rendering at the time it is constructed. Rather, at some * doesn't know which view it will be rendering at the time it is constructed. Rather, at some

View File

@ -1,7 +1,6 @@
package org.fdroid.fdroid.views.main; package org.fdroid.fdroid.views.main;
import android.Manifest; import android.Manifest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.UriPermission; import android.content.UriPermission;
@ -22,9 +21,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.nearby.SDCardScannerService; import org.fdroid.fdroid.nearby.SDCardScannerService;
@ -34,6 +31,11 @@ import org.fdroid.fdroid.nearby.TreeUriScannerIntentService;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
/** /**
* A splash screen encouraging people to start the swap process. The swap * A splash screen encouraging people to start the swap process. The swap
* process is quite heavy duty in that it fires up Bluetooth and/or WiFi * process is quite heavy duty in that it fires up Bluetooth and/or WiFi

View File

@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal"
tools:ignore="VectorRaster">
<path
android:fillColor="#FFFFFF"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM9.29,16.29L5.7,12.7c-0.39,-0.39 -0.39,-1.02 0,-1.41 0.39,-0.39 1.02,-0.39 1.41,0L10,14.17l6.88,-6.88c0.39,-0.39 1.02,-0.39 1.41,0 0.39,0.39 0.39,1.02 0,1.41l-7.59,7.59c-0.38,0.39 -1.02,0.39 -1.41,0z"/>
</vector>

View File

@ -1,19 +1,33 @@
<vector android:height="24dp" android:viewportHeight="48.0" <vector android:height="24dp"
android:viewportHeight="48.0"
android:tint="?attr/colorControlNormal" android:tint="?attr/colorControlNormal"
android:viewportWidth="48.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:viewportWidth="48.0"
<path android:fillColor="#ffffff" android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="#ffffff"
android:pathData="m22.75,12.78c-6.19,0 -11.22,5.03 -11.22,11.22 0,0.55 0.05,1.08 0.13,1.61 1.71,0.27 3.29,0.93 4.64,1.91 -0.57,-1.05 -0.9,-2.24 -0.9,-3.52 0,-4.05 3.3,-7.35 7.35,-7.35 4.05,0 7.35,3.3 7.35,7.35 0,4.05 -3.3,7.35 -7.35,7.35 -1.38,0 -2.66,-0.39 -3.77,-1.05 0.92,1.39 1.53,2.99 1.73,4.73 0.66,0.12 1.34,0.2 2.04,0.2 6.19,0 11.22,-5.03 11.22,-11.22 0,-6.19 -5.03,-11.22 -11.22,-11.22" android:pathData="m22.75,12.78c-6.19,0 -11.22,5.03 -11.22,11.22 0,0.55 0.05,1.08 0.13,1.61 1.71,0.27 3.29,0.93 4.64,1.91 -0.57,-1.05 -0.9,-2.24 -0.9,-3.52 0,-4.05 3.3,-7.35 7.35,-7.35 4.05,0 7.35,3.3 7.35,7.35 0,4.05 -3.3,7.35 -7.35,7.35 -1.38,0 -2.66,-0.39 -3.77,-1.05 0.92,1.39 1.53,2.99 1.73,4.73 0.66,0.12 1.34,0.2 2.04,0.2 6.19,0 11.22,-5.03 11.22,-11.22 0,-6.19 -5.03,-11.22 -11.22,-11.22"
android:strokeColor="#00000000" android:strokeWidth="1"/> android:strokeColor="#00000000"
<path android:fillColor="#ffffff" android:strokeWidth="1" />
<path
android:fillColor="#ffffff"
android:pathData="m42.28,25.4c-0.36,0 -0.71,-0.02 -1.06,-0.06 -0.69,9.6 -8.71,17.2 -18.48,17.2 -1.28,0 -2.53,-0.13 -3.74,-0.38 -0.83,1.26 -1.91,2.33 -3.18,3.15 2.18,0.71 4.5,1.1 6.91,1.1 12.03,0 21.87,-9.54 22.38,-21.45 -0.9,0.29 -1.85,0.44 -2.84,0.44" android:pathData="m42.28,25.4c-0.36,0 -0.71,-0.02 -1.06,-0.06 -0.69,9.6 -8.71,17.2 -18.48,17.2 -1.28,0 -2.53,-0.13 -3.74,-0.38 -0.83,1.26 -1.91,2.33 -3.18,3.15 2.18,0.71 4.5,1.1 6.91,1.1 12.03,0 21.87,-9.54 22.38,-21.45 -0.9,0.29 -1.85,0.44 -2.84,0.44"
android:strokeColor="#00000000" android:strokeWidth="1"/> android:strokeColor="#00000000"
<path android:fillColor="#ffffff" android:strokeWidth="1" />
<path
android:fillColor="#ffffff"
android:pathData="m42.28,10.64c-2.96,0 -5.36,2.41 -5.36,5.36 0,2.96 2.41,5.36 5.36,5.36 2.96,0 5.36,-2.41 5.36,-5.36 0,-2.96 -2.41,-5.36 -5.36,-5.36" android:pathData="m42.28,10.64c-2.96,0 -5.36,2.41 -5.36,5.36 0,2.96 2.41,5.36 5.36,5.36 2.96,0 5.36,-2.41 5.36,-5.36 0,-2.96 -2.41,-5.36 -5.36,-5.36"
android:strokeColor="#00000000" android:strokeWidth="1"/> android:strokeColor="#00000000"
<path android:fillColor="#ffffff" android:strokeWidth="1" />
<path
android:fillColor="#ffffff"
android:pathData="m10,29.5c-3.72,0 -6.75,3.03 -6.75,6.75 0,3.72 3.03,6.75 6.75,6.75 3.72,0 6.75,-3.03 6.75,-6.75 0,-3.72 -3.03,-6.75 -6.75,-6.75" android:pathData="m10,29.5c-3.72,0 -6.75,3.03 -6.75,6.75 0,3.72 3.03,6.75 6.75,6.75 3.72,0 6.75,-3.03 6.75,-6.75 0,-3.72 -3.03,-6.75 -6.75,-6.75"
android:strokeColor="#00000000" android:strokeWidth="1"/> android:strokeColor="#00000000"
<path android:fillAlpha="1" android:fillColor="#ffffff" android:strokeWidth="1" />
<path
android:fillAlpha="1"
android:fillColor="#ffffff"
android:pathData="m4.47,27.01c-0.16,-0.98 -0.25,-1.98 -0.25,-3.01 0,-10.22 8.31,-18.53 18.53,-18.53 4.68,0 8.97,1.75 12.23,4.63C35.81,9.08 36.85,8.24 38.03,7.64 34.02,3.9 28.65,1.6 22.75,1.6 10.4,1.6 0.35,11.65 0.35,24c0,2.1 0.3,4.13 0.84,6.05 0.87,-1.23 1.99,-2.27 3.28,-3.04" android:pathData="m4.47,27.01c-0.16,-0.98 -0.25,-1.98 -0.25,-3.01 0,-10.22 8.31,-18.53 18.53,-18.53 4.68,0 8.97,1.75 12.23,4.63C35.81,9.08 36.85,8.24 38.03,7.64 34.02,3.9 28.65,1.6 22.75,1.6 10.4,1.6 0.35,11.65 0.35,24c0,2.1 0.3,4.13 0.84,6.05 0.87,-1.23 1.99,-2.27 3.28,-3.04"
android:strokeColor="#00000000" android:strokeWidth="1"/> android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector> </vector>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/header" android:id="@+id/header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="130dp" android:layout_height="130dp"
@ -12,7 +13,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@drawable/swap_start_header"/> app:srcCompat="@drawable/swap_start_header"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -1,78 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingBottom="2dip"
android:paddingTop="2dip">
<ImageView
android:id="@android:id/icon"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
android:layout_marginTop="6dip"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
tools:src="@drawable/ic_launcher"
tools:ignore="ContentDescription" />
<!-- Suppress InconsistentLayout because the lower API levels use a checkbox rather than this -->
<ImageView
android:id="@+id/checked"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_marginRight="?attr/listPreferredItemPaddingLeft"
android:layout_marginEnd="?android:attr/listPreferredItemPaddingStart"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
tools:suppress="InconsistentLayout"
android:src="@drawable/ic_add_circle_outline" />
<TwoLineListItem
android:layout_toRightOf="@android:id/icon"
android:layout_toEndOf="@android:id/icon"
android:layout_toLeftOf="@id/checked"
android:layout_toStartOf="@id/checked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:mode="twoLine" >
<TextView
android:id="@+id/application_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
android:layout_marginTop="6dip"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="F-Droid" />
<TextView
android:id="@+id/package_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/application_label"
android:layout_alignLeft="@+id/application_label"
android:layout_below="@+id/application_label"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Application Manager" />
</TwoLineListItem>
</RelativeLayout>

View File

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingBottom="2dip"
android:paddingTop="2dip">
<ImageView
android:id="@android:id/icon"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
android:layout_marginTop="6dip"
android:layout_alignParentStart="true"
tools:src="@drawable/ic_launcher"
tools:ignore="ContentDescription" />
<!-- Suppress InconsistentLayout because the lower API levels use a checkbox rather than this -->
<ImageView
android:id="@+id/checked"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_marginEnd="?android:attr/listPreferredItemPaddingStart"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
tools:suppress="InconsistentLayout"
android:src="@drawable/ic_add_circle_outline" />
<TwoLineListItem
android:layout_toEndOf="@android:id/icon"
android:layout_toStartOf="@id/checked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:mode="twoLine" >
<TextView
android:id="@+id/application_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
android:layout_marginTop="6dip"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="F-Droid" />
<TextView
android:id="@+id/package_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/application_label"
android:layout_below="@+id/application_label"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Application Manager" />
</TwoLineListItem>
</RelativeLayout>

View File

@ -1,291 +1,302 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
tools:context=".panic.CalculatorActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:background="?attr/colorPrimary" tools:context=".panic.CalculatorActivity"
app:layout_constraintEnd_toEndOf="parent" android:fitsSystemWindows="true">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" <com.google.android.material.appbar.AppBarLayout
app:theme="?attr/actionBarTheme" /> android:id="@+id/topAppBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:liftOnScroll="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/ic_back"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
</com.google.android.material.appbar.AppBarLayout>
<TextView <TextView
android:id="@+id/textView" android:id="@+id/textView"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:gravity="bottom|end" android:gravity="bottom|end"
android:padding="5dp" android:padding="5dp"
android:textAlignment="textEnd" android:textAlignment="textEnd"
android:textSize="22sp" android:textSize="22sp"
android:typeface="monospace" android:typeface="monospace"
app:layout_constraintBottom_toTopOf="@+id/ce" app:layout_constraintBottom_toTopOf="@+id/ce"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" app:layout_constraintTop_toBottomOf="@+id/topAppBarLayout"
tools:text="1337+42" /> tools:text="1337+42" />
<Button <Button
android:id="@+id/times" android:id="@+id/times"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="op" android:onClick="op"
android:text="×" android:text="×"
app:layout_constraintBottom_toTopOf="@+id/seven" app:layout_constraintBottom_toTopOf="@+id/seven"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/divided" android:id="@+id/divided"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="op" android:onClick="op"
android:text="÷" android:text="÷"
app:layout_constraintBottom_toTopOf="@+id/eight" app:layout_constraintBottom_toTopOf="@+id/eight"
app:layout_constraintStart_toEndOf="@+id/times" app:layout_constraintStart_toEndOf="@+id/times"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/c" android:id="@+id/c"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="c" android:onClick="c"
android:text="C" android:text="C"
app:layout_constraintBottom_toTopOf="@+id/nine" app:layout_constraintBottom_toTopOf="@+id/nine"
app:layout_constraintStart_toEndOf="@+id/divided" app:layout_constraintStart_toEndOf="@+id/divided"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/seven" android:id="@+id/seven"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="7" android:text="7"
app:layout_constraintBottom_toTopOf="@+id/four" app:layout_constraintBottom_toTopOf="@+id/four"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/eight" android:id="@+id/eight"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="8" android:text="8"
app:layout_constraintBottom_toTopOf="@+id/five" app:layout_constraintBottom_toTopOf="@+id/five"
app:layout_constraintStart_toEndOf="@+id/seven" app:layout_constraintStart_toEndOf="@+id/seven"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/nine" android:id="@+id/nine"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="9" android:text="9"
app:layout_constraintBottom_toTopOf="@+id/six" app:layout_constraintBottom_toTopOf="@+id/six"
app:layout_constraintStart_toEndOf="@+id/eight" app:layout_constraintStart_toEndOf="@+id/eight"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/ce" android:id="@+id/ce"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="ce" android:onClick="ce"
android:text="CE" android:text="CE"
app:layout_constraintBottom_toTopOf="@+id/plus" app:layout_constraintBottom_toTopOf="@+id/plus"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nine" app:layout_constraintStart_toEndOf="@+id/nine"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/four" android:id="@+id/four"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="4" android:text="4"
app:layout_constraintBottom_toTopOf="@+id/one" app:layout_constraintBottom_toTopOf="@+id/one"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/five" android:id="@+id/five"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="5" android:text="5"
app:layout_constraintBottom_toTopOf="@+id/two" app:layout_constraintBottom_toTopOf="@+id/two"
app:layout_constraintStart_toEndOf="@+id/four" app:layout_constraintStart_toEndOf="@+id/four"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/six" android:id="@+id/six"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="6" android:text="6"
app:layout_constraintBottom_toTopOf="@+id/three" app:layout_constraintBottom_toTopOf="@+id/three"
app:layout_constraintStart_toEndOf="@+id/five" app:layout_constraintStart_toEndOf="@+id/five"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/plus" android:id="@+id/plus"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="op" android:onClick="op"
android:text="+" android:text="+"
app:layout_constraintBottom_toTopOf="@+id/minus" app:layout_constraintBottom_toTopOf="@+id/minus"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/six" app:layout_constraintStart_toEndOf="@+id/six"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/minus" android:id="@+id/minus"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="op" android:onClick="op"
android:text="-" android:text="-"
app:layout_constraintBottom_toTopOf="@+id/equals" app:layout_constraintBottom_toTopOf="@+id/equals"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/three" app:layout_constraintStart_toEndOf="@+id/three"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/one" android:id="@+id/one"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="1" android:text="1"
app:layout_constraintBottom_toTopOf="@+id/zero" app:layout_constraintBottom_toTopOf="@+id/zero"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/two" android:id="@+id/two"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="2" android:text="2"
app:layout_constraintBottom_toTopOf="@+id/comma" app:layout_constraintBottom_toTopOf="@+id/comma"
app:layout_constraintStart_toEndOf="@+id/one" app:layout_constraintStart_toEndOf="@+id/one"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/three" android:id="@+id/three"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="3" android:text="3"
app:layout_constraintBottom_toTopOf="@+id/percent" app:layout_constraintBottom_toTopOf="@+id/percent"
app:layout_constraintStart_toEndOf="@+id/two" app:layout_constraintStart_toEndOf="@+id/two"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/zero" android:id="@+id/zero"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="0" android:text="0"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/comma" android:id="@+id/comma"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="number" android:onClick="number"
android:text="." android:text="."
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/zero" app:layout_constraintStart_toEndOf="@+id/zero"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/percent" android:id="@+id/percent"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="op" android:onClick="op"
android:text="%" android:text="%"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/comma" app:layout_constraintStart_toEndOf="@+id/comma"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/equals" android:id="@+id/equals"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="op" android:onClick="op"
android:text="=" android:text="="
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/three" app:layout_constraintStart_toEndOf="@+id/three"
app:layout_constraintTop_toTopOf="@+id/three" app:layout_constraintTop_toTopOf="@+id/three"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,21 +1,32 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:background="?attr/colorPrimary" android:orientation="vertical"
app:theme="?attr/actionBarTheme" /> android:fitsSystemWindows="true">
<fragment xmlns:android="http://schemas.android.com/apk/res/android" <com.google.android.material.appbar.AppBarLayout
android:id="@+id/fragment_container" android:layout_width="match_parent"
class="org.fdroid.fdroid.panic.PanicPreferencesFragment" android:layout_height="wrap_content"
android:layout_width="match_parent" android:fitsSystemWindows="true"
android:layout_height="match_parent" /> app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/panic_settings"
app:navigationIcon="@drawable/ic_back"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
class="org.fdroid.fdroid.panic.PanicPreferencesFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout> </LinearLayout>

View File

@ -5,7 +5,8 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -16,7 +17,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<org.fdroid.fdroid.views.BannerUpdatingRepos <org.fdroid.fdroid.views.StatusBanner
android:id="@+id/banner_updating_repos" android:id="@+id/banner_updating_repos"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -11,7 +11,7 @@
android:id="@+id/image" android:id="@+id/image"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:src="@drawable/nearby_splash" app:srcCompat="@drawable/nearby_splash"
android:importantForAccessibility="no" android:importantForAccessibility="no"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"

View File

@ -16,7 +16,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight" android:minHeight="?attr/listPreferredItemHeight"
android:paddingBottom="2dip" android:paddingBottom="2dip"
android:paddingTop="2dip"> android:paddingTop="2dip">
@ -25,10 +25,9 @@
android:layout_width="48dip" android:layout_width="48dip"
android:layout_height="48dip" android:layout_height="48dip"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft" android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart" android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_marginTop="6dip" android:layout_marginTop="6dip"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
tools:src="@drawable/ic_launcher" tools:src="@drawable/ic_launcher"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
@ -37,15 +36,13 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft" android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart" android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_centerVertical="true" /> android:layout_centerVertical="true" />
<TwoLineListItem <TwoLineListItem
android:layout_toRightOf="@android:id/icon"
android:layout_toEndOf="@android:id/icon" android:layout_toEndOf="@android:id/icon"
android:layout_toLeftOf="@id/checkbox"
android:layout_toStartOf="@id/checkbox" android:layout_toStartOf="@id/checkbox"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -56,7 +53,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft" android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart" android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_marginTop="6dip" android:layout_marginTop="6dip"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="F-Droid" /> tools:text="F-Droid" />
@ -66,7 +63,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignStart="@+id/application_label" android:layout_alignStart="@+id/application_label"
android:layout_alignLeft="@+id/application_label"
android:layout_below="@+id/application_label" android:layout_below="@+id/application_label"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Application Manager" /> tools:text="Application Manager" />

View File

@ -1,24 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
<androidx.appcompat.widget.Toolbar android:fitsSystemWindows="true">
android:id="@+id/toolbar" <com.google.android.material.appbar.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:titleTextAppearance="@style/SwapTheme.Wizard.Text" android:layout_height="wrap_content"
titleTextAppearance="@style/SwapTheme.Wizard.Text" android:fitsSystemWindows="true"
android:minHeight="?attr/actionBarSize" app:liftOnScroll="true">
android:background="?attr/colorPrimary"
tools:ignore="UnusedAttribute"/> <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/ic_back"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout <FrameLayout
android:id="@+id/container" android:id="@+id/container"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent"/> android:layout_height="fill_parent" />
</LinearLayout> </LinearLayout>

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight" android:minHeight="?attr/listPreferredItemHeight"
android:paddingBottom="2dip" android:paddingBottom="2dip"
android:paddingTop="2dip"> android:paddingTop="2dip">
@ -12,7 +12,7 @@
android:id="@android:id/icon" android:id="@android:id/icon"
android:layout_width="48dip" android:layout_width="48dip"
android:layout_height="48dip" android:layout_height="48dip"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart" android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:layout_marginTop="6dip" android:layout_marginTop="6dip"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
@ -28,7 +28,7 @@
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:orientation="vertical" android:orientation="vertical"
android:gravity="end" android:gravity="end"
android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd" android:layout_marginEnd="?attr/listPreferredItemPaddingEnd"
android:layout_marginRight="10dp"> android:layout_marginRight="10dp">
<Button <Button
@ -68,7 +68,7 @@
android:layout_toLeftOf="@+id/button_or_text" android:layout_toLeftOf="@+id/button_or_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart" android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:layout_marginTop="6dip" android:layout_marginTop="6dip"
android:layout_marginBottom="6dip" android:layout_marginBottom="6dip"

View File

@ -14,7 +14,7 @@
<ImageView <ImageView
android:id="@+id/icon" android:id="@+id/icon"
android:src="@drawable/ic_launcher" swap:srcCompat="@drawable/ic_launcher"
android:contentDescription="@string/icon" android:contentDescription="@string/icon"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_width="117.6dp" android:layout_width="117.6dp"

View File

@ -25,7 +25,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/wifi_icon" android:id="@+id/wifi_icon"
android:src="@drawable/ic_wifi" swap:srcCompat="@drawable/ic_wifi"
android:layout_below="@+id/text_description" android:layout_below="@+id/text_description"
android:layout_centerHorizontal="true"/> android:layout_centerHorizontal="true"/>

View File

@ -14,7 +14,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/icon_nfc" android:id="@+id/icon_nfc"
android:src="@drawable/nfc_touch" swap:srcCompat="@drawable/nfc_touch"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/> android:layout_centerHorizontal="true"/>

View File

@ -14,13 +14,13 @@
android:layout_width="32dp" android:layout_width="32dp"
android:layout_height="32dp" android:layout_height="32dp"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft" android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart" android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:layout_gravity="center_vertical"> android:layout_gravity="center_vertical">
<ImageView <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:src="@drawable/circle" app:srcCompat="@drawable/circle"
app:tint="@color/swap_light_grey_icon"/> app:tint="@color/swap_light_grey_icon"/>
<ImageView <ImageView
@ -38,7 +38,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginLeft="?attr/listPreferredItemPaddingLeft" android:layout_marginLeft="?attr/listPreferredItemPaddingLeft"
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart" android:layout_marginStart="?attr/listPreferredItemPaddingStart"
android:textSize="20sp" android:textSize="20sp"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="Nexus 4"/> tools:text="Nexus 4"/>

View File

@ -26,7 +26,7 @@
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:contentDescription="@string/use_bluetooth" android:contentDescription="@string/use_bluetooth"
android:src="@drawable/ic_bluetooth_searching"/> swap:srcCompat="@drawable/ic_bluetooth_searching"/>
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
@ -53,7 +53,7 @@
</LinearLayout> </LinearLayout>
<androidx.appcompat.widget.SwitchCompat <com.google.android.material.switchmaterial.SwitchMaterial
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:enabled="false" android:enabled="false"
@ -74,7 +74,7 @@
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:contentDescription="@string/wifi" android:contentDescription="@string/wifi"
android:src="@drawable/ic_wifi"/> swap:srcCompat="@drawable/ic_wifi"/>
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
@ -110,7 +110,7 @@
</LinearLayout> </LinearLayout>
<androidx.appcompat.widget.SwitchCompat <com.google.android.material.switchmaterial.SwitchMaterial
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/switch_wifi"/> android:id="@+id/switch_wifi"/>
@ -155,7 +155,7 @@
<Button <Button
android:id="@+id/btn_send_fdroid" android:id="@+id/btn_send_fdroid"
style="@style/Widget.MaterialComponents.Button.TextButton" style="@style/Widget.App.Button.TextButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
swap:icon="@drawable/ic_fdroid_grey" swap:icon="@drawable/ic_fdroid_grey"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -163,7 +163,7 @@
<Button <Button
android:id="@+id/btn_scan_qr" android:id="@+id/btn_scan_qr"
style="@style/Widget.MaterialComponents.Button.TextButton" style="@style/Widget.App.Button.TextButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/swap_scan_qr" android:text="@string/swap_scan_qr"

View File

@ -1,22 +1,42 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:ignore="MenuTitle"> tools:ignore="MenuTitle">
<!-- android:title and android:icon are set dynamically in MainActivity --> <!-- android:title and android:icon are set dynamically in MainActivity -->
<item <item
app:showAsAction="ifRoom|withText" android:id="@+id/latest"
android:id="@+id/latest"/> android:enabled="true"
android:icon="@drawable/ic_latest"
android:orderInCategory="0"
android:title="@string/main_menu__latest_apps"
app:showAsAction="ifRoom|withText" />
<item <item
app:showAsAction="ifRoom|withText" android:id="@+id/categories"
android:id="@+id/categories"/> android:enabled="true"
android:icon="@drawable/ic_categories"
android:orderInCategory="1"
android:title="@string/main_menu__categories"
app:showAsAction="ifRoom|withText" />
<item <item
app:showAsAction="ifRoom|withText" android:id="@+id/nearby"
android:id="@+id/nearby"/> android:enabled="true"
android:icon="@drawable/ic_nearby"
android:orderInCategory="2"
android:title="@string/main_menu__swap_nearby"
app:showAsAction="ifRoom|withText" />
<item <item
app:showAsAction="ifRoom|withText" android:id="@+id/updates"
android:id="@+id/updates"/> android:enabled="true"
android:icon="@drawable/ic_updates"
android:orderInCategory="3"
android:title="@string/main_menu__updates"
app:showAsAction="ifRoom|withText" />
<item <item
app:showAsAction="ifRoom|withText" android:id="@+id/settings"
android:id="@+id/settings"/> android:enabled="true"
android:icon="@drawable/ic_settings"
android:orderInCategory="4"
android:title="@string/menu_settings"
app:showAsAction="ifRoom|withText" />
</menu> </menu>

View File

@ -4,7 +4,7 @@
<style name="SwapTheme.AppList.SwapSuccess" parent="SwapTheme.AppList.SwapSuccessBase"> <style name="SwapTheme.AppList.SwapSuccess" parent="SwapTheme.AppList.SwapSuccessBase">
<item name="android:textAlignment">center</item> <item name="android:textAlignment">center</item>
<item name="android:gravity">center</item> <item name="android:gravity">center</item>
<item name="android:fontFamily">sans-serif-light</item> <item name="fontFamily">sans-serif-light</item>
</style> </style>
<style name="SwapTheme.AppList.SwapSuccessDetails" parent="SwapTheme.AppList.SwapSuccessDetailsBase"> <style name="SwapTheme.AppList.SwapSuccessDetails" parent="SwapTheme.AppList.SwapSuccessDetailsBase">
@ -23,7 +23,7 @@
</style> </style>
<style name="SwapTheme.Wizard.MainText" parent="SwapTheme.Wizard.MainTextBase"> <style name="SwapTheme.Wizard.MainText" parent="SwapTheme.Wizard.MainTextBase">
<item name="android:fontFamily">sans-serif-light</item> <item name="fontFamily">sans-serif-light</item>
</style> </style>
</resources> </resources>

View File

@ -2,7 +2,7 @@
<resources> <resources>
<style name="SwapTheme.Wizard" parent="Theme.AppCompat.Light.NoActionBar"> <style name="SwapTheme.Wizard" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:colorButtonNormal">#04b9e6</item> <item name="colorButtonNormal">#04b9e6</item>
</style> </style>
</resources> </resources>

View File

@ -3,13 +3,9 @@
<style name="SwapTheme.Wizard" parent="Theme.AppCompat.Light.NoActionBar"> <style name="SwapTheme.Wizard" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorButtonNormal">@color/swap_bright_blue</item> <item name="colorButtonNormal">@color/swap_bright_blue</item>
<item name="actionButtonStyle">@style/SwapTheme.Wizard.ActionButton</item>
<item name="actionBarStyle">@style/Widget.AppCompat.ActionBar.Solid</item>
</style> </style>
<style name="SwapTheme.StartSwap" parent="AppThemeLight"> <style name="SwapTheme.StartSwap" parent="Theme.App"/>
<item name="android:background">@android:color/white</item>
</style>
<style name="SwapTheme.StartSwap.Text" parent="@style/SwapTheme.StartSwap"> <style name="SwapTheme.StartSwap.Text" parent="@style/SwapTheme.StartSwap">
</style> </style>
@ -17,10 +13,10 @@
<style name="SwapTheme.BluetoothDeviceList" parent="@style/SwapTheme.Wizard"> <style name="SwapTheme.BluetoothDeviceList" parent="@style/SwapTheme.Wizard">
</style> </style>
<style name="SwapTheme.AppList" parent="AppThemeLight"> <style name="SwapTheme.AppList" parent="Base.Theme.App">
</style> </style>
<style name="SwapTheme.AppList.ListItem" parent="AppThemeLight"> <style name="SwapTheme.AppList.ListItem" parent="Theme.App">
</style> </style>
<style name="SwapTheme.AppList.SwapSuccessBase"> <style name="SwapTheme.AppList.SwapSuccessBase">

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
* Copyright (C) 2010-2012 Ciaran Gultnieks * Copyright (C) 2010-2012 Ciaran Gultnieks
* Copyright (C) 2013-2017 Peter Serwylo * Copyright (C) 2013-2017 Peter Serwylo
@ -22,397 +23,328 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="org.fdroid.fdroid" package="org.fdroid.fdroid"
android:installLocation="auto"> android:installLocation="auto">
<supports-screens <supports-screens
android:anyDensity="true" android:anyDensity="true"
android:largeScreens="true" android:largeScreens="true"
android:normalScreens="true" android:normalScreens="true"
android:resizeable="true" android:resizeable="true"
android:smallScreens="true" android:smallScreens="true"
android:xlargeScreens="true" android:xlargeScreens="true" />
/>
<uses-feature <uses-feature
android:name="android.hardware.telephony" android:name="android.hardware.telephony"
android:required="false"/> android:required="false" />
<uses-feature <uses-feature
android:name="android.hardware.wifi" android:name="android.hardware.wifi"
android:required="false"/> android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-feature
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> android:name="android.hardware.touchscreen"
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> android:required="false" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application <application
android:name=".FDroidApp" android:name=".FDroidApp"
android:icon="@drawable/ic_launcher" android:allowBackup="true"
android:label="@string/app_name" android:description="@string/app_description"
android:description="@string/app_description" android:fullBackupContent="@xml/backup_rules"
android:allowBackup="true" android:icon="@drawable/ic_launcher"
android:fullBackupContent="@xml/backup_rules" android:label="BobStore"
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppThemeLight" android:supportsRtl="true"
android:supportsRtl="true"> android:theme="@style/Theme.App">
<provider
android:authorities="${applicationId}.data.AppProvider"
android:name="org.fdroid.fdroid.data.AppProvider"
android:exported="false"/>
<provider
android:authorities="${applicationId}.data.RepoProvider"
android:name="org.fdroid.fdroid.data.RepoProvider"
android:exported="false"/>
<provider
android:authorities="${applicationId}.data.ApkProvider"
android:name="org.fdroid.fdroid.data.ApkProvider"
android:exported="false"/>
<provider
android:authorities="${applicationId}.data.TempApkProvider"
android:name="org.fdroid.fdroid.data.TempApkProvider"
android:exported="false"/>
<provider
android:authorities="${applicationId}.data.TempAppProvider"
android:name="org.fdroid.fdroid.data.TempAppProvider"
android:exported="false"/>
<provider
android:authorities="${applicationId}.data.InstalledAppProvider"
android:name="org.fdroid.fdroid.data.InstalledAppProvider"
android:exported="false"/>
<provider
android:authorities="${applicationId}.data.AppPrefsProvider"
android:name="org.fdroid.fdroid.data.AppPrefsProvider"
android:exported="false"/>
<provider
android:authorities="${applicationId}.data.PackageIdProvider"
android:name="org.fdroid.fdroid.data.PackageIdProvider"
android:exported="false"/>
<provider
android:authorities="${applicationId}.data.CategoryProvider"
android:name="org.fdroid.fdroid.data.CategoryProvider"
android:exported="false"/>
<provider
android:name="org.fdroid.fdroid.installer.ApkFileProvider"
android:authorities="${applicationId}.installer.ApkFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/apk_file_provider"/>
</provider>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.installer"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/installer_file_provider"/>
</provider>
<activity <activity
android:name=".privileged.views.InstallConfirmActivity" android:name=".privileged.views.InstallConfirmActivity"
android:label="@string/menu_install" android:configChanges="layoutDirection|locale"
android:theme="@style/MinWithDialogBaseThemeLight" android:excludeFromRecents="true"
android:excludeFromRecents="true" android:label="@string/menu_install"
android:parentActivityName=".views.main.MainActivity" android:parentActivityName=".views.main.MainActivity">
android:configChanges="layoutDirection|locale">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity"/> android:value=".views.main.MainActivity" />
</activity>
<activity
android:name=".privileged.views.UninstallDialogActivity"
android:excludeFromRecents="true"
android:theme="@style/AppThemeTransparent"/>
<activity
android:name=".views.ManageReposActivity"
android:label="@string/menu_manage"
android:launchMode="singleTask"
android:parentActivityName=".views.main.MainActivity"
android:configChanges="layoutDirection|locale">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity"/>
</activity>
<activity
android:name=".NfcNotEnabledActivity"
android:noHistory="true"
android:configChanges="layoutDirection|locale"/>
<activity
android:name=".views.RepoDetailsActivity"
android:label="@string/repo_details"
android:parentActivityName=".views.ManageReposActivity"
android:windowSoftInputMode="stateHidden"
android:configChanges="layoutDirection|locale">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".views.ManageReposActivity"/>
</activity> </activity>
<activity <activity
android:name=".views.AppDetailsActivity" android:name=".privileged.views.UninstallDialogActivity"
android:label="@string/app_details" android:excludeFromRecents="true" />
android:exported="true"
android:parentActivityName=".views.main.MainActivity" <activity
android:configChanges="layoutDirection|locale"> android:name=".views.ManageReposActivity"
android:configChanges="layoutDirection|locale"
android:label="@string/menu_manage"
android:launchMode="singleTask"
android:parentActivityName=".views.main.MainActivity">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity"/> android:value=".views.main.MainActivity" />
</activity> </activity>
<activity
android:name=".acra.CrashReportActivity"
android:theme="@style/AppThemeDark"
android:process=":error_report"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="true"/>
<activity android:name=".views.ScreenShotsActivity"/>
<!-- Note: AppThemeTransparent, this activity shows dialogs only -->
<activity android:name=".data.ObbUrlActivity"
android:theme="@android:style/Theme.NoDisplay"/>
<!-- Note: AppThemeTransparent, this activity shows dialogs only -->
<activity
android:name=".installer.DefaultInstallerActivity"
android:theme="@style/AppThemeTransparent"/>
<!-- Note: AppThemeTransparent, this activity shows dialogs only -->
<activity
android:name=".installer.ErrorDialogActivity"
android:theme="@style/AppThemeTransparent"/>
<receiver android:name=".receiver.StartupReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.HOME"/>
</intent-filter>
</receiver>
<receiver android:name=".receiver.PackageManagerReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_CHANGED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
<receiver android:name=".NotificationBroadcastReceiver" android:exported="false">
<!-- Doesn't require an intent-filter because it is explicitly invoked via Intent.setClass() -->
</receiver>
<receiver android:name=".receiver.DeviceStorageReceiver">
<intent-filter>
<action android:name="android.intent.action.DEVICE_STORAGE_LOW"/>
</intent-filter>
</receiver>
<service
android:name=".UpdateService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<service
android:name=".UpdateJobService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"/>
<service
android:name=".net.DownloaderService"
android:exported="false"/>
<service
android:name=".installer.InstallerService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<service
android:name=".DeleteCacheService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<service
android:name=".net.ConnectivityMonitorService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<service
android:name=".installer.InstallManagerService"
android:exported="false"/>
<service
android:name=".installer.InstallHistoryService"
android:exported="false"/>
<service
android:name=".installer.ObfInstallerService"
android:exported="false"/>
<service
android:name=".data.InstalledAppProviderService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<service
android:name=".AddRepoIntentService"
android:exported="false"/>
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:exported="false"
tools:node="remove" />
<activity <activity
android:name=".views.main.MainActivity" android:name=".NfcNotEnabledActivity"
android:launchMode="singleTop" android:configChanges="layoutDirection|locale"
android:windowSoftInputMode="adjustResize"> android:noHistory="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <activity
android:name=".views.RepoDetailsActivity"
android:configChanges="layoutDirection|locale"
android:label="@string/repo_details"
android:parentActivityName=".views.ManageReposActivity"
android:windowSoftInputMode="stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".views.ManageReposActivity" />
</activity>
<activity
android:name=".views.AppDetailsActivity"
android:configChanges="layoutDirection|locale"
android:exported="true"
android:label="@string/app_details"
android:parentActivityName=".views.main.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity" />
</activity>
<activity
android:name=".acra.CrashReportActivity"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="true"
android:launchMode="singleInstance"
android:process=":error_report" />
<activity android:name=".views.ScreenShotsActivity" />
<activity
android:name=".data.ObbUrlActivity"
android:theme="@android:style/Theme.NoDisplay" />
<activity
android:name=".installer.DefaultInstallerActivity"
android:theme="@style/AppThemeTransparent" />
<activity
android:name=".installer.ErrorDialogActivity"
android:theme="@style/AppThemeTransparent" />
<activity
android:name=".views.main.MainActivity"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<!-- App URLs --> <!-- App URLs -->
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="fdroid.app"/> <data android:scheme="fdroid.app" />
</intent-filter> </intent-filter>
<intent-filter android:autoVerify="false"> <intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"/> <data android:scheme="https" />
<data android:host="f-droid.org"/> <data android:host="f-droid.org" />
<data android:host="www.f-droid.org"/> <data android:host="www.f-droid.org" />
<data android:host="staging.f-droid.org"/> <data android:host="staging.f-droid.org" />
<data android:pathPrefix="/app/"/> <data android:pathPrefix="/app/" />
<data android:pathPrefix="/packages/"/> <data android:pathPrefix="/packages/" />
<data android:pathPrefix="/repository/browse"/> <data android:pathPrefix="/repository/browse" />
<!-- support localized URLs --> <!-- support localized URLs -->
<data android:pathPattern="/.*/packages/.*"/> <data android:pathPattern="/.*/packages/.*" />
<data android:pathPattern="/.*/packages/.*/"/> <data android:pathPattern="/.*/packages/.*/" />
</intent-filter> </intent-filter>
<intent-filter android:autoVerify="false"> <intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http"/> <data android:scheme="http" />
<data android:host="f-droid.org"/> <data android:host="f-droid.org" />
<data android:host="www.f-droid.org"/> <data android:host="www.f-droid.org" />
<data android:host="staging.f-droid.org"/> <data android:host="staging.f-droid.org" />
<data android:pathPrefix="/app/"/> <data android:pathPrefix="/app/" />
<data android:pathPrefix="/packages/"/> <data android:pathPrefix="/packages/" />
<data android:pathPrefix="/repository/browse"/> <data android:pathPrefix="/repository/browse" />
<!-- support localized URLs --> <!-- support localized URLs -->
<data android:pathPattern="/.*/packages/.*"/> <data android:pathPattern="/.*/packages/.*" />
<data android:pathPattern="/.*/packages/.*/"/> <data android:pathPattern="/.*/packages/.*/" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="market" android:host="details"/> <data
android:host="details"
android:scheme="market" />
</intent-filter> </intent-filter>
<intent-filter android:autoVerify="false"> <intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http"/> <data android:scheme="http" />
<data android:scheme="https"/> <data android:scheme="https" />
<data android:host="play.google.com"/> <!-- they don't do www. --> <data android:host="play.google.com" /> <!-- they don't do www. -->
<data android:path="/store/apps/details"/> <data android:path="/store/apps/details" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="amzn" android:host="apps" android:path="/android"/> <data
android:host="apps"
android:path="/android"
android:scheme="amzn" />
</intent-filter> </intent-filter>
<intent-filter android:autoVerify="false"> <intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http"/> <data android:scheme="http" />
<data android:scheme="https"/> <data android:scheme="https" />
<data android:host="amazon.com"/> <data android:host="amazon.com" />
<data android:host="www.amazon.com"/> <data android:host="www.amazon.com" />
<data android:path="/gp/mas/dl/android"/> <data android:path="/gp/mas/dl/android" />
</intent-filter> </intent-filter>
<!-- Search URLs --> <!-- Search URLs -->
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="fdroid.search"/> <data android:scheme="fdroid.search" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="market" android:host="search"/> <data
android:host="search"
android:scheme="market" />
</intent-filter> </intent-filter>
<intent-filter android:autoVerify="false"> <intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http"/> <data android:scheme="http" />
<data android:scheme="https"/> <data android:scheme="https" />
<data android:host="play.google.com"/> <!-- they don't do www. --> <data android:host="play.google.com" /> <!-- they don't do www. -->
<data android:path="/store/search"/> <data android:path="/store/search" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.SEARCH"/> <action android:name="android.intent.action.SEARCH" />
</intent-filter> </intent-filter>
<meta-data <intent-filter android:autoVerify="false">
android:name="android.app.searchable" <action android:name="android.intent.action.VIEW" />
android:resource="@xml/searchable"/>
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<!--
Android's scheme matcher is case-sensitive, so include
ALL CAPS versions to support ALL CAPS URLs in QR Codes.
QR Codes have a special ALL CAPS mode that uses a reduced
character set, making for more compact QR Codes.
-->
<data android:scheme="http" />
<data
android:scheme="HTTP"
tools:ignore="AppLinkUrlError" />
<data android:scheme="https" />
<data
android:scheme="HTTPS"
tools:ignore="AppLinkUrlError" />
<data android:host="*" />
<!--
The pattern matcher here is poorly implemented, in particular the * is
non-greedy, so you have to do stupid tricks to match patterns that have
repeat characters in them. http://stackoverflow.com/a/8599921/306864
-->
<data android:path="/fdroid/repo" />
<data android:pathPattern="/fdroid/repo/*" />
<data android:pathPattern="/.*/fdroid/repo" />
<data android:pathPattern="/.*/fdroid/repo/*" />
<data android:pathPattern="/.*/.*/fdroid/repo" />
<data android:pathPattern="/.*/.*/fdroid/repo/*" />
<data android:pathPattern="/.*/.*/.*/fdroid/repo" />
<data android:pathPattern="/.*/.*/.*/fdroid/repo/*" />
<data android:pathPattern="/.*/.*/.*/.*/fdroid/repo" />
<data android:pathPattern="/.*/.*/.*/.*/fdroid/repo/*" />
<data android:pathPattern="/.*/.*/.*/.*/.*/fdroid/repo" />
<data android:pathPattern="/.*/.*/.*/.*/.*/fdroid/repo/*" />
<data android:pathPattern="/.*/.*/.*/.*/.*/.*/fdroid/repo" />
<data android:pathPattern="/.*/.*/.*/.*/.*/.*/fdroid/repo/*" />
<data android:path="/fdroid/archive" />
<data android:pathPattern="/fdroid/archive/*" />
<data android:pathPattern="/.*/fdroid/archive" />
<data android:pathPattern="/.*/fdroid/archive/*" />
<data android:pathPattern="/.*/.*/fdroid/archive" />
<data android:pathPattern="/.*/.*/fdroid/archive/*" />
<data android:pathPattern="/.*/.*/.*/fdroid/archive" />
<data android:pathPattern="/.*/.*/.*/fdroid/archive/*" />
<data android:pathPattern="/.*/.*/.*/.*/fdroid/archive" />
<data android:pathPattern="/.*/.*/.*/.*/fdroid/archive/*" />
<!--
Some QR Code scanners don't respect custom schemes like fdroidrepo://,
so this is a workaround, since the local repo URL is all uppercase in
the QR Code for sending the local repo to another device.
-->
<data android:path="/FDROID/REPO" />
<data android:pathPattern="/.*/FDROID/REPO" />
<data android:pathPattern="/.*/.*/FDROID/REPO" />
<data android:pathPattern="/.*/.*/.*/FDROID/REPO" />
</intent-filter>
<!-- Repo URLs --> <!-- Repo URLs -->
@ -432,11 +364,11 @@
This filter supports HTTP and HTTPS schemes. There is an additional filter for This filter supports HTTP and HTTPS schemes. There is an additional filter for
fdroidrepo:// and fdroidrepos:// fdroidrepo:// and fdroidrepos://
--> -->
<intent-filter android:autoVerify="false"> <intent-filter>
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT" />
<!-- <!--
Android's scheme matcher is case-sensitive, so include Android's scheme matcher is case-sensitive, so include
@ -444,51 +376,14 @@
QR Codes have a special ALL CAPS mode that uses a reduced QR Codes have a special ALL CAPS mode that uses a reduced
character set, making for more compact QR Codes. character set, making for more compact QR Codes.
--> -->
<data android:scheme="http"/> <data android:scheme="fdroidrepo" />
<data android:scheme="HTTP" tools:ignore="AppLinkUrlError"/> <data
<data android:scheme="https"/> android:scheme="FDROIDREPO"
<data android:scheme="HTTPS" tools:ignore="AppLinkUrlError"/> tools:ignore="AppLinkUrlError" />
<data android:scheme="fdroidrepos" />
<data android:host="*"/> <data
android:scheme="FDROIDREPOS"
<!-- tools:ignore="AppLinkUrlError" />
The pattern matcher here is poorly implemented, in particular the * is
non-greedy, so you have to do stupid tricks to match patterns that have
repeat characters in them. http://stackoverflow.com/a/8599921/306864
-->
<data android:path="/fdroid/repo"/>
<data android:pathPattern="/fdroid/repo/*"/>
<data android:pathPattern="/.*/fdroid/repo"/>
<data android:pathPattern="/.*/fdroid/repo/*"/>
<data android:pathPattern="/.*/.*/fdroid/repo"/>
<data android:pathPattern="/.*/.*/fdroid/repo/*"/>
<data android:pathPattern="/.*/.*/.*/fdroid/repo"/>
<data android:pathPattern="/.*/.*/.*/fdroid/repo/*"/>
<data android:pathPattern="/.*/.*/.*/.*/fdroid/repo"/>
<data android:pathPattern="/.*/.*/.*/.*/fdroid/repo/*"/>
<data android:pathPattern="/.*/.*/.*/.*/.*/fdroid/repo"/>
<data android:pathPattern="/.*/.*/.*/.*/.*/fdroid/repo/*"/>
<data android:pathPattern="/.*/.*/.*/.*/.*/.*/fdroid/repo"/>
<data android:pathPattern="/.*/.*/.*/.*/.*/.*/fdroid/repo/*"/>
<data android:path="/fdroid/archive"/>
<data android:pathPattern="/fdroid/archive/*"/>
<data android:pathPattern="/.*/fdroid/archive"/>
<data android:pathPattern="/.*/fdroid/archive/*"/>
<data android:pathPattern="/.*/.*/fdroid/archive"/>
<data android:pathPattern="/.*/.*/fdroid/archive/*"/>
<data android:pathPattern="/.*/.*/.*/fdroid/archive"/>
<data android:pathPattern="/.*/.*/.*/fdroid/archive/*"/>
<data android:pathPattern="/.*/.*/.*/.*/fdroid/archive"/>
<data android:pathPattern="/.*/.*/.*/.*/fdroid/archive/*"/>
<!--
Some QR Code scanners don't respect custom schemes like fdroidrepo://,
so this is a workaround, since the local repo URL is all uppercase in
the QR Code for sending the local repo to another device.
-->
<data android:path="/FDROID/REPO"/>
<data android:pathPattern="/.*/FDROID/REPO"/>
<data android:pathPattern="/.*/.*/FDROID/REPO"/>
<data android:pathPattern="/.*/.*/.*/FDROID/REPO"/>
</intent-filter> </intent-filter>
<!-- <!--
@ -496,58 +391,186 @@
looks for fdroidrepos://* and doesn't care what the path is. looks for fdroidrepos://* and doesn't care what the path is.
--> -->
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW"/> <action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.DEFAULT"/>
<!--
Android's scheme matcher is case-sensitive, so include
ALL CAPS versions to support ALL CAPS URLs in QR Codes.
QR Codes have a special ALL CAPS mode that uses a reduced
character set, making for more compact QR Codes.
-->
<data android:scheme="fdroidrepo"/>
<data android:scheme="FDROIDREPO" tools:ignore="AppLinkUrlError"/>
<data android:scheme="fdroidrepos"/>
<data android:scheme="FDROIDREPOS" tools:ignore="AppLinkUrlError"/>
</intent-filter>
<!-- Handle NFC tags detected from outside our application -->
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<!-- <!--
URIs that come in via NFC have scheme/host normalized to all lower case URIs that come in via NFC have scheme/host normalized to all lower case
https://developer.android.com/reference/android/nfc/NfcAdapter.html#ACTION_NDEF_DISCOVERED https://developer.android.com/reference/android/nfc/NfcAdapter.html#ACTION_NDEF_DISCOVERED
--> -->
<data android:scheme="fdroidrepo"/> <data android:scheme="fdroidrepo" />
<data android:scheme="fdroidrepos"/> <data android:scheme="fdroidrepos" />
</intent-filter> </intent-filter>
</activity>
<activity android:name=".views.apps.AppListActivity"/> <!-- Handle NFC tags detected from outside our application -->
<activity android:name=".views.installed.InstalledAppsActivity"
android:parentActivityName=".views.main.MainActivity">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.app.searchable"
android:value=".views.main.MainActivity"/> android:resource="@xml/searchable" />
</activity>
<activity android:name=".views.InstallHistoryActivity"
android:parentActivityName=".views.main.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity"/>
</activity>
<activity android:name=".AboutActivity" android:theme="@style/Theme.AppCompat.Light.Dialog"/> </activity>
<activity android:name=".installer.FileInstallerActivity" android:theme="@style/AppThemeTransparent"/> <activity android:name=".views.apps.AppListActivity" />
<activity
android:name=".views.installed.InstalledAppsActivity"
android:parentActivityName=".views.main.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity" />
</activity>
<activity
android:name=".views.InstallHistoryActivity"
android:parentActivityName=".views.main.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".views.main.MainActivity" />
</activity>
<activity android:name=".AboutActivity" />
<activity
android:name=".installer.FileInstallerActivity"
android:theme="@style/AppThemeTransparent" />
<provider
android:name="org.fdroid.fdroid.data.AppProvider"
android:authorities="${applicationId}.data.AppProvider"
android:exported="false" />
<provider
android:name="org.fdroid.fdroid.data.RepoProvider"
android:authorities="${applicationId}.data.RepoProvider"
android:exported="false" />
<!-- Note: AppThemeTransparent, this activity shows dialogs only -->
<provider
android:name="org.fdroid.fdroid.data.ApkProvider"
android:authorities="${applicationId}.data.ApkProvider"
android:exported="false" />
<!-- Note: AppThemeTransparent, this activity shows dialogs only -->
<provider
android:name="org.fdroid.fdroid.data.TempApkProvider"
android:authorities="${applicationId}.data.TempApkProvider"
android:exported="false" />
<!-- Note: AppThemeTransparent, this activity shows dialogs only -->
<provider
android:name="org.fdroid.fdroid.data.TempAppProvider"
android:authorities="${applicationId}.data.TempAppProvider"
android:exported="false" />
<provider
android:name="org.fdroid.fdroid.data.InstalledAppProvider"
android:authorities="${applicationId}.data.InstalledAppProvider"
android:exported="false" />
<provider
android:name="org.fdroid.fdroid.data.AppPrefsProvider"
android:authorities="${applicationId}.data.AppPrefsProvider"
android:exported="false" />
<provider
android:name="org.fdroid.fdroid.data.PackageIdProvider"
android:authorities="${applicationId}.data.PackageIdProvider"
android:exported="false" />
<provider
android:name="org.fdroid.fdroid.data.CategoryProvider"
android:authorities="${applicationId}.data.CategoryProvider"
android:exported="false" />
<provider
android:name="org.fdroid.fdroid.installer.ApkFileProvider"
android:authorities="${applicationId}.installer.ApkFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/apk_file_provider" />
</provider>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.installer"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/installer_file_provider" />
</provider>
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:exported="false"
tools:node="remove" />
<receiver android:name=".receiver.StartupReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
<receiver android:name=".receiver.PackageManagerReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver
android:name=".NotificationBroadcastReceiver"
android:exported="false">
<!-- Doesn't require an intent-filter because it is explicitly invoked via Intent.setClass() -->
</receiver>
<receiver android:name=".receiver.DeviceStorageReceiver">
<intent-filter>
<action android:name="android.intent.action.DEVICE_STORAGE_LOW" />
</intent-filter>
</receiver>
<service
android:name=".UpdateService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name=".UpdateJobService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name=".net.DownloaderService"
android:exported="false" />
<service
android:name=".installer.InstallerService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name=".DeleteCacheService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name=".net.ConnectivityMonitorService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name=".installer.InstallManagerService"
android:exported="false" />
<service
android:name=".installer.InstallHistoryService"
android:exported="false" />
<service
android:name=".installer.ObfInstallerService"
android:exported="false" />
<service
android:name=".data.InstalledAppProviderService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name=".AddRepoIntentService"
android:exported="false" />
</application> </application>

View File

@ -16,7 +16,6 @@
package com.google.zxing.integration.android; package com.google.zxing.integration.android;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
@ -26,6 +25,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@ -336,7 +336,7 @@ public class IntentIntegrator {
* @param intent Intent to start. * @param intent Intent to start.
* @param code Request code for the activity * @param code Request code for the activity
* @see android.app.AppCompatActivity#startActivityForResult(Intent, int) * @see android.app.AppCompatActivity#startActivityForResult(Intent, int)
* @see android.app.Fragment#startActivityForResult(Intent, int) * @see Fragment#startActivityForResult(Intent, int)
*/ */
protected void startActivityForResult(Intent intent, int code) { protected void startActivityForResult(Intent intent, int code) {
if (fragment == null) { if (fragment == null) {

View File

@ -1,32 +0,0 @@
package org.fdroid.fdroid;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
public class AboutActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
FDroidApp fdroidApp = (FDroidApp) getApplication();
fdroidApp.applyDialogTheme(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.about);
String versionName = Utils.getVersionName(this);
if (versionName != null) {
((TextView) findViewById(R.id.version)).setText(versionName);
}
findViewById(R.id.ok_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}

View File

@ -5,10 +5,9 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.data.RepoProvider;
import org.fdroid.fdroid.views.ManageReposActivity; import org.fdroid.fdroid.views.ManageReposActivity;
@ -18,6 +17,9 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Locale; import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/** /**
* Handles requests to add new repos via URLs. This is an {@code IntentService} * Handles requests to add new repos via URLs. This is an {@code IntentService}
* so that requests are queued, which is necessary when either * so that requests are queued, which is necessary when either

View File

@ -9,10 +9,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.TaskStackBuilder;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.data.AppProvider; import org.fdroid.fdroid.data.AppProvider;
@ -28,6 +25,11 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.TaskStackBuilder;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/** /**
* Manages the state of APKs that are being installed or that have updates available. * Manages the state of APKs that are being installed or that have updates available.
* This also ensures the state is saved across F-Droid restarts, and repopulates * This also ensures the state is saved across F-Droid restarts, and repopulates

View File

@ -4,7 +4,7 @@ import android.content.Context;
import android.content.pm.FeatureInfo; import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build; import android.os.Build;
import androidx.annotation.Nullable;
import org.fdroid.fdroid.compat.SupportedArchitectures; import org.fdroid.fdroid.compat.SupportedArchitectures;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
@ -14,6 +14,8 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import androidx.annotation.Nullable;
// Call getIncompatibleReasons(apk) on an instance of this class to // Call getIncompatibleReasons(apk) on an instance of this class to
// find reasons why an apk may be incompatible with the user's device. // find reasons why an apk may be incompatible with the user's device.
public class CompatibilityChecker { public class CompatibilityChecker {

View File

@ -3,14 +3,16 @@ package org.fdroid.fdroid;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Process; import android.os.Process;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
import androidx.core.content.ContextCompat;
import android.util.Log; import android.util.Log;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import java.io.File; import java.io.File;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
import androidx.core.content.ContextCompat;
/** /**
* An {@link JobIntentService} subclass for deleting the full cache for this app. * An {@link JobIntentService} subclass for deleting the full cache for this app.
*/ */

View File

@ -24,7 +24,6 @@
package org.fdroid.fdroid; package org.fdroid.fdroid;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo; import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.Application; import android.app.Application;
@ -46,10 +45,7 @@ import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.collection.LongSparseArray;
import androidx.core.content.ContextCompat;
import com.nostra13.universalimageloader.cache.disc.DiskCache; import com.nostra13.universalimageloader.cache.disc.DiskCache;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiskCache; import com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiskCache;
@ -57,8 +53,7 @@ import com.nostra13.universalimageloader.core.DefaultConfigurationFactory;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.process.BitmapProcessor; import com.nostra13.universalimageloader.core.process.BitmapProcessor;
import info.guardianproject.netcipher.NetCipher;
import info.guardianproject.netcipher.proxy.OrbotHelper;
import org.acra.ACRA; import org.acra.ACRA;
import org.acra.ReportField; import org.acra.ReportField;
import org.acra.ReportingInteractionMode; import org.acra.ReportingInteractionMode;
@ -82,13 +77,23 @@ import org.fdroid.fdroid.net.ImageLoaderForUIL;
import org.fdroid.fdroid.panic.HidingManager; import org.fdroid.fdroid.panic.HidingManager;
import org.fdroid.fdroid.work.CleanCacheWorker; import org.fdroid.fdroid.work.CleanCacheWorker;
import javax.microedition.khronos.opengles.GL10;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.Security; import java.security.Security;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import javax.microedition.khronos.opengles.GL10;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.collection.LongSparseArray;
import androidx.core.content.ContextCompat;
import info.guardianproject.netcipher.NetCipher;
import info.guardianproject.netcipher.proxy.OrbotHelper;
@ReportsCrashes(mailTo = BuildConfig.ACRA_REPORT_EMAIL, @ReportsCrashes(mailTo = BuildConfig.ACRA_REPORT_EMAIL,
mode = ReportingInteractionMode.DIALOG, mode = ReportingInteractionMode.DIALOG,
reportDialogClass = org.fdroid.fdroid.acra.CrashReportActivity.class, reportDialogClass = org.fdroid.fdroid.acra.CrashReportActivity.class,
@ -152,30 +157,47 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
private static Theme curTheme = Theme.light; private static Theme curTheme = Theme.light;
public void reloadTheme() { /**
curTheme = Preferences.get().getTheme(); * Apply pure black background in dark theme setting. Must be called in every activity's
} * {@link AppCompatActivity#onCreate()}, before super.onCreate().
*
public void applyTheme(AppCompatActivity activity) { * @param activity The activity to apply the setting.
activity.setTheme(getCurThemeResId()); */
setSecureWindow(activity); public void applyPureBlackBackgroundInDarkTheme(AppCompatActivity activity) {
} final boolean isPureBlack = Preferences.get().isPureBlack();
if (isPureBlack) {
public static int getCurThemeResId() { activity.setTheme(R.style.Theme_App_Black);
switch (curTheme) {
case light:
return R.style.AppThemeLight;
case dark:
return R.style.AppThemeDark;
case night:
return R.style.AppThemeNight;
default:
return R.style.AppThemeLight;
} }
} }
public void applyTheme() {
curTheme = Preferences.get().getTheme();
switch (curTheme) {
case dark:
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
break;
case light:
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
break;
default:
// `Set by Battery Saver` for Q above (inclusive), `Use system default` for Q below
// https://medium.com/androiddevelopers/appcompat-v23-2-daynight-d10f90c83e94
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
}
break;
}
}
// TODO: ResId no longer exists.
public static int getCurThemeResId() {
return R.style.Theme_App;
}
public static boolean isAppThemeLight() { public static boolean isAppThemeLight() {
return curTheme == Theme.light; return AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_NO;
} }
public void applyDialogTheme(AppCompatActivity activity) { public void applyDialogTheme(AppCompatActivity activity) {
@ -191,10 +213,7 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
private static int getCurDialogThemeResId() { private static int getCurDialogThemeResId() {
switch (curTheme) { switch (curTheme) {
case light:
return R.style.MinWithDialogBaseThemeLight;
case dark: case dark:
return R.style.MinWithDialogBaseThemeDark;
case night: case night:
return R.style.MinWithDialogBaseThemeDark; return R.style.MinWithDialogBaseThemeDark;
default: default:
@ -202,24 +221,6 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
} }
} }
/**
* Force reload the {@link AppCompatActivity to make theme changes take effect.}
* Same as {@link Languages#forceChangeLanguage(AppCompatActivity)}
*
* @param activity the {@code AppCompatActivity} to force reload
*/
public static void forceChangeTheme(AppCompatActivity activity) {
Intent intent = activity.getIntent();
if (intent == null) { // when launched as LAUNCHER
return;
}
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
activity.finish();
activity.overridePendingTransition(0, 0);
activity.startActivity(intent);
activity.overridePendingTransition(0, 0);
}
public static void enableBouncyCastle() { public static void enableBouncyCastle() {
Security.addProvider(BOUNCYCASTLE_PROVIDER); Security.addProvider(BOUNCYCASTLE_PROVIDER);
} }
@ -268,7 +269,7 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
* @see #getTimeout() * @see #getTimeout()
* @see Repo#getRandomMirror(String) * @see Repo#getRandomMirror(String)
*/ */
public static String getNewMirrorOnError(@Nullable String urlString, Repo repo2) throws IOException { public static synchronized String getNewMirrorOnError(@Nullable String urlString, Repo repo2) throws IOException {
if (repo2.hasMirrors()) { if (repo2.hasMirrors()) {
if (numTries <= 0) { if (numTries <= 0) {
if (timeout == Downloader.DEFAULT_TIMEOUT) { if (timeout == Downloader.DEFAULT_TIMEOUT) {
@ -393,7 +394,8 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
PRNGFixes.apply(); PRNGFixes.apply();
curTheme = preferences.getTheme(); applyTheme();
configureProxy(preferences); configureProxy(preferences);

View File

@ -27,9 +27,9 @@ import android.content.ContentResolver;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import androidx.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.ApkProvider; import org.fdroid.fdroid.data.ApkProvider;
import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.App;
@ -48,9 +48,6 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -64,6 +61,12 @@ import java.util.List;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import androidx.annotation.NonNull;
// TODO move to org.fdroid.fdroid.updater // TODO move to org.fdroid.fdroid.updater
// TODO reduce visibility of methods once in .updater package (.e.g tests need it public now) // TODO reduce visibility of methods once in .updater package (.e.g tests need it public now)

View File

@ -25,9 +25,9 @@ package org.fdroid.fdroid;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import androidx.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonFactory;
@ -36,6 +36,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.InjectableValues; import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.App;
@ -47,10 +48,6 @@ import org.fdroid.fdroid.data.Schema;
import org.fdroid.fdroid.net.Downloader; import org.fdroid.fdroid.net.Downloader;
import org.fdroid.fdroid.net.DownloaderFactory; import org.fdroid.fdroid.net.DownloaderFactory;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLKeyException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLProtocolException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -71,6 +68,13 @@ import java.util.Map;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLKeyException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLProtocolException;
import androidx.annotation.NonNull;
/** /**
* Receives the index data about all available apps and packages via the V1 * Receives the index data about all available apps and packages via the V1
* JSON data {@link #DATA_FILE_NAME}, embedded in a signed jar * JSON data {@link #DATA_FILE_NAME}, embedded in a signed jar

View File

@ -8,8 +8,6 @@ import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -18,6 +16,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import androidx.appcompat.app.AppCompatActivity;
public final class Languages { public final class Languages {
public static final String TAG = "Languages"; public static final String TAG = "Languages";

View File

@ -1,7 +1,6 @@
package org.fdroid.fdroid; package org.fdroid.fdroid;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -12,6 +11,8 @@ import android.nfc.NfcAdapter;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
public class NfcHelper { public class NfcHelper {
private static final String TAG = "NfcHelper"; private static final String TAG = "NfcHelper";

View File

@ -6,6 +6,7 @@ import android.nfc.NfcAdapter;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
// aka Android 4.0 aka Ice Cream Sandwich // aka Android 4.0 aka Ice Cream Sandwich
@ -39,8 +40,9 @@ public class NfcNotEnabledActivity extends AppCompatActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
FDroidApp fdroidApp = (FDroidApp) getApplication();
fdroidApp.applyPureBlackBackgroundInDarkTheme(this);
((FDroidApp) getApplication()).applyTheme(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
final Intent intent = new Intent(); final Intent intent = new Intent();

View File

@ -20,11 +20,6 @@ import android.text.TextUtils;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import android.view.View; import android.view.View;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason; import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageSize; import com.nostra13.universalimageloader.core.assist.ImageSize;
@ -38,6 +33,11 @@ import org.fdroid.fdroid.views.main.MainActivity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@SuppressWarnings("LineLength") @SuppressWarnings("LineLength")
public class NotificationHelper { public class NotificationHelper {
public static final String CHANNEL_SWAPS = "swap-channel"; public static final String CHANNEL_SWAPS = "swap-channel";

View File

@ -30,8 +30,7 @@ import android.net.NetworkInfo;
import android.os.Build; import android.os.Build;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.Log; import android.util.Log;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import org.fdroid.fdroid.installer.PrivilegedInstaller; import org.fdroid.fdroid.installer.PrivilegedInstaller;
import org.fdroid.fdroid.net.ConnectivityMonitorService; import org.fdroid.fdroid.net.ConnectivityMonitorService;
@ -44,6 +43,9 @@ import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
/** /**
* Handles shared preferences for FDroid, looking after the names of * Handles shared preferences for FDroid, looking after the names of
* preferences, default values and caching. Needs to be setup in the FDroidApp * preferences, default values and caching. Needs to be setup in the FDroidApp
@ -87,6 +89,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
public static final String PREF_AUTO_DOWNLOAD_INSTALL_UPDATES = "updateAutoDownload"; public static final String PREF_AUTO_DOWNLOAD_INSTALL_UPDATES = "updateAutoDownload";
public static final String PREF_UPDATE_NOTIFICATION_ENABLED = "updateNotify"; public static final String PREF_UPDATE_NOTIFICATION_ENABLED = "updateNotify";
public static final String PREF_THEME = "theme"; public static final String PREF_THEME = "theme";
public static final String PREF_USE_PURE_BLACK_DARK_THEME = "usePureBlackDarkTheme";
public static final String PREF_SHOW_INCOMPAT_VERSIONS = "incompatibleVersions"; public static final String PREF_SHOW_INCOMPAT_VERSIONS = "incompatibleVersions";
public static final String PREF_SHOW_ANTI_FEATURE_APPS = "showAntiFeatureApps"; public static final String PREF_SHOW_ANTI_FEATURE_APPS = "showAntiFeatureApps";
public static final String PREF_FORCE_TOUCH_APPS = "ignoreTouchscreen"; public static final String PREF_FORCE_TOUCH_APPS = "ignoreTouchscreen";
@ -151,7 +154,8 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
public enum Theme { public enum Theme {
light, light,
dark, dark,
night, followSystem,
night, // Obsolete
lightWithDarkActionBar, // Obsolete lightWithDarkActionBar, // Obsolete
} }
@ -395,6 +399,10 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
return Theme.valueOf(preferences.getString(Preferences.PREF_THEME, null)); return Theme.valueOf(preferences.getString(Preferences.PREF_THEME, null));
} }
public boolean isPureBlack() {
return preferences.getBoolean(Preferences.PREF_USE_PURE_BLACK_DARK_THEME, false);
}
public boolean isLocalRepoHttpsEnabled() { public boolean isLocalRepoHttpsEnabled() {
return false; // disabled until it works well return false; // disabled until it works well
} }

View File

@ -1,11 +1,11 @@
package org.fdroid.fdroid; package org.fdroid.fdroid;
import androidx.annotation.NonNull;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import androidx.annotation.NonNull;
class ProgressBufferedInputStream extends BufferedInputStream { class ProgressBufferedInputStream extends BufferedInputStream {
private final ProgressListener progressListener; private final ProgressListener progressListener;
@ -24,7 +24,7 @@ class ProgressBufferedInputStream extends BufferedInputStream {
} }
@Override @Override
public int read(@NonNull byte[] buffer, int byteOffset, int byteCount) throws IOException { public synchronized int read(@NonNull byte[] buffer, int byteOffset, int byteCount) throws IOException {
if (progressListener != null) { if (progressListener != null) {
currentBytes += byteCount; currentBytes += byteCount;
/* don't send every change to keep things efficient. 333333 bytes to keep all /* don't send every change to keep things efficient. 333333 bytes to keep all

View File

@ -4,7 +4,9 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.util.Base64; import android.util.Base64;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.data.RepoProvider;

View File

@ -30,7 +30,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Process; import android.os.Process;
import android.os.SystemClock; import android.os.SystemClock;
@ -38,12 +37,6 @@ import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.ApkProvider; import org.fdroid.fdroid.data.ApkProvider;
import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.App;
@ -57,9 +50,18 @@ import org.fdroid.fdroid.installer.InstallManagerService;
import org.fdroid.fdroid.net.BluetoothDownloader; import org.fdroid.fdroid.net.BluetoothDownloader;
import org.fdroid.fdroid.net.ConnectivityMonitorService; import org.fdroid.fdroid.net.ConnectivityMonitorService;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class UpdateService extends JobIntentService { public class UpdateService extends JobIntentService {
@ -81,6 +83,13 @@ public class UpdateService extends JobIntentService {
public static final int STATUS_ERROR_LOCAL_SMALL = 4; public static final int STATUS_ERROR_LOCAL_SMALL = 4;
public static final int STATUS_INFO = 5; public static final int STATUS_INFO = 5;
/**
* This number should never change, it is used by ROMs to trigger
* the first background update of F-Droid during setup.
*
* @see <a href="https://gitlab.com/fdroid/fdroidclient/-/issues/2147">Add a way to trigger an index update externally</a>
* @see <a href="https://review.calyxos.org/c/CalyxOS/platform_packages_apps_SetupWizard/+/3461"/>Schedule F-Droid index update on initialization and network connection</a>
*/
private static final int JOB_ID = 0xfedcba; private static final int JOB_ID = 0xfedcba;
private static final int NOTIFY_ID_UPDATING = 0; private static final int NOTIFY_ID_UPDATING = 0;
@ -208,42 +217,30 @@ public class UpdateService extends JobIntentService {
* unlimited networks over metered networks for index updates and auto * unlimited networks over metered networks for index updates and auto
* downloads of app updates. Starting with {@code android-21}, this uses * downloads of app updates. Starting with {@code android-21}, this uses
* {@link android.app.job.JobScheduler} instead. * {@link android.app.job.JobScheduler} instead.
*
* @return a {@link Completable} that schedules the update. If this process is already running,
* a {@code Completable} that completes immediately is returned.
*/ */
public static void scheduleIfStillOnWifi(Context context) { @NonNull
public static Completable scheduleIfStillOnWifi(Context context) {
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
throw new IllegalStateException("This should never be used on android-21 or newer!"); throw new IllegalStateException("This should never be used on android-21 or newer!");
} }
if (isScheduleIfStillOnWifiRunning || !Preferences.get().isBackgroundDownloadAllowed()) { if (isScheduleIfStillOnWifiRunning || !Preferences.get().isBackgroundDownloadAllowed()) {
return; return Completable.complete();
} }
isScheduleIfStillOnWifiRunning = true; isScheduleIfStillOnWifiRunning = true;
new StillOnWifiAsyncTask(context).execute();
}
private static final class StillOnWifiAsyncTask extends AsyncTask<Void, Void, Void> {
private final WeakReference<Context> contextWeakReference;
private StillOnWifiAsyncTask(Context context) {
this.contextWeakReference = new WeakReference<>(context);
}
@Override
protected Void doInBackground(Void... voids) {
Context context = contextWeakReference.get();
try {
Thread.sleep(120000);
if (Preferences.get().isBackgroundDownloadAllowed()) {
Utils.debugLog(TAG, "scheduling update because there is good internet");
schedule(context);
}
} catch (Throwable e) { // NOPMD
Utils.debugLog(TAG, e.getMessage());
}
isScheduleIfStillOnWifiRunning = false;
return null;
}
return Completable.timer(2, TimeUnit.MINUTES)
.andThen(Completable.fromAction(() -> {
if (Preferences.get().isBackgroundDownloadAllowed()) {
Utils.debugLog(TAG, "scheduling update because there is good internet");
schedule(context);
}
isScheduleIfStillOnWifiRunning = false;
}))
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread());
} }
public static void stopNow(Context context) { public static void stopNow(Context context) {
@ -253,6 +250,37 @@ public class UpdateService extends JobIntentService {
} }
} }
/**
* Return a {@link List} of all {@link Repo}s that have either a local
* canonical URL or a local mirror URL. These are repos that can be
* updated and used without using the Internet.
*/
public static List<Repo> getLocalRepos(Context context) {
return getLocalRepos(RepoProvider.Helper.all(context));
}
/**
* Return the repos in the {@code repos} {@link List} that have either a
* local canonical URL or a local mirror URL. These are repos that can be
* updated and used without using the Internet.
*/
public static List<Repo> getLocalRepos(List<Repo> repos) {
ArrayList<Repo> localRepos = new ArrayList<>();
for (Repo repo : repos) {
if (isLocalRepoAddress(repo.address)) {
localRepos.add(repo);
} else {
for (String mirrorAddress : repo.getMirrorList()) {
if (isLocalRepoAddress(mirrorAddress)) {
localRepos.add(repo);
break;
}
}
}
}
return localRepos;
}
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@ -264,7 +292,7 @@ public class UpdateService extends JobIntentService {
.setSmallIcon(R.drawable.ic_refresh) .setSmallIcon(R.drawable.ic_refresh)
.setOngoing(true) .setOngoing(true)
.setCategory(NotificationCompat.CATEGORY_SERVICE) .setCategory(NotificationCompat.CATEGORY_SERVICE)
.setContentTitle(getString(R.string.update_notification_title)); .setContentTitle(getString(R.string.banner_updating_repositories));
appUpdateStatusManager = AppUpdateStatusManager.getInstance(this); appUpdateStatusManager = AppUpdateStatusManager.getInstance(this);
} }
@ -404,22 +432,11 @@ public class UpdateService extends JobIntentService {
if (isLocalRepoAddress(address)) { if (isLocalRepoAddress(address)) {
Utils.debugLog(TAG, "skipping internet check, this is local: " + address); Utils.debugLog(TAG, "skipping internet check, this is local: " + address);
} else if (netState == ConnectivityMonitorService.FLAG_NET_UNAVAILABLE) { } else if (netState == ConnectivityMonitorService.FLAG_NET_UNAVAILABLE) {
boolean foundLocalRepo = false; // keep track of repos that have a local copy in case internet is not available
for (Repo repo : repos) { List<Repo> localRepos = getLocalRepos(repos);
if (isLocalRepoAddress(repo.address)) { if (localRepos.size() > 0) {
foundLocalRepo = true; repos = localRepos;
} else { } else {
for (String mirrorAddress : repo.getMirrorList()) {
if (isLocalRepoAddress(mirrorAddress)) {
foundLocalRepo = true;
//localRepos.add(repo);
//FDroidApp.setLastWorkingMirror(repo.getId(), mirrorAddress);
break;
}
}
}
}
if (!foundLocalRepo) {
Utils.debugLog(TAG, "No internet, cannot update"); Utils.debugLog(TAG, "No internet, cannot update");
if (manualUpdate) { if (manualUpdate) {
Utils.showToastFromService(this, getString(R.string.warning_no_internet), Toast.LENGTH_SHORT); Utils.showToastFromService(this, getString(R.string.warning_no_internet), Toast.LENGTH_SHORT);

View File

@ -27,6 +27,7 @@ import android.content.pm.Signature;
import android.content.res.Resources; import android.content.res.Resources;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
@ -44,19 +45,21 @@ import android.text.style.TypefaceSpan;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Display;
import android.view.View; import android.view.View;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import com.google.zxing.BarcodeFormat;
import androidx.annotation.RequiresApi; import com.google.zxing.encode.Contents;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.google.zxing.encode.QRCodeEncoder;
import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.utils.StorageUtils; import com.nostra13.universalimageloader.utils.StorageUtils;
import org.fdroid.fdroid.compat.FileCompat; import org.fdroid.fdroid.compat.FileCompat;
import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.Repo;
@ -94,6 +97,15 @@ import java.util.TimeZone;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.schedulers.Schedulers;
public final class Utils { public final class Utils {
private static final String TAG = "Utils"; private static final String TAG = "Utils";
@ -480,12 +492,7 @@ public final class Utils {
*/ */
public static DisplayImageOptions.Builder getDefaultDisplayImageOptionsBuilder() { public static DisplayImageOptions.Builder getDefaultDisplayImageOptionsBuilder() {
if (defaultDisplayImageOptionsBuilder == null) { if (defaultDisplayImageOptionsBuilder == null) {
defaultDisplayImageOptionsBuilder = new DisplayImageOptions.Builder() defaultDisplayImageOptionsBuilder = createDefaultDisplayImageOptionsBuilder();
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(false)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY);
} }
return defaultDisplayImageOptionsBuilder; return defaultDisplayImageOptionsBuilder;
} }
@ -497,7 +504,7 @@ public final class Utils {
*/ */
public static DisplayImageOptions getRepoAppDisplayImageOptions() { public static DisplayImageOptions getRepoAppDisplayImageOptions() {
if (repoAppDisplayImageOptions == null) { if (repoAppDisplayImageOptions == null) {
repoAppDisplayImageOptions = getDefaultDisplayImageOptionsBuilder() repoAppDisplayImageOptions = createDefaultDisplayImageOptionsBuilder()
.showImageOnLoading(R.drawable.ic_repo_app_default) .showImageOnLoading(R.drawable.ic_repo_app_default)
.showImageForEmptyUri(R.drawable.ic_repo_app_default) .showImageForEmptyUri(R.drawable.ic_repo_app_default)
.showImageOnFail(R.drawable.ic_repo_app_default) .showImageOnFail(R.drawable.ic_repo_app_default)
@ -507,6 +514,15 @@ public final class Utils {
return repoAppDisplayImageOptions; return repoAppDisplayImageOptions;
} }
private static DisplayImageOptions.Builder createDefaultDisplayImageOptionsBuilder() {
return new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(false)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY);
}
/** /**
* If app has an iconUrl we feed that to UIL, otherwise we ask the PackageManager which will * If app has an iconUrl we feed that to UIL, otherwise we ask the PackageManager which will
* return the app's icon directly when the app is installed. * return the app's icon directly when the app is installed.
@ -979,6 +995,27 @@ public final class Utils {
} }
} }
@NonNull
public static Single<Bitmap> generateQrBitmap(@NonNull final AppCompatActivity activity,
@NonNull final String qrData) {
return Single.fromCallable(() -> {
Display display = activity.getWindowManager().getDefaultDisplay();
Point outSize = new Point();
display.getSize(outSize);
final int x = outSize.x;
final int y = outSize.y;
final int qrCodeDimension = Math.min(x, y);
debugLog(TAG, "generating QRCode Bitmap of " + qrCodeDimension + "x" + qrCodeDimension);
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(qrData, null,
Contents.Type.TEXT, BarcodeFormat.QR_CODE.toString(), qrCodeDimension);
return qrCodeEncoder.encodeAsBitmap();
})
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> Log.e(TAG, "Could not encode QR as bitmap", throwable));
}
/** /**
* Keep an instance of this class as an field in an AppCompatActivity for figuring out whether the on * Keep an instance of this class as an field in an AppCompatActivity for figuring out whether the on
* screen keyboard is currently visible or not. * screen keyboard is currently visible or not.

View File

@ -2,12 +2,15 @@ package org.fdroid.fdroid.acra;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import android.widget.EditText; import android.widget.EditText;
import org.acra.dialog.BaseCrashReportDialog; import org.acra.dialog.BaseCrashReportDialog;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.textfield.TextInputLayout;
public class CrashReportActivity extends BaseCrashReportDialog public class CrashReportActivity extends BaseCrashReportDialog
implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener { implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
@ -29,7 +32,8 @@ public class CrashReportActivity extends BaseCrashReportDialog
dialog.setOnDismissListener(this); dialog.setOnDismissListener(this);
dialog.show(); dialog.show();
comment = (EditText) dialog.findViewById(android.R.id.input); TextInputLayout commentLayout = dialog.findViewById(android.R.id.input);
comment = commentLayout.getEditText();
if (savedInstanceState != null) { if (savedInstanceState != null) {
comment.setText(savedInstanceState.getString(STATE_COMMENT)); comment.setText(savedInstanceState.getString(STATE_COMMENT));
} }

View File

@ -4,13 +4,15 @@ package org.fdroid.fdroid.acra;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.NonNull;
import org.acra.ReportField; import org.acra.ReportField;
import org.acra.collections.ImmutableSet; import org.acra.collections.ImmutableSet;
import org.acra.collector.CrashReportData; import org.acra.collector.CrashReportData;
import org.acra.config.ACRAConfiguration; import org.acra.config.ACRAConfiguration;
import org.acra.sender.ReportSender; import org.acra.sender.ReportSender;
import androidx.annotation.NonNull;
public class CrashReportSender implements ReportSender { public class CrashReportSender implements ReportSender {
private final ACRAConfiguration config; private final ACRAConfiguration config;

View File

@ -1,12 +1,13 @@
package org.fdroid.fdroid.acra; package org.fdroid.fdroid.acra;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull;
import org.acra.config.ACRAConfiguration; import org.acra.config.ACRAConfiguration;
import org.acra.sender.ReportSender; import org.acra.sender.ReportSender;
import org.acra.sender.ReportSenderFactory; import org.acra.sender.ReportSenderFactory;
import androidx.annotation.NonNull;
public class CrashReportSenderFactory implements ReportSenderFactory { public class CrashReportSenderFactory implements ReportSenderFactory {
@NonNull @NonNull
@Override @Override

View File

@ -5,8 +5,6 @@ import android.os.Build;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.util.Log; import android.util.Log;
import androidx.annotation.RequiresApi;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.SanitizedFile; import org.fdroid.fdroid.data.SanitizedFile;
@ -14,6 +12,8 @@ import org.fdroid.fdroid.data.SanitizedFile;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import androidx.annotation.RequiresApi;
/** /**
* This class works only with {@link SanitizedFile} instances to enforce * This class works only with {@link SanitizedFile} instances to enforce
* filtering of the file names from files downloaded from the internet. * filtering of the file names from files downloaded from the internet.

View File

@ -12,11 +12,11 @@ import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.text.TextUtils; import android.text.TextUtils;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.fasterxml.jackson.annotation.JacksonInject; import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import org.fdroid.fdroid.BuildConfig; import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.Schema.ApkTable.Cols; import org.fdroid.fdroid.data.Schema.ApkTable.Cols;
@ -30,6 +30,9 @@ import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/** /**
* Represents a single package of an application. This represents one particular * Represents a single package of an application. This represents one particular
* package of a given application, for info about the app in general, see * package of a given application, for info about the app in general, see

Some files were not shown because too many files have changed in this diff Show More