Compare commits

...

795 Commits

Author SHA1 Message Date
Gilbert Gilb's
37c10e7b48 Show a dialog after picking PCloud file storage.
Not seeing any file was confusing to users.

See https://github.com/PhilippC/keepass2android/issues/794
See https://github.com/PhilippC/keepass2android/issues/796
2019-05-25 21:44:48 +02:00
Gilbert Gilb's
02b8292a2e Use new option to overwrite file in PCloud file storage. 2019-05-25 21:36:39 +02:00
Gilbert Gilb's
2d1909c227 Update PCloud SDK to 1.1.0. 2019-05-25 21:35:54 +02:00
PhilippC
87cfa4c4d4 Merge pull request #766 from PhilippC/l10n_master
New Crowdin translations
2019-04-01 10:44:12 +02:00
PhilippC
58ec829d1a New translations strings.xml (Portuguese) 2019-04-01 10:39:46 +02:00
PhilippC
90fd2daa01 New translations strings.xml (Danish) 2019-04-01 10:39:05 +02:00
Philipp Crocoll
d0749324c9 Merge remote-tracking branch 'remotes/origin/l10n_master'
# Resolved Conflicts:
#	src/keepass2android/Resources/values-da/strings.xml
#	src/keepass2android/Resources/values-de/strings.xml
#	src/keepass2android/Resources/values-nl/strings.xml
#	src/keepass2android/Resources/values-ru/strings.xml
2019-04-01 10:36:15 +02:00
PhilippC
a43f72d18a New translations strings.xml (German) 2019-04-01 10:29:58 +02:00
PhilippC
3d691088be New translations strings.xml (Portuguese, Brazilian) 2019-04-01 10:29:53 +02:00
Philipp Crocoll
bca3becadb improved language in resource strings 2019-04-01 10:21:50 +02:00
PhilippC
d937fbe7ad New translations strings.xml (Danish) 2019-04-01 04:10:10 +02:00
PhilippC
c13e00871d New translations strings.xml (Danish) 2019-04-01 03:50:10 +02:00
PhilippC
b5b716da4c New translations strings.xml (Danish) 2019-04-01 03:30:09 +02:00
PhilippC
45d2a8e0b2 New translations strings.xml (Danish) 2019-04-01 03:20:10 +02:00
PhilippC
d47c948699 New translations strings.xml (Danish) 2019-04-01 03:10:11 +02:00
PhilippC
fdf36babba New translations strings.xml (Danish) 2019-04-01 03:00:12 +02:00
PhilippC
d47411264e New translations strings.xml (Danish) 2019-04-01 02:50:11 +02:00
PhilippC
b9ebad7942 New translations strings.xml (Danish) 2019-04-01 02:40:09 +02:00
PhilippC
2878cc1cb5 New translations strings.xml (Danish) 2019-04-01 02:10:11 +02:00
PhilippC
9277d76f37 New translations strings.xml (Danish) 2019-04-01 02:00:21 +02:00
PhilippC
b7b1301334 New translations strings.xml (Turkish) 2019-03-31 14:10:11 +02:00
PhilippC
954dd73ffa New translations strings.xml (Turkish) 2019-03-31 14:00:12 +02:00
PhilippC
7aeab98c5b New translations strings.xml (Portuguese) 2019-03-30 00:00:10 +01:00
PhilippC
51123d60d3 New translations strings.xml (Portuguese) 2019-03-29 23:50:11 +01:00
PhilippC
395d4b5a97 New translations strings.xml (Hungarian) 2019-03-29 15:00:15 +01:00
PhilippC
654f025f64 New translations strings.xml (Hungarian) 2019-03-29 14:50:11 +01:00
PhilippC
8a9ccea5d3 New translations strings.xml (Hungarian) 2019-03-29 14:40:11 +01:00
PhilippC
92e00075c6 New translations strings.xml (Hungarian) 2019-03-29 14:30:11 +01:00
PhilippC
624e78e734 New translations strings.xml (Hungarian) 2019-03-29 14:20:11 +01:00
PhilippC
76bb8822fa New translations strings.xml (Hungarian) 2019-03-29 14:10:09 +01:00
PhilippC
e3cba097fa New translations strings.xml (Hungarian) 2019-03-29 14:00:13 +01:00
PhilippC
c812fca8c1 New translations strings.xml (Hungarian) 2019-03-29 13:50:10 +01:00
PhilippC
f86f4ee18c New translations strings.xml (Hungarian) 2019-03-29 13:20:09 +01:00
PhilippC
dafed9786e New translations strings.xml (Hungarian) 2019-03-29 13:10:10 +01:00
PhilippC
cd3a119053 New translations strings.xml (Hungarian) 2019-03-29 13:00:14 +01:00
PhilippC
f143a171aa New translations strings.xml (Hungarian) 2019-03-29 12:50:13 +01:00
PhilippC
ee93d7df82 New translations strings.xml (Hungarian) 2019-03-29 12:40:11 +01:00
PhilippC
61a3bcc53d New translations strings.xml (Hungarian) 2019-03-29 12:30:12 +01:00
PhilippC
17a46eb92c New translations strings.xml (Hungarian) 2019-03-29 12:00:11 +01:00
PhilippC
14b121a8ba New translations strings.xml (Danish) 2019-03-29 01:50:11 +01:00
PhilippC
41b57417e5 New translations strings.xml (Russian) 2019-03-28 20:10:13 +01:00
PhilippC
bb492c3043 New translations strings.xml (Slovak) 2019-03-28 18:50:14 +01:00
PhilippC
b683dca67c New translations strings.xml (Slovak) 2019-03-28 18:40:11 +01:00
PhilippC
b6e6024bda New translations strings.xml (German) 2019-03-28 15:30:31 +01:00
PhilippC
2b3a95e21d New translations strings.xml (German) 2019-03-28 15:20:13 +01:00
PhilippC
de9c27f1f5 New translations strings.xml (Portuguese, Brazilian) 2019-03-28 13:40:13 +01:00
PhilippC
85c9cb26b1 New translations strings.xml (Portuguese, Brazilian) 2019-03-28 13:30:13 +01:00
PhilippC
8ffa27e93d New translations strings.xml (Italian) 2019-03-28 13:20:19 +01:00
PhilippC
ea743fc2c5 New translations strings.xml (Portuguese, Brazilian) 2019-03-28 13:20:13 +01:00
PhilippC
7fab9aab00 New translations strings.xml (Italian) 2019-03-28 13:10:18 +01:00
PhilippC
444e224d41 New translations strings.xml (Portuguese, Brazilian) 2019-03-28 13:10:12 +01:00
PhilippC
9fde19f1ce New translations strings.xml (Portuguese) 2019-03-28 12:20:22 +01:00
PhilippC
4e085b5dca New translations strings.xml (Italian) 2019-03-28 12:20:16 +01:00
PhilippC
06ab58cc07 New translations strings.xml (Danish) 2019-03-28 11:50:12 +01:00
PhilippC
9dae1746ec New translations strings.xml (Danish) 2019-03-28 11:30:11 +01:00
PhilippC
db87191f1f New translations strings.xml (Danish) 2019-03-28 11:20:10 +01:00
PhilippC
76abe79b6d New translations strings.xml (Japanese) 2019-03-28 10:30:12 +01:00
PhilippC
970bc29e01 New translations strings.xml (Japanese) 2019-03-28 10:20:13 +01:00
PhilippC
79a3262659 New translations strings.xml (French) 2019-03-28 10:10:11 +01:00
PhilippC
3add6d64ef New translations strings.xml (French) 2019-03-28 09:50:12 +01:00
PhilippC
43168b18d1 New translations strings.xml (French) 2019-03-28 09:40:11 +01:00
PhilippC
6970b42456 New translations strings.xml (Polish) 2019-03-28 09:10:17 +01:00
PhilippC
a545b96601 New translations strings.xml (Spanish) 2019-03-28 09:10:11 +01:00
PhilippC
59b66409e8 New translations strings.xml (Chinese Traditional) 2019-03-28 09:00:13 +01:00
PhilippC
25c50bbcaf New translations strings.xml (Chinese Traditional) 2019-03-28 08:50:09 +01:00
PhilippC
a9a5df00d2 New translations strings.xml (German) 2019-03-28 08:40:09 +01:00
PhilippC
5f4d9c29dc New translations strings.xml (German) 2019-03-28 08:10:09 +01:00
PhilippC
31e158e39b New translations strings.xml (Ukrainian) 2019-03-28 08:00:10 +01:00
PhilippC
25af5844be New translations strings.xml (German) 2019-03-28 07:50:10 +01:00
PhilippC
f79bb49af1 New translations strings.xml (Slovenian) 2019-03-28 07:30:19 +01:00
PhilippC
2756bae656 New translations strings.xml (Italian) 2019-03-28 07:30:14 +01:00
PhilippC
b574b55f84 New translations strings.xml (Dutch) 2019-03-28 07:30:09 +01:00
PhilippC
76ef1c4033 New translations strings.xml (Dutch) 2019-03-28 07:20:09 +01:00
PhilippC
409deaee9d New translations strings.xml (Italian) 2019-03-28 07:10:16 +01:00
PhilippC
8396e18283 New translations strings.xml (Dutch) 2019-03-28 07:10:10 +01:00
PhilippC
5e952e06ff New translations strings.xml (Italian) 2019-03-28 07:00:12 +01:00
PhilippC
7b6dc3d773 New translations strings.xml (Italian) 2019-03-28 06:50:10 +01:00
PhilippC
1759b67921 New translations strings.xml (Ukrainian) 2019-03-28 06:10:10 +01:00
PhilippC
1307b0e5d1 New translations strings.xml (Ukrainian) 2019-03-28 05:50:10 +01:00
PhilippC
c1af6994bf New translations strings.xml (Ukrainian) 2019-03-28 05:40:09 +01:00
PhilippC
d09c15e5b8 New translations strings.xml (Chinese Simplified) 2019-03-28 05:30:23 +01:00
PhilippC
ea98b170d9 New translations strings.xml (Russian) 2019-03-28 05:30:17 +01:00
PhilippC
c67f4e45c7 New translations strings.xml (Ukrainian) 2019-03-28 05:30:11 +01:00
PhilippC
c21a5afe94 New translations strings.xml (Chinese Simplified) 2019-03-28 05:20:15 +01:00
PhilippC
49de16f0f3 New translations strings.xml (Russian) 2019-03-28 05:20:09 +01:00
PhilippC
6d60afadf4 New translations strings.xml (Chinese Simplified) 2019-03-28 05:10:09 +01:00
PhilippC
c6751af075 New translations strings.xml (Vietnamese) 2019-03-28 05:02:50 +01:00
PhilippC
d41aa389a7 New translations strings.xml (Dutch) 2019-03-28 05:02:46 +01:00
PhilippC
f95986fd7a New translations strings.xml (Czech) 2019-03-28 05:02:40 +01:00
PhilippC
ac522bce43 New translations strings.xml (Croatian) 2019-03-28 05:02:34 +01:00
PhilippC
6e0729c3b3 New translations strings.xml (Chinese Traditional) 2019-03-28 05:02:30 +01:00
PhilippC
9ce674da2b New translations strings.xml (Chinese Simplified) 2019-03-28 05:02:26 +01:00
PhilippC
da8a8e7e77 New translations strings.xml (Catalan) 2019-03-28 05:02:22 +01:00
PhilippC
566a1088bd New translations strings.xml (Bulgarian) 2019-03-28 05:02:16 +01:00
PhilippC
11f1f07653 New translations strings.xml (Finnish) 2019-03-28 05:02:11 +01:00
PhilippC
45194bb26f New translations strings.xml (Basque) 2019-03-28 05:02:05 +01:00
PhilippC
1f6440189f New translations strings.xml (Russian) 2019-03-28 05:01:59 +01:00
PhilippC
60e98d87d8 New translations strings.xml (Danish) 2019-03-28 05:01:54 +01:00
PhilippC
f560124088 New translations strings.xml (German) 2019-03-28 05:01:48 +01:00
PhilippC
7521d0b787 New translations strings.xml (Portuguese, Brazilian) 2019-03-28 05:01:45 +01:00
PhilippC
c45e52f571 New translations strings.xml (Ukrainian) 2019-03-28 04:45:19 +01:00
PhilippC
275920e5be New translations strings.xml (Greek) 2019-03-28 04:45:16 +01:00
PhilippC
7045c6ee8d New translations strings.xml (Turkish) 2019-03-28 04:45:11 +01:00
PhilippC
7a7b65e8c6 New translations strings.xml (Azerbaijani) 2019-03-28 04:45:04 +01:00
PhilippC
261526b4d1 New translations strings.xml (Arabic) 2019-03-28 04:44:58 +01:00
PhilippC
bc74c91a2c New translations strings.xml (French) 2019-03-28 04:44:53 +01:00
PhilippC
ab47543df0 New translations strings.xml (Hebrew) 2019-03-28 04:44:47 +01:00
PhilippC
3a601468a9 New translations strings.xml (Swedish) 2019-03-28 04:44:42 +01:00
PhilippC
f2002e2b90 New translations strings.xml (Slovenian) 2019-03-28 04:44:38 +01:00
PhilippC
29031167d6 New translations strings.xml (Slovak) 2019-03-28 04:44:32 +01:00
PhilippC
7305ac47c3 New translations strings.xml (Serbian (Cyrillic)) 2019-03-28 04:44:26 +01:00
PhilippC
2aec6c9e4b New translations strings.xml (Romanian) 2019-03-28 04:44:22 +01:00
PhilippC
5a2cdf3cda New translations strings.xml (Portuguese) 2019-03-28 04:44:18 +01:00
PhilippC
a943df63fc New translations strings.xml (Polish) 2019-03-28 04:44:13 +01:00
PhilippC
ca771abebe New translations strings.xml (Galician) 2019-03-28 04:44:07 +01:00
PhilippC
010db6148d New translations strings.xml (Persian) 2019-03-28 04:44:01 +01:00
PhilippC
8f065f480c New translations strings.xml (Norwegian Bokmal) 2019-03-28 04:43:57 +01:00
PhilippC
f163f9382f New translations strings.xml (Korean) 2019-03-28 04:43:52 +01:00
PhilippC
e752244b5f New translations strings.xml (Japanese) 2019-03-28 04:43:47 +01:00
PhilippC
4bbb958a05 New translations strings.xml (Italian) 2019-03-28 04:43:43 +01:00
PhilippC
d1ddfed8dd New translations strings.xml (Indonesian) 2019-03-28 04:43:39 +01:00
PhilippC
bdb39f203a New translations strings.xml (Hungarian) 2019-03-28 04:43:34 +01:00
PhilippC
1bcb6aabe7 New translations strings.xml (Norwegian Nynorsk) 2019-03-28 04:43:30 +01:00
PhilippC
90b09b0f7e New translations strings.xml (Spanish) 2019-03-28 04:43:26 +01:00
Philipp Crocoll
4e6e0a0e73 improve English texts 2019-03-28 04:42:40 +01:00
Philipp Crocoll
ad4c764adb fix potential crashes when database has been closed and recreating activities 2019-03-28 04:42:24 +01:00
PhilippC
2265432ec4 New translations strings.xml (German) 2019-03-28 04:40:11 +01:00
PhilippC
bb45e60a3f New translations strings.xml (French) 2019-03-27 22:20:09 +01:00
PhilippC
b1ff92d63e New translations strings.xml (French) 2019-03-27 22:10:15 +01:00
Philipp Crocoll
016864edfc fix potential crash 2019-03-27 19:20:16 +01:00
PhilippC
dc5133e676 New translations strings.xml (Greek) 2019-03-27 01:00:12 +01:00
PhilippC
1fbd10c918 New translations strings.xml (Greek) 2019-03-27 00:50:09 +01:00
PhilippC
4cd219ab32 New translations strings.xml (Greek) 2019-03-27 00:40:10 +01:00
PhilippC
871e84fec9 New translations strings.xml (Greek) 2019-03-27 00:30:11 +01:00
PhilippC
08ce132587 New translations strings.xml (Greek) 2019-03-27 00:20:09 +01:00
PhilippC
4c58d8df72 New translations strings.xml (Greek) 2019-03-27 00:10:11 +01:00
PhilippC
bf554d2417 New translations strings.xml (Greek) 2019-03-27 00:00:09 +01:00
PhilippC
631cd8e35f New translations strings.xml (Greek) 2019-03-26 23:50:12 +01:00
PhilippC
f46c4d8054 New translations strings.xml (Russian) 2019-03-26 22:50:10 +01:00
PhilippC
0010713b78 New translations strings.xml (Russian) 2019-03-26 22:40:13 +01:00
PhilippC
f5bfd4f8f2 New translations strings.xml (Russian) 2019-03-26 22:30:09 +01:00
PhilippC
6d04d2f579 New translations strings.xml (Russian) 2019-03-26 22:20:10 +01:00
PhilippC
0d3cef1626 New translations strings.xml (Chinese Traditional) 2019-03-25 18:50:10 +01:00
PhilippC
4d251becb0 New translations strings.xml (Chinese Traditional) 2019-03-25 18:40:09 +01:00
PhilippC
372d4c4bf3 New translations strings.xml (Slovenian) 2019-03-25 11:20:12 +01:00
PhilippC
2dbda89973 New translations strings.xml (German) 2019-03-25 11:12:54 +01:00
PhilippC
2f55bbddd8 New translations strings.xml (Portuguese) 2019-03-25 11:11:54 +01:00
PhilippC
928773b183 New translations strings.xml (German) 2019-03-25 10:50:13 +01:00
PhilippC
bc9803cbc4 New translations strings.xml (German) 2019-03-25 10:40:10 +01:00
Philipp Crocoll
fca8f5efbc remove unused strings 2019-03-25 10:34:19 +01:00
PhilippC
f09fe4f7e2 New translations strings.xml (German) 2019-03-25 10:30:12 +01:00
PhilippC
de3bc0ff6c New translations strings.xml (Japanese) 2019-03-25 10:20:11 +01:00
Philipp Crocoll
c4a1b6a82e avoid opening password activity when database is already open, closes https://github.com/PhilippC/keepass2android/issues/706 2019-03-25 10:10:19 +01:00
PhilippC
bd08dd54e2 New translations strings.xml (Chinese Traditional) 2019-03-25 09:33:14 +01:00
PhilippC
b1f93fdb75 New translations strings.xml (Chinese Simplified) 2019-03-25 09:33:07 +01:00
PhilippC
51599b3f1a New translations strings.xml (Catalan) 2019-03-25 09:33:02 +01:00
PhilippC
1b753877a9 New translations strings.xml (Finnish) 2019-03-25 09:32:55 +01:00
PhilippC
d33ffa9d22 New translations strings.xml (Portuguese, Brazilian) 2019-03-25 09:32:36 +01:00
PhilippC
df710e523a New translations strings.xml (Turkish) 2019-03-25 09:32:23 +01:00
PhilippC
7d218e0706 New translations strings.xml (Slovenian) 2019-03-25 09:31:57 +01:00
PhilippC
88127a4858 New translations strings.xml (Slovak) 2019-03-25 09:31:51 +01:00
PhilippC
63f2a6f902 New translations strings.xml (Japanese) 2019-03-25 09:31:14 +01:00
Philipp Crocoll
d8286eb639 Merge branch 'l10n_master' of https://github.com/PhilippC/keepass2android
# Resolved Conflicts:
#	src/keepass2android/Resources/values-cs/strings.xml
#	src/keepass2android/Resources/values-da/strings.xml
#	src/keepass2android/Resources/values-de/strings.xml
#	src/keepass2android/Resources/values-hu/strings.xml
#	src/keepass2android/Resources/values-nl/strings.xml
#	src/keepass2android/Resources/values-pl/strings.xml
#	src/keepass2android/Resources/values-ru/strings.xml
#	src/keepass2android/Resources/values-tr/strings.xml
2019-03-25 09:27:27 +01:00
PhilippC
668fa46a98 New translations strings.xml (Slovenian) 2019-03-25 09:15:11 +01:00
PhilippC
e16a671a26 New translations strings.xml (Portuguese) 2019-03-25 09:14:56 +01:00
Philipp Crocoll
7f89ef358c Merge branch 'master' of https://github.com/PhilippC/keepass2android 2019-03-25 09:10:05 +01:00
Philipp Crocoll
e0df319279 try to proceed to password activity also if file storage setup is required, closes https://github.com/PhilippC/keepass2android/issues/416 2019-03-25 09:09:55 +01:00
Philipp Crocoll
61c7a260b4 improve child database configuration activity 2019-03-25 09:08:48 +01:00
Philipp Crocoll
f26fce63ad avoid crash when ROM does not support fingerprint encryption, closes https://github.com/PhilippC/keepass2android/issues/155 2019-03-25 09:08:32 +01:00
Philipp Crocoll
74c3c96b43 Merge branch 'master' of c:/ph/keepass2android 2019-03-25 09:05:39 +01:00
PhilippC
765b020152 New translations strings.xml (Chinese Traditional) 2019-03-25 05:30:11 +01:00
PhilippC
59c05235f6 New translations strings.xml (Chinese Traditional) 2019-03-25 05:20:10 +01:00
PhilippC
92a4131c88 New translations strings.xml (Chinese Traditional) 2019-03-25 05:10:12 +01:00
Philipp Crocoll
540e14bbe7 1.07-pre8 2019-03-24 20:27:35 +01:00
PhilippC
0ebd355edd New translations strings.xml (Slovak) 2019-03-23 23:10:10 +01:00
PhilippC
68d4dfed04 New translations strings.xml (Slovenian) 2019-03-23 19:40:09 +01:00
PhilippC
37a482d2e4 New translations strings.xml (Slovenian) 2019-03-23 19:30:09 +01:00
PhilippC
b79cc65728 New translations strings.xml (Japanese) 2019-03-23 16:10:10 +01:00
PhilippC
78977c7e31 New translations strings.xml (Japanese) 2019-03-23 16:00:11 +01:00
PhilippC
1957fc5345 New translations strings.xml (Turkish) 2019-03-23 07:50:09 +01:00
PhilippC
49cefff75d New translations strings.xml (Turkish) 2019-03-23 07:30:08 +01:00
PhilippC
2ebb145b7b New translations strings.xml (Turkish) 2019-03-23 07:20:17 +01:00
PhilippC
0a6f1394e4 New translations strings.xml (Turkish) 2019-03-23 07:10:11 +01:00
PhilippC
1310913281 New translations strings.xml (Slovenian) 2019-03-22 20:40:10 +01:00
PhilippC
c245c5ade3 New translations strings.xml (Slovenian) 2019-03-22 20:20:10 +01:00
PhilippC
9e6f45a59b New translations strings.xml (Slovenian) 2019-03-22 20:00:18 +01:00
PhilippC
f6a78c8890 New translations strings.xml (Slovenian) 2019-03-22 16:00:15 +01:00
PhilippC
76717fa3cb New translations strings.xml (Slovenian) 2019-03-22 13:10:10 +01:00
PhilippC
a19230393d New translations strings.xml (Chinese Simplified) 2019-03-22 08:00:13 +01:00
PhilippC
0b89969a33 New translations strings.xml (Chinese Simplified) 2019-03-22 07:50:10 +01:00
PhilippC
bbe97230d2 New translations strings.xml (German) 2019-03-22 05:40:10 +01:00
PhilippC
ee0161737c New translations strings.xml (Catalan) 2019-03-22 05:20:10 +01:00
Philipp Crocoll
e7e0b91703 fix potential crash when changing offline cache preference 2019-03-22 04:59:44 +01:00
PhilippC
dbcdf71bbe New translations strings.xml (French) 2019-03-21 21:50:12 +01:00
PhilippC
779615c09a New translations strings.xml (Finnish) 2019-03-21 06:20:11 +01:00
PhilippC
1c3a1ce53c New translations strings.xml (Finnish) 2019-03-21 06:10:09 +01:00
PhilippC
981c524e3f New translations strings.xml (Croatian) 2019-03-21 05:22:26 +01:00
PhilippC
44a7d68f31 New translations strings.xml (Chinese Traditional) 2019-03-21 05:22:22 +01:00
PhilippC
ae858e3dc4 New translations strings.xml (Chinese Simplified) 2019-03-21 05:22:17 +01:00
PhilippC
22fd23a31d New translations strings.xml (Catalan) 2019-03-21 05:22:13 +01:00
PhilippC
2babe87d6d New translations strings.xml (Russian) 2019-03-21 05:21:59 +01:00
PhilippC
95a8b3fe34 New translations strings.xml (German) 2019-03-21 05:21:50 +01:00
PhilippC
32c526a26a New translations strings.xml (Portuguese, Brazilian) 2019-03-21 05:21:46 +01:00
Philipp Crocoll
b2adfad2ee catch potential file not found exceptions 2019-03-21 04:27:44 +01:00
Philipp Crocoll
ee5a8534a7 catch all exceptions when stopping fingerprint, maybe there is a java exception 2019-03-21 04:15:04 +01:00
Philipp Crocoll
80ba3b969d allow to turn off saving of credentials through Autofill for the whole app. Closes https://github.com/PhilippC/keepass2android/issues/488. Allow to re-enable disabled autofill targets in the app preferences. Closes https://github.com/PhilippC/keepass2android/issues/715 2019-03-21 04:13:29 +01:00
Philipp Crocoll
83bd6911c8 Merge branch 'master' of c:/ph/keepass2android 2019-03-19 22:08:28 +01:00
Philipp Crocoll
6c66f6199c 1.07-pre7 2019-03-19 22:08:19 +01:00
Philipp Crocoll
c11731541c reenable search suggestion listener 2019-03-19 22:07:38 +01:00
PhilippC
609593ebd0 New translations strings.xml (French) 2019-03-19 21:51:42 +01:00
PhilippC
85b867a5ca New translations strings.xml (Slovak) 2019-03-19 21:51:27 +01:00
PhilippC
a3690051eb New translations strings.xml (Portuguese) 2019-03-19 21:51:15 +01:00
PhilippC
ecb44a2611 New translations strings.xml (Polish) 2019-03-19 21:51:08 +01:00
PhilippC
7898ea9ba7 New translations strings.xml (Japanese) 2019-03-19 21:50:50 +01:00
PhilippC
90a2029f3d New translations strings.xml (Italian) 2019-03-19 21:50:45 +01:00
PhilippC
1d9a9ea658 New translations strings.xml (Hungarian) 2019-03-19 21:50:36 +01:00
PhilippC
e88f80eda3 New translations strings.xml (Spanish) 2019-03-19 21:50:27 +01:00
Philipp Crocoll
025e2f415d improve logging output 2019-03-19 21:49:04 +01:00
Philipp Crocoll
e113ca79de add missing file 2019-03-19 21:23:50 +01:00
Philipp Crocoll
f988c44440 update changelog 2019-03-19 21:20:07 +01:00
Philipp Crocoll
37cda26e27 fix potential crashes in AutoFill service 2019-03-19 21:13:16 +01:00
Philipp Crocoll
65c2da9afa implement really hacky workaround for another crash on Samsung devices with Android 9 2019-03-19 20:58:37 +01:00
Philipp Crocoll
434b7b756b Merge branch 'master' of c:/ph/keepass2android 2019-03-18 05:51:54 +01:00
Philipp Crocoll
9dfcab6c1c 1.07-pre6 2019-03-18 05:50:56 +01:00
Philipp Crocoll
9f39f4e377 set NoHistory flag for SwitchImeActivity, improves switching back to KP2A 2019-03-18 05:44:01 +01:00
Philipp Crocoll
58da4284ac Merge branch 'master' of c:/ph/keepass2android
# Resolved Conflicts:
#	src/keepass2android/Properties/AndroidManifest_net.xml
#	src/keepass2android/Resources/values/strings.xml
2019-03-18 05:12:05 +01:00
Philipp Crocoll
55787ff6cf fix crash on Samsung devices with Android 9, fix problem with bringing up keyboard 2019-03-18 05:09:20 +01:00
Philipp Crocoll
3b93610e43 fix crash when sending debug log (closes https://github.com/PhilippC/keepass2android/issues/264) 2019-03-18 05:08:34 +01:00
Philipp Crocoll
40f3066ee0 avoid potential crashes when opening child databases (caused by network on main thread or URLs without username/password), fixes https://github.com/PhilippC/keepass2android/issues/728 2019-03-18 03:56:34 +01:00
PhilippC
2108aac41c New translations strings.xml (Russian) 2019-03-15 10:50:12 +01:00
PhilippC
68f8300395 New translations strings.xml (Russian) 2019-03-15 10:40:10 +01:00
PhilippC
325a61912e New translations strings.xml (Russian) 2019-03-15 10:30:10 +01:00
PhilippC
7363c88fce New translations strings.xml (Russian) 2019-03-15 10:20:09 +01:00
PhilippC
0b0f95c65c New translations strings.xml (Danish) 2019-03-14 18:20:18 +01:00
PhilippC
354675f1e5 New translations strings.xml (German) 2019-03-13 14:50:13 +01:00
PhilippC
7a769f283b New translations strings.xml (German) 2019-03-13 14:40:14 +01:00
PhilippC
3dc67d5978 New translations strings.xml (Portuguese, Brazilian) 2019-03-12 15:40:09 +01:00
PhilippC
d3a0d71857 New translations strings.xml (Portuguese, Brazilian) 2019-03-12 15:30:16 +01:00
PhilippC
72f7534a5f New translations strings.xml (Portuguese, Brazilian) 2019-03-12 15:20:13 +01:00
PhilippC
27a733cbed New translations strings.xml (Portuguese, Brazilian) 2019-03-12 15:10:13 +01:00
Philipp Crocoll
92a0ce98bb make nfc implementation compatible to Yubikey NEO 5 (closes https://github.com/PhilippC/keepass2android/issues/564) 2019-03-11 11:46:02 +01:00
Philipp Crocoll
84c9632508 using public suffix to determine canonical domains which fixes the aliexpress issue (fixes https://github.com/PhilippC/keepass2android/issues/711) 2019-03-11 10:56:55 +01:00
Philipp Crocoll
22c2b406db more attempts to get OneDrive for business working 2019-03-11 09:43:42 +01:00
PhilippC
bc374a1317 New translations strings.xml (Spanish) 2019-03-11 09:10:09 +01:00
Philipp Crocoll
0bf82a999a don't refuse to load databases with invalid times 2019-03-11 02:52:56 +01:00
PhilippC
453a8459ac New translations strings.xml (Turkish) 2019-03-10 01:20:10 +01:00
PhilippC
53f6ddad22 New translations strings.xml (Ukrainian) 2019-03-09 22:10:08 +01:00
PhilippC
14bd128931 New translations strings.xml (Greek) 2019-03-08 23:30:11 +01:00
PhilippC
b0b8daa03d New translations strings.xml (Greek) 2019-03-08 23:20:08 +01:00
PhilippC
940cd70f64 New translations strings.xml (Spanish) 2019-03-08 08:40:09 +01:00
PhilippC
d8cdef0622 New translations strings.xml (Spanish) 2019-03-08 08:30:12 +01:00
PhilippC
44a7cfe32e New translations strings.xml (Spanish) 2019-03-08 08:20:09 +01:00
PhilippC
8584352e21 New translations strings.xml (Turkish) 2019-03-07 12:50:10 +01:00
PhilippC
1c39d027e0 New translations strings.xml (Turkish) 2019-03-07 12:40:12 +01:00
PhilippC
ce82e2cdcf New translations strings.xml (Arabic) 2019-03-06 07:30:10 +01:00
PhilippC
a8492f75cd New translations strings.xml (Arabic) 2019-03-06 07:20:10 +01:00
PhilippC
03afb38aa3 New translations strings.xml (Portuguese) 2019-03-04 19:20:10 +01:00
PhilippC
acc2acce2c New translations strings.xml (Portuguese) 2019-03-04 18:50:08 +01:00
PhilippC
3a612864f8 New translations strings.xml (Portuguese) 2019-03-04 18:40:09 +01:00
PhilippC
7e1789a3f4 New translations strings.xml (Slovak) 2019-03-03 13:10:10 +01:00
PhilippC
69dea794e1 New translations strings.xml (Dutch) 2019-03-02 14:50:08 +01:00
PhilippC
4e024bd8b1 New translations strings.xml (Dutch) 2019-03-02 14:40:10 +01:00
PhilippC
6078e511aa New translations strings.xml (Dutch) 2019-03-02 14:30:09 +01:00
PhilippC
58574cd824 New translations strings.xml (Spanish) 2019-02-27 14:30:11 +01:00
PhilippC
635fa99cf2 New translations strings.xml (Spanish) 2019-02-27 14:00:12 +01:00
PhilippC
074d71cef7 New translations strings.xml (Spanish) 2019-02-27 09:20:12 +01:00
PhilippC
027075b1b2 New translations strings.xml (Czech) 2019-02-24 00:00:09 +01:00
PhilippC
898ad42f96 New translations strings.xml (Czech) 2019-02-23 23:50:10 +01:00
PhilippC
c87ffeff71 New translations strings.xml (Japanese) 2019-02-22 11:20:10 +01:00
PhilippC
40f0744adc New translations strings.xml (Japanese) 2019-02-22 11:10:09 +01:00
PhilippC
eba555f260 New translations strings.xml (Japanese) 2019-02-22 11:00:12 +01:00
PhilippC
e7db208a40 New translations strings.xml (Russian) 2019-02-20 20:40:11 +01:00
PhilippC
69399bb328 New translations strings.xml (Italian) 2019-02-18 20:20:14 +01:00
PhilippC
749e928d66 New translations strings.xml (Italian) 2019-02-18 20:10:09 +01:00
PhilippC
a3b8690609 New translations strings.xml (Polish) 2019-02-18 12:40:12 +01:00
PhilippC
340e6794ca New translations strings.xml (German) 2019-02-17 02:50:09 +01:00
PhilippC
7a23152cee New translations strings.xml (German) 2019-02-17 02:40:09 +01:00
PhilippC
d00f71884a New translations strings.xml (German) 2019-02-17 02:30:11 +01:00
PhilippC
587014159d New translations strings.xml (Chinese Simplified) 2019-02-16 15:20:11 +01:00
PhilippC
e2cb3691e4 New translations strings.xml (Chinese Simplified) 2019-02-16 15:10:09 +01:00
PhilippC
a40be3b658 New translations strings.xml (Chinese Simplified) 2019-02-16 13:50:08 +01:00
PhilippC
598d7c699a New translations strings.xml (Chinese Simplified) 2019-02-16 13:40:11 +01:00
PhilippC
23c9b9f2d9 New translations strings.xml (Norwegian Bokmal) 2019-02-15 08:50:09 +01:00
PhilippC
22aeff708a New translations strings.xml (Chinese Simplified) 2019-02-14 08:10:11 +01:00
PhilippC
e9b7b935ee New translations strings.xml (Chinese Simplified) 2019-02-14 08:00:15 +01:00
PhilippC
eb0d9ec482 New translations strings.xml (Chinese Simplified) 2019-02-14 07:50:11 +01:00
PhilippC
cfd0d72100 New translations strings.xml (Polish) 2019-02-11 20:00:15 +01:00
PhilippC
f615dc265a New translations strings.xml (Polish) 2019-02-11 19:50:12 +01:00
PhilippC
53c4971c4e New translations strings.xml (Polish) 2019-02-11 19:40:12 +01:00
PhilippC
3a98fa9f53 New translations strings.xml (Japanese) 2019-02-11 08:20:11 +01:00
PhilippC
6ed5386c12 New translations strings.xml (German) 2019-02-11 04:10:09 +01:00
PhilippC
a998a7f92b New translations strings.xml (German) 2019-02-11 04:00:09 +01:00
PhilippC
3218989b13 New translations strings.xml (German) 2019-02-11 03:50:09 +01:00
PhilippC
3aff954063 New translations strings.xml (Catalan) 2019-02-09 16:20:09 +01:00
PhilippC
11e824c133 New translations strings.xml (Catalan) 2019-02-09 16:10:09 +01:00
PhilippC
a26662a813 New translations strings.xml (Catalan) 2019-02-09 10:10:10 +01:00
PhilippC
007838197b New translations strings.xml (Catalan) 2019-02-09 10:00:09 +01:00
PhilippC
0ad82d5b91 New translations strings.xml (Catalan) 2019-02-09 09:10:08 +01:00
PhilippC
52e47a62d2 New translations strings.xml (Korean) 2019-02-08 17:40:11 +01:00
PhilippC
cbaaf3ee54 New translations strings.xml (Chinese Traditional) 2019-02-08 16:10:12 +01:00
PhilippC
26f26ee35d New translations strings.xml (Chinese Traditional) 2019-02-08 16:00:13 +01:00
PhilippC
0102ac77e3 New translations strings.xml (Chinese Traditional) 2019-02-08 15:50:10 +01:00
PhilippC
d24101bee2 New translations strings.xml (Chinese Traditional) 2019-02-08 15:40:11 +01:00
PhilippC
36cced5ce7 New translations strings.xml (Chinese Traditional) 2019-02-08 15:30:13 +01:00
PhilippC
87eb537ebe New translations strings.xml (French) 2019-02-07 00:40:11 +01:00
PhilippC
86fdc17d2a New translations strings.xml (Slovak) 2019-02-06 21:21:11 +01:00
PhilippC
bd8763c62f New translations strings.xml (Portuguese, Brazilian) 2019-02-06 21:20:54 +01:00
Philipp Crocoll
bc917d41ad 1.07-pre5 2019-02-06 21:13:59 +01:00
Philipp Crocoll
68b60b427a fix missing native keytransform, closes #630 2019-02-06 21:13:46 +01:00
PhilippC
c9e64c53ec New translations strings.xml (Slovak) 2019-02-06 16:10:18 +01:00
PhilippC
6ba6c6bac7 New translations strings.xml (Slovak) 2019-02-06 16:00:26 +01:00
PhilippC
f2967e1d8f New translations strings.xml (Slovak) 2019-02-06 15:50:13 +01:00
PhilippC
60783ca88e New translations strings.xml (Slovak) 2019-02-06 15:40:12 +01:00
PhilippC
8d7c1371df New translations strings.xml (Vietnamese) 2019-02-06 15:33:16 +01:00
PhilippC
090bfe9091 New translations strings.xml (Basque) 2019-02-06 15:33:10 +01:00
PhilippC
3ad2ba9f33 New translations strings.xml (Bulgarian) 2019-02-06 15:33:05 +01:00
PhilippC
1036def599 New translations strings.xml (Catalan) 2019-02-06 15:33:00 +01:00
PhilippC
2acad69940 New translations strings.xml (Chinese Simplified) 2019-02-06 15:32:56 +01:00
PhilippC
1f18011a5b New translations strings.xml (Chinese Traditional) 2019-02-06 15:32:51 +01:00
PhilippC
3da63b378c New translations strings.xml (Croatian) 2019-02-06 15:32:45 +01:00
PhilippC
0852aa7429 New translations strings.xml (Czech) 2019-02-06 15:32:39 +01:00
PhilippC
8a863ca636 New translations strings.xml (Danish) 2019-02-06 15:32:33 +01:00
PhilippC
83db5c205d New translations strings.xml (Finnish) 2019-02-06 15:32:26 +01:00
PhilippC
760e73959c New translations strings.xml (French) 2019-02-06 15:32:22 +01:00
PhilippC
e516e06a53 New translations strings.xml (Galician) 2019-02-06 15:32:16 +01:00
PhilippC
a954461be3 New translations strings.xml (German) 2019-02-06 15:32:12 +01:00
PhilippC
5998369af6 New translations strings.xml (Greek) 2019-02-06 15:32:06 +01:00
PhilippC
f41a2604c4 New translations strings.xml (Azerbaijani) 2019-02-06 15:31:57 +01:00
PhilippC
6fc578d286 New translations strings.xml (Hebrew) 2019-02-06 15:31:51 +01:00
PhilippC
f2604a5fec New translations strings.xml (Indonesian) 2019-02-06 15:31:47 +01:00
PhilippC
642026156a New translations strings.xml (Italian) 2019-02-06 15:31:41 +01:00
PhilippC
708c511a98 New translations strings.xml (Japanese) 2019-02-06 15:31:35 +01:00
PhilippC
2c75b5886f New translations strings.xml (Korean) 2019-02-06 15:31:30 +01:00
PhilippC
0ef7f5a955 New translations strings.xml (Russian) 2019-02-06 15:31:20 +01:00
PhilippC
28856c01cd New translations strings.xml (Serbian (Cyrillic)) 2019-02-06 15:31:09 +01:00
PhilippC
a47bd03e94 New translations strings.xml (Slovak) 2019-02-06 15:31:01 +01:00
PhilippC
c5551ddeb5 New translations strings.xml (Slovenian) 2019-02-06 15:30:57 +01:00
PhilippC
020f274ef3 New translations strings.xml (Spanish) 2019-02-06 15:30:51 +01:00
PhilippC
e2f8f04ace New translations strings.xml (Swedish) 2019-02-06 15:30:45 +01:00
PhilippC
6d61d885c1 New translations strings.xml (Turkish) 2019-02-06 15:30:39 +01:00
PhilippC
e98cd16032 New translations strings.xml (Ukrainian) 2019-02-06 15:30:33 +01:00
PhilippC
4ec8bdda2f New translations strings.xml (Hungarian) 2019-02-06 15:30:29 +01:00
PhilippC
16df1624f8 New translations strings.xml (Arabic) 2019-02-06 15:30:20 +01:00
PhilippC
cb978e012b New translations strings.xml (Portuguese) 2019-02-06 06:20:56 +01:00
PhilippC
b7ea02696b New translations strings.xml (Polish) 2019-02-06 06:20:51 +01:00
PhilippC
49cb8874ca New translations strings.xml (Persian) 2019-02-06 06:20:46 +01:00
PhilippC
1384256d87 New translations strings.xml (Norwegian Nynorsk) 2019-02-06 06:20:41 +01:00
PhilippC
705b2fcd9a New translations strings.xml (Norwegian Bokmal) 2019-02-06 06:20:38 +01:00
PhilippC
906ca77973 New translations strings.xml (Romanian) 2019-02-06 06:20:34 +01:00
PhilippC
7dc5c734d0 New translations strings.xml (Dutch) 2019-02-06 06:20:29 +01:00
Philipp Crocoll
a3c1e311f7 1.07-pre4 2019-02-06 06:15:33 +01:00
Philipp Crocoll
4d246a250d remove AdalBindings project 2019-02-06 06:15:20 +01:00
Philipp Crocoll
8d2c41f558 fix duplicate string resource id 2019-02-06 06:14:49 +01:00
PhilippC
3b06c4c14a New translations strings.xml (Chinese Traditional) 2019-02-05 20:03:10 +01:00
PhilippC
f98dcb813d New translations strings.xml (Finnish) 2019-02-05 20:02:56 +01:00
PhilippC
17cf31e8cf New translations strings.xml (Portuguese, Brazilian) 2019-02-05 20:02:13 +01:00
PhilippC
6771c378bf New translations strings.xml (Russian) 2019-02-05 20:02:09 +01:00
Philipp Crocoll
013aa4d071 Merge branch 'master' of https://github.com/PhilippC/keepass2android 2019-02-05 19:55:58 +01:00
PhilippC
b887e16628 Merge pull request #515 from PhilippC/l10n_master
New Crowdin translations
2019-02-05 19:55:45 +01:00
PhilippC
7774ed65bd Merge branch 'master' into l10n_master 2019-02-05 19:55:11 +01:00
PhilippC
c85f996aa3 New translations strings.xml (Portuguese) 2019-02-05 19:51:56 +01:00
Philipp Crocoll
64d9cc00d1 Merge branch 'master' of https://github.com/PhilippC/keepass2android 2019-02-05 19:46:56 +01:00
Philipp Crocoll
a0efbecee4 Forward to Search results directly when multiple databases open, closes https://github.com/PhilippC/keepass2android/issues/642 2019-02-05 12:15:22 +01:00
Philipp Crocoll
cceb4c6677 increase timeout (https://github.com/PhilippC/keepass2android/issues/339). still todo: test how KP2A behaves on write errors. 2019-02-05 12:14:52 +01:00
Philipp Crocoll
66e448a648 avoid using a deprecated method, might help with https://github.com/PhilippC/keepass2android/issues/653 2019-02-05 11:08:38 +01:00
Philipp Crocoll
eb134fd41a NfcOtpActivity is back - this time with app link enabled (allows users to enter https://keepass2android.crocoll.net/neo/ as NDEF payload and should work on all recent Android devices with NFC). Closes #603 2019-02-05 10:36:08 +01:00
Philipp Crocoll
857d6f9008 reset cancellation signal when cancelled. might fix https://github.com/PhilippC/keepass2android/issues/560 (cannot reproduce, so user must test) 2019-02-05 10:04:10 +01:00
PhilippC
32396c4534 Merge pull request #654 from Small-Ku/master
Update crowdin.yml for better Chinese localiztion
2019-02-05 06:38:57 +01:00
Philipp Crocoll
2df46b6647 improve language in some strings 2019-02-05 06:29:01 +01:00
Philipp Crocoll
9f6ad37547 Revert "failing attempt to integrate ADAL authentication (for OneDrive for business)"
This reverts commit 6b69ad20ad.
2019-02-05 06:28:40 +01:00
PhilippC
65955843e5 New translations strings.xml (Dutch) 2019-01-26 15:40:08 +01:00
PhilippC
9e9b5fb9dd New translations strings.xml (Polish) 2019-01-19 14:10:09 +01:00
PhilippC
f96fc67bc2 New translations strings.xml (Russian) 2019-01-15 13:50:14 +01:00
PhilippC
07ebd0b4ca New translations strings.xml (Russian) 2019-01-15 13:40:10 +01:00
PhilippC
64e955c512 New translations strings.xml (Japanese) 2019-01-14 13:50:11 +01:00
PhilippC
161753b195 New translations strings.xml (Japanese) 2019-01-14 13:40:15 +01:00
PhilippC
f92adb847a New translations strings.xml (Japanese) 2019-01-14 13:30:13 +01:00
PhilippC
98f780c277 New translations strings.xml (Portuguese, Brazilian) 2019-01-14 03:20:08 +01:00
PhilippC
3c512e74db New translations strings.xml (Portuguese, Brazilian) 2019-01-14 03:10:08 +01:00
PhilippC
9b752dd28f New translations strings.xml (Portuguese, Brazilian) 2019-01-14 03:00:11 +01:00
PhilippC
3cf2719c29 New translations strings.xml (Croatian) 2019-01-07 07:30:10 +01:00
PhilippC
be420c0394 New translations strings.xml (Croatian) 2019-01-07 07:20:08 +01:00
PhilippC
1b1d995b9d New translations strings.xml (Russian) 2019-01-03 16:50:10 +01:00
PhilippC
6410f41fa2 New translations strings.xml (Italian) 2019-01-02 15:50:09 +01:00
PhilippC
f90a45b1e6 New translations strings.xml (Italian) 2019-01-02 15:40:08 +01:00
PhilippC
9ca5569122 New translations strings.xml (Slovak) 2019-01-02 12:20:08 +01:00
Philipp Crocoll
a6b4a35973 added OneDriveStorage2 based on Graph SDK 2018-12-30 07:53:29 +01:00
PhilippC
06cb6bac3e New translations strings.xml (Turkish) 2018-12-28 10:50:11 +01:00
PhilippC
5241aeea9f New translations strings.xml (Turkish) 2018-12-28 10:40:09 +01:00
Philipp Crocoll
6b69ad20ad failing attempt to integrate ADAL authentication (for OneDrive for business) 2018-12-27 21:46:11 +01:00
PhilippC
a79d2ec323 New translations strings.xml (Catalan) 2018-12-27 21:40:08 +01:00
PhilippC
209a0fe2da New translations strings.xml (Catalan) 2018-12-27 21:30:10 +01:00
Small_Ku
277f439f70 Update crowdin.yml
for Chinese translation
2018-12-27 00:05:15 +08:00
PhilippC
d9f29fdcaa New translations strings.xml (Danish) 2018-12-26 06:50:08 +01:00
PhilippC
a9141d3fe2 New translations strings.xml (Danish) 2018-12-26 06:40:08 +01:00
PhilippC
4ce55e88fa New translations strings.xml (Danish) 2018-12-26 06:30:08 +01:00
PhilippC
c930d388dc New translations strings.xml (Finnish) 2018-12-25 10:30:25 +01:00
PhilippC
12c7911cf4 New translations strings.xml (Finnish) 2018-12-25 10:20:18 +01:00
PhilippC
06377ff497 New translations strings.xml (Finnish) 2018-12-25 10:10:08 +01:00
PhilippC
7a1938e515 New translations strings.xml (Finnish) 2018-12-25 10:00:09 +01:00
PhilippC
445166d220 New translations strings.xml (Danish) 2018-12-25 08:10:08 +01:00
PhilippC
3963501d0c New translations strings.xml (Danish) 2018-12-25 08:00:09 +01:00
PhilippC
acb51d7859 New translations strings.xml (Spanish) 2018-12-23 19:50:09 +01:00
PhilippC
4dbfb76ced Merge pull request #628 from Skycoder42/master
Correctly extract protected fields from intent (Fixes #627)
2018-12-23 07:27:32 +01:00
Philipp Crocoll
4188464652 change "application" to "app" in english strings 2018-12-23 07:09:17 +01:00
PhilippC
fb552a8d62 New translations strings.xml (Chinese Simplified) 2018-12-23 02:40:09 +01:00
PhilippC
c998e4e34f New translations strings.xml (Chinese Simplified) 2018-12-23 02:30:09 +01:00
PhilippC
ab46015a5a New translations strings.xml (Chinese Simplified) 2018-12-23 02:20:09 +01:00
PhilippC
dd10740bf2 New translations strings.xml (German) 2018-12-22 13:40:08 +01:00
PhilippC
44f26685e4 New translations strings.xml (German) 2018-12-22 13:30:08 +01:00
PhilippC
3caa56ae8c New translations strings.xml (French) 2018-12-21 16:30:09 +01:00
PhilippC
1ca4fbb078 New translations strings.xml (Czech) 2018-12-18 23:40:10 +01:00
PhilippC
bdf5270fa0 New translations strings.xml (Czech) 2018-12-18 19:30:09 +01:00
PhilippC
e3e865b108 New translations strings.xml (Czech) 2018-12-18 19:20:09 +01:00
PhilippC
33f3736798 New translations strings.xml (Czech) 2018-12-18 19:10:11 +01:00
PhilippC
a86fbcee44 New translations strings.xml (Czech) 2018-12-18 19:00:13 +01:00
PhilippC
cdbf8a2811 New translations strings.xml (Czech) 2018-12-18 18:50:09 +01:00
PhilippC
da4fae4e04 New translations strings.xml (Czech) 2018-12-18 18:40:10 +01:00
PhilippC
ddeefc4ab6 New translations strings.xml (Chinese Traditional) 2018-12-17 19:20:11 +01:00
PhilippC
33702064a5 New translations strings.xml (French) 2018-12-17 12:40:10 +01:00
PhilippC
b72995c8bf New translations strings.xml (Chinese Simplified) 2018-12-17 12:20:16 +01:00
PhilippC
868eb1c4fb New translations strings.xml (Catalan) 2018-12-17 12:20:10 +01:00
PhilippC
d93140efc6 New translations strings.xml (Chinese Traditional) 2018-12-17 12:12:20 +01:00
PhilippC
0f59d46ede New translations strings.xml (Croatian) 2018-12-17 12:12:14 +01:00
PhilippC
812b5f22f9 New translations strings.xml (Czech) 2018-12-17 12:12:10 +01:00
PhilippC
d1b5feae0d New translations strings.xml (Danish) 2018-12-17 12:12:05 +01:00
PhilippC
0861fa9e03 New translations strings.xml (Dutch) 2018-12-17 12:12:00 +01:00
PhilippC
c3fe9f513d New translations strings.xml (Finnish) 2018-12-17 12:11:56 +01:00
PhilippC
b513669f4d New translations strings.xml (French) 2018-12-17 12:11:49 +01:00
PhilippC
1ad74fdacc New translations strings.xml (Galician) 2018-12-17 12:11:44 +01:00
PhilippC
9a24ede989 New translations strings.xml (German) 2018-12-17 12:11:40 +01:00
PhilippC
7ea8dfa8ce New translations strings.xml (Greek) 2018-12-17 12:11:35 +01:00
PhilippC
670068eeba New translations strings.xml (Hungarian) 2018-12-17 12:11:28 +01:00
PhilippC
70310f1970 New translations strings.xml (Indonesian) 2018-12-17 12:11:19 +01:00
PhilippC
4463c148a5 New translations strings.xml (Japanese) 2018-12-17 12:11:15 +01:00
PhilippC
c982b45134 New translations strings.xml (Korean) 2018-12-17 12:11:10 +01:00
PhilippC
d209a2c7f8 New translations strings.xml (Norwegian Bokmal) 2018-12-17 12:11:05 +01:00
PhilippC
75c73193a2 New translations strings.xml (Portuguese, Brazilian) 2018-12-17 12:10:59 +01:00
PhilippC
fc99f6774d New translations strings.xml (Romanian) 2018-12-17 12:10:54 +01:00
PhilippC
d40fab86c9 New translations strings.xml (Slovak) 2018-12-17 12:10:45 +01:00
PhilippC
5c0520e093 New translations strings.xml (Slovenian) 2018-12-17 12:10:41 +01:00
PhilippC
1bb9ead202 New translations strings.xml (Spanish) 2018-12-17 12:10:36 +01:00
PhilippC
3afd8915f0 New translations strings.xml (Swedish) 2018-12-17 12:10:32 +01:00
PhilippC
ba3f2d2823 New translations strings.xml (Turkish) 2018-12-17 12:10:28 +01:00
PhilippC
24989d80ac New translations strings.xml (Ukrainian) 2018-12-17 12:10:22 +01:00
PhilippC
d2c16158cc New translations strings.xml (Vietnamese) 2018-12-17 12:10:17 +01:00
PhilippC
8514fd6266 New translations strings.xml (Italian) 2018-12-17 12:10:13 +01:00
Philipp Crocoll
30d1534c01 show save errors as dialogs, closes #339 2018-12-17 12:09:31 +01:00
PhilippC
4f0800d4fc New translations strings.xml (Portuguese) 2018-12-17 12:00:49 +01:00
PhilippC
41fa396318 New translations strings.xml (Polish) 2018-12-17 12:00:45 +01:00
PhilippC
d94af84002 New translations strings.xml (Persian) 2018-12-17 12:00:41 +01:00
PhilippC
63b92cc35a New translations strings.xml (Russian) 2018-12-17 12:00:31 +01:00
PhilippC
3238d9fbc5 New translations strings.xml (Arabic) 2018-12-17 12:00:26 +01:00
Philipp Crocoll
780d4c95fe improve message when file is readonly, closes #521 2018-12-17 11:47:24 +01:00
PhilippC
c3b27c75bf New translations strings.xml (Chinese Traditional) 2018-12-17 11:40:08 +01:00
PhilippC
23c7031672 New translations strings.xml (Chinese Traditional) 2018-12-17 11:30:11 +01:00
PhilippC
9e98d09a93 New translations strings.xml (Chinese Traditional) 2018-12-17 11:20:11 +01:00
Philipp Crocoll
06e64f7347 more autofill logging 2018-12-17 11:12:07 +01:00
Philipp Crocoll
92594db78d automatically fill in OTPs copied from Yubiclip. closes #603 and closes #564 2018-12-17 11:11:56 +01:00
PhilippC
c574f2d6bd New translations strings.xml (Chinese Traditional) 2018-12-17 11:10:11 +01:00
PhilippC
ee156cbfd6 New translations strings.xml (Chinese Traditional) 2018-12-17 10:50:09 +01:00
PhilippC
73d12daf04 New translations strings.xml (Chinese Traditional) 2018-12-17 10:40:09 +01:00
Philipp Crocoll
e4179a934b fix wrong time display when editing expiration date, fixes #634 2018-12-17 10:03:43 +01:00
Philipp Crocoll
afd309d9a8 work on reducing popups for autofill/allow to disable autofill for query. not yet fully functional. refers to #455. 2018-12-17 10:03:02 +01:00
PhilippC
1a24b00c5e New translations strings.xml (Italian) 2018-12-17 09:40:08 +01:00
PhilippC
445e4d8b31 New translations strings.xml (Italian) 2018-12-17 09:30:34 +01:00
PhilippC
224ca98d0e New translations strings.xml (Swedish) 2018-12-16 23:50:10 +01:00
PhilippC
13419c9fb7 New translations strings.xml (Croatian) 2018-12-16 22:10:12 +01:00
PhilippC
00646bc84b New translations strings.xml (Croatian) 2018-12-16 22:00:13 +01:00
PhilippC
cb4b686335 New translations strings.xml (Dutch) 2018-12-16 14:10:09 +01:00
PhilippC
5e900b62c8 New translations strings.xml (Ukrainian) 2018-12-12 09:00:09 +01:00
PhilippC
74c94d37e5 New translations strings.xml (French) 2018-12-11 21:40:08 +01:00
PhilippC
588814d1a6 New translations strings.xml (Portuguese) 2018-12-11 21:30:12 +01:00
PhilippC
572b858f81 New translations strings.xml (Portuguese) 2018-12-11 21:20:10 +01:00
PhilippC
1a9fc48490 New translations strings.xml (Japanese) 2018-12-11 05:30:09 +01:00
PhilippC
2dd131e6c3 New translations strings.xml (Portuguese, Brazilian) 2018-12-11 00:10:08 +01:00
Philipp Crocoll
d1ad2a681f Autofill: fill emailAddress fields with username 2018-12-10 11:24:40 +01:00
Philipp Crocoll
e2e7666c4f fix incorrect webDomain checking, fixes https://github.com/PhilippC/keepass2android/issues/592 2018-12-10 11:23:44 +01:00
Philipp Crocoll
665639fdca fix switching keyboards not working in Android 9: fixes https://github.com/PhilippC/keepass2android/issues/530 2018-12-10 09:52:23 +01:00
Philipp Crocoll
8bb930c1fc make kdb library "embedded jar" instead of "inputjar" to fix issue with native key transform not working. -> 1.07-pre3 2018-12-10 09:50:26 +01:00
PhilippC
b3b9d8d105 New translations strings.xml (Catalan) 2018-12-09 17:30:10 +01:00
PhilippC
82c409252b New translations strings.xml (Polish) 2018-12-09 15:30:18 +01:00
PhilippC
14c63a03c4 New translations strings.xml (Chinese Simplified) 2018-12-09 15:30:14 +01:00
PhilippC
0c7ad8b16c New translations strings.xml (Catalan) 2018-12-09 15:30:10 +01:00
PhilippC
1bf2d8219a New translations strings.xml (Chinese Traditional) 2018-12-09 14:42:11 +01:00
PhilippC
a72264ef36 New translations strings.xml (Croatian) 2018-12-09 14:42:06 +01:00
PhilippC
1acc399568 New translations strings.xml (Czech) 2018-12-09 14:42:00 +01:00
PhilippC
160960437c New translations strings.xml (Danish) 2018-12-09 14:41:56 +01:00
PhilippC
61992adcca New translations strings.xml (Dutch) 2018-12-09 14:41:52 +01:00
PhilippC
10e0ae8200 New translations strings.xml (Finnish) 2018-12-09 14:41:47 +01:00
PhilippC
eb58b8576e New translations strings.xml (French) 2018-12-09 14:41:43 +01:00
PhilippC
9b4d2d6ed7 New translations strings.xml (Galician) 2018-12-09 14:41:38 +01:00
PhilippC
6417e9dec5 New translations strings.xml (German) 2018-12-09 14:41:33 +01:00
PhilippC
f5ac217f13 New translations strings.xml (Greek) 2018-12-09 14:41:29 +01:00
PhilippC
a3d3b14dd1 New translations strings.xml (Bulgarian) 2018-12-09 14:41:21 +01:00
PhilippC
8fccce8684 New translations strings.xml (Hungarian) 2018-12-09 14:41:17 +01:00
PhilippC
4a847cd74a New translations strings.xml (Italian) 2018-12-09 14:41:11 +01:00
PhilippC
f4c1db39ad New translations strings.xml (Japanese) 2018-12-09 14:41:07 +01:00
PhilippC
d9ff177427 New translations strings.xml (Korean) 2018-12-09 14:41:02 +01:00
PhilippC
95e3566c5f New translations strings.xml (Norwegian Bokmal) 2018-12-09 14:40:57 +01:00
PhilippC
76e02ff514 New translations strings.xml (Romanian) 2018-12-09 14:40:52 +01:00
PhilippC
8aca9a2d82 New translations strings.xml (Serbian (Cyrillic)) 2018-12-09 14:40:47 +01:00
PhilippC
3abab2072a New translations strings.xml (Slovak) 2018-12-09 14:40:42 +01:00
PhilippC
ca9e479dc5 New translations strings.xml (Slovenian) 2018-12-09 14:40:38 +01:00
PhilippC
4d230a7b3e New translations strings.xml (Spanish) 2018-12-09 14:40:34 +01:00
PhilippC
974cc59e6c New translations strings.xml (Swedish) 2018-12-09 14:40:31 +01:00
PhilippC
9f09b144f0 New translations strings.xml (Turkish) 2018-12-09 14:40:26 +01:00
PhilippC
9d4dad5fee New translations strings.xml (Ukrainian) 2018-12-09 14:40:22 +01:00
PhilippC
46ffa93d93 New translations strings.xml (Vietnamese) 2018-12-09 14:40:19 +01:00
PhilippC
8b709bc070 New translations strings.xml (Indonesian) 2018-12-09 14:40:14 +01:00
PhilippC
c1284c760a New translations strings.xml (Basque) 2018-12-09 14:40:09 +01:00
PhilippC
6529a94d3a New translations strings.xml (Portuguese) 2018-12-09 08:30:39 +01:00
PhilippC
f5e91a0524 New translations strings.xml (Polish) 2018-12-09 08:30:35 +01:00
PhilippC
f63bd3016b New translations strings.xml (Norwegian Nynorsk) 2018-12-09 08:30:28 +01:00
PhilippC
09cd590796 New translations strings.xml (Russian) 2018-12-09 08:30:24 +01:00
PhilippC
da728c4039 New translations strings.xml (Arabic) 2018-12-09 08:30:20 +01:00
Philipp Crocoll
14b7b8cec1 Merge branch 'master' of https://github.com/PhilippC/keepass2android 2018-12-09 08:23:18 +01:00
Philipp Crocoll
3695c04933 avoid endless loops trying to open databases when loading fails. changelog 1.07-pre2 for release. 2018-12-09 08:22:45 +01:00
Philipp Crocoll
f0f3bb6ede more logging regarding key transformation 2018-12-09 08:21:25 +01:00
Philipp Crocoll
7824326c5b fix typo in string 2018-12-09 08:21:03 +01:00
Philipp Crocoll
a65d263ae2 manifest for 1.07-pre2 2018-12-09 08:20:50 +01:00
PhilippC
f3e628be6b New translations strings.xml (Polish) 2018-12-09 02:10:10 +01:00
PhilippC
62e8dc7767 New translations strings.xml (Polish) 2018-12-09 02:00:09 +01:00
PhilippC
8e8cfa704a New translations strings.xml (Polish) 2018-12-09 01:50:08 +01:00
PhilippC
8b2eff0194 New translations strings.xml (Polish) 2018-12-09 01:40:08 +01:00
PhilippC
d4d063b97a New translations strings.xml (Polish) 2018-12-09 01:30:08 +01:00
PhilippC
d5ec33e1bd New translations strings.xml (Polish) 2018-12-09 01:20:09 +01:00
PhilippC
0726f22ec7 New translations strings.xml (Polish) 2018-12-09 01:00:12 +01:00
PhilippC
531ab93388 New translations strings.xml (Polish) 2018-12-09 00:50:08 +01:00
Philipp Crocoll
a7ad00d402 fix incorrect expiration time in EntryEditActivity, fixes #634 2018-12-08 17:44:02 +01:00
PhilippC
1f18848b4e New translations strings.xml (French) 2018-12-08 17:30:08 +01:00
PhilippC
38179d9ce3 New translations strings.xml (Chinese Simplified) 2018-12-07 08:10:10 +01:00
PhilippC
b86c493cf8 New translations strings.xml (Slovak) 2018-12-04 22:20:13 +01:00
PhilippC
0cc2df85da New translations strings.xml (Catalan) 2018-12-03 21:30:10 +01:00
Skycoder42
3157bac5f6 Add missing import 2018-12-03 18:40:01 +01:00
Skycoder42
5cb1709f5d Correctly extract protected fields from intent
Fixes #627
2018-12-03 18:37:36 +01:00
PhilippC
e6834b13a5 New translations strings.xml (Azerbaijani) 2018-12-03 11:52:59 +01:00
PhilippC
8a17daa002 New translations strings.xml (Chinese Traditional) 2018-12-03 11:52:08 +01:00
PhilippC
1b09189195 New translations strings.xml (Portuguese, Brazilian) 2018-12-03 11:50:50 +01:00
Philipp Crocoll
7f21fa2c40 added ConfigChanges flags to all activities which could potentially show the ykDroid dialog to reduce the chance of activity recreation (this is considered a workaround, waiting for the solution at https://github.com/pp3345/ykDroid/issues/8) 2018-12-03 11:37:08 +01:00
PhilippC
e0e4fc85f7 New translations strings.xml (Vietnamese) 2018-12-01 21:20:08 +01:00
PhilippC
b3e57db9f8 New translations strings.xml (Portuguese) 2018-12-01 00:40:08 +01:00
PhilippC
f8d93a5de7 New translations strings.xml (Portuguese) 2018-12-01 00:30:08 +01:00
PhilippC
c5423ac650 New translations strings.xml (German) 2018-11-29 09:20:13 +01:00
PhilippC
6e93d17d14 New translations strings.xml (German) 2018-11-29 09:10:15 +01:00
PhilippC
127bc1be5c New translations strings.xml (Chinese Simplified) 2018-11-28 03:20:14 +01:00
PhilippC
8136b09992 New translations strings.xml (Ukrainian) 2018-11-27 14:20:09 +01:00
PhilippC
2ffac3268e New translations strings.xml (Ukrainian) 2018-11-27 14:00:12 +01:00
PhilippC
c7056e9d40 New translations strings.xml (Ukrainian) 2018-11-27 13:50:10 +01:00
PhilippC
3fb8b4e7ff New translations strings.xml (Russian) 2018-11-26 21:50:09 +01:00
PhilippC
c728a7802d New translations strings.xml (Russian) 2018-11-26 21:40:09 +01:00
PhilippC
e7d3049456 New translations strings.xml (Russian) 2018-11-26 21:30:09 +01:00
PhilippC
316675c77e New translations strings.xml (Russian) 2018-11-26 21:20:09 +01:00
PhilippC
c836d3de71 New translations strings.xml (Russian) 2018-11-26 21:00:14 +01:00
PhilippC
230429135a New translations strings.xml (Russian) 2018-11-26 20:40:08 +01:00
PhilippC
0be8092382 New translations strings.xml (Russian) 2018-11-26 20:30:09 +01:00
PhilippC
eb2019e568 New translations strings.xml (Russian) 2018-11-26 20:20:12 +01:00
PhilippC
bffbb17271 New translations strings.xml (Spanish) 2018-11-26 09:30:11 +01:00
PhilippC
16b997096d New translations strings.xml (Spanish) 2018-11-26 09:20:10 +01:00
PhilippC
3b23f2a4ed New translations strings.xml (Hungarian) 2018-11-25 03:40:09 +01:00
PhilippC
87f86fd2e8 New translations strings.xml (Slovak) 2018-11-23 20:10:07 +01:00
PhilippC
396509579a New translations strings.xml (Slovak) 2018-11-23 20:00:09 +01:00
PhilippC
91175f19c4 New translations strings.xml (Catalan) 2018-11-23 17:50:09 +01:00
PhilippC
7c22ca0f91 New translations strings.xml (Catalan) 2018-11-23 17:40:18 +01:00
PhilippC
5eb416d8d9 New translations strings.xml (Turkish) 2018-11-22 20:32:03 +01:00
PhilippC
12e374bd2f New translations strings.xml (Turkish) 2018-11-22 20:20:15 +01:00
PhilippC
9b50f0e77c New translations strings.xml (German) 2018-11-21 23:00:10 +01:00
PhilippC
6aa89287b1 New translations strings.xml (German) 2018-11-21 22:50:14 +01:00
PhilippC
4b9ebdc87c New translations strings.xml (French) 2018-11-21 22:20:11 +01:00
PhilippC
336b45667e New translations strings.xml (Russian) 2018-11-21 12:50:09 +01:00
PhilippC
3c33a1126b New translations strings.xml (Russian) 2018-11-21 12:40:10 +01:00
Philipp Crocoll
836cdfb16c move CurrentlyWaitingKey to App instead of activity to survive activity recreation. Avoid activity recreation when plugging in Yubikey. Fixes #609. 2018-11-21 03:01:43 +01:00
Philipp Crocoll
8512bae997 make sure we always save database as KDBX4 when using ChallengeXCKey (for compatibility with KeepassXC), closes #596 2018-11-20 06:08:30 +01:00
PhilippC
6fbe8c5dee New translations strings.xml (German) 2018-11-20 05:00:11 +01:00
Philipp Crocoll
2132ea416b notify about unconfigured child databases. finishes implementation of child databases, thus closes #174 2018-11-20 04:54:45 +01:00
PhilippC
24081b9223 New translations strings.xml (Chinese Simplified) 2018-11-19 20:11:57 +01:00
PhilippC
220cc98559 New translations strings.xml (Portuguese, Brazilian) 2018-11-19 20:10:49 +01:00
Philipp Crocoll
ef8b9b0685 allow to open AutoOpenEntries manually if they are not "Enabled" (but "Visible"). Don't suggest to configure fingerprint unlock for child databases. 2018-11-19 20:03:53 +01:00
PhilippC
e8dd47369c New translations strings.xml (Portuguese) 2018-11-19 19:20:09 +01:00
PhilippC
537eaddecd New translations strings.xml (Portuguese) 2018-11-19 19:10:09 +01:00
Philipp Crocoll
183c171da6 first version of KeeAutoExec functionality in Keepass2Android 2018-11-19 19:06:12 +01:00
Philipp Crocoll
58c6114840 fix potentially incorrect display of storage type in EntryEditActivity 2018-11-18 13:33:19 +01:00
Philipp Crocoll
df5162ce56 implemented first version of AutoOpen entry editing 2018-11-18 03:56:49 +01:00
PhilippC
ae61fe892d New translations strings.xml (Persian) 2018-11-15 20:50:08 +01:00
PhilippC
a78de3b4b9 New translations strings.xml (Persian) 2018-11-15 20:40:10 +01:00
PhilippC
f26a864e83 New translations strings.xml (Persian) 2018-11-15 20:30:14 +01:00
PhilippC
0e0b03e6f2 New translations strings.xml (Persian) 2018-11-15 20:20:11 +01:00
Philipp Crocoll
e5595f13eb intermediate commit, starting to implement edit GUI for AutoOpen entries (does not compile) 2018-11-15 19:14:10 +01:00
PhilippC
1b12c16685 New translations strings.xml (Turkish) 2018-11-14 08:30:11 +01:00
PhilippC
048055daac New translations strings.xml (Turkish) 2018-11-14 08:10:11 +01:00
Philipp Crocoll
f2590f1fed Merge branch 'master' of https://github.com/PhilippC/keepass2android 2018-11-13 22:00:06 +01:00
Philipp Crocoll
2eb7b22100 start implementing the GUI for editing AutoOpen entries 2018-11-13 21:57:43 +01:00
PhilippC
f169750d1a New translations strings.xml (French) 2018-11-13 20:50:12 +01:00
PhilippC
fbb361fa7a New translations strings.xml (Swedish) 2018-11-13 18:10:13 +01:00
PhilippC
902faca13c New translations strings.xml (Italian) 2018-11-13 17:20:16 +01:00
PhilippC
7e476a5785 New translations strings.xml (Italian) 2018-11-13 17:10:18 +01:00
PhilippC
c78c5aad02 New translations strings.xml (Italian) 2018-11-13 17:00:22 +01:00
PhilippC
42c49645da New translations strings.xml (Catalan) 2018-11-13 17:00:18 +01:00
Philipp Crocoll
9427fb9ecc merge KeeAutoExec extension from https://sourceforge.net/p/keepass/discussion/329220/thread/509d35a111/#f70b 2018-11-12 09:47:38 +01:00
PhilippC
61878f293f New translations strings.xml (Chinese Traditional) 2018-11-12 09:12:42 +01:00
PhilippC
2bd1727076 New translations strings.xml (Croatian) 2018-11-12 09:12:37 +01:00
PhilippC
f0fbf7bf8b New translations strings.xml (Czech) 2018-11-12 09:12:31 +01:00
PhilippC
4a1fccc395 New translations strings.xml (Danish) 2018-11-12 09:12:27 +01:00
PhilippC
54c0497933 New translations strings.xml (Dutch) 2018-11-12 09:12:23 +01:00
PhilippC
49a99e9f15 New translations strings.xml (Finnish) 2018-11-12 09:12:16 +01:00
PhilippC
134fd5b2c2 New translations strings.xml (French) 2018-11-12 09:12:12 +01:00
PhilippC
696f9b3550 New translations strings.xml (Galician) 2018-11-12 09:12:06 +01:00
PhilippC
aeda42cb71 New translations strings.xml (German) 2018-11-12 09:11:59 +01:00
PhilippC
7ba8400c38 New translations strings.xml (Greek) 2018-11-12 09:11:55 +01:00
PhilippC
02f10f07e8 New translations strings.xml (Bulgarian) 2018-11-12 09:11:46 +01:00
PhilippC
83cc32afaa New translations strings.xml (Hungarian) 2018-11-12 09:11:41 +01:00
PhilippC
5b8382643a New translations strings.xml (Italian) 2018-11-12 09:11:35 +01:00
PhilippC
003cb8719a New translations strings.xml (Japanese) 2018-11-12 09:11:28 +01:00
PhilippC
c625ebc128 New translations strings.xml (Korean) 2018-11-12 09:11:23 +01:00
PhilippC
89c0b02327 New translations strings.xml (Norwegian Bokmal) 2018-11-12 09:11:17 +01:00
PhilippC
94bb17a301 New translations strings.xml (Romanian) 2018-11-12 09:11:11 +01:00
PhilippC
4f29b921e5 New translations strings.xml (Serbian (Cyrillic)) 2018-11-12 09:11:06 +01:00
PhilippC
8d5dbb0f3d New translations strings.xml (Slovak) 2018-11-12 09:11:02 +01:00
PhilippC
db321e45da New translations strings.xml (Slovenian) 2018-11-12 09:10:57 +01:00
PhilippC
8e254a341c New translations strings.xml (Spanish) 2018-11-12 09:10:53 +01:00
PhilippC
847a52ab08 New translations strings.xml (Swedish) 2018-11-12 09:10:47 +01:00
PhilippC
94e69e4e84 New translations strings.xml (Turkish) 2018-11-12 09:10:41 +01:00
PhilippC
8834526cac New translations strings.xml (Ukrainian) 2018-11-12 09:10:36 +01:00
PhilippC
788365687e New translations strings.xml (Vietnamese) 2018-11-12 09:10:31 +01:00
PhilippC
4c3d328140 New translations strings.xml (Indonesian) 2018-11-12 09:10:25 +01:00
PhilippC
2588f74f7c New translations strings.xml (Basque) 2018-11-12 09:10:20 +01:00
PhilippC
b70a4ef428 Merge pull request #612 from adorokhine/gradle-build
Add Gradle build config to PluginQR and update to match source conventions.
2018-11-12 09:08:02 +01:00
PhilippC
026a903251 New translations strings.xml (Portuguese) 2018-11-11 07:40:47 +01:00
PhilippC
3557113ed8 New translations strings.xml (Polish) 2018-11-11 07:40:42 +01:00
PhilippC
acd8c27a13 New translations strings.xml (Persian) 2018-11-11 07:40:38 +01:00
PhilippC
3c186eb113 New translations strings.xml (Norwegian Nynorsk) 2018-11-11 07:40:34 +01:00
PhilippC
841eb34224 New translations strings.xml (Russian) 2018-11-11 07:40:29 +01:00
PhilippC
ef583ba7ec New translations strings.xml (Arabic) 2018-11-11 07:40:23 +01:00
Alexander Dorokhine
fa0e06df75 Add Gradle build config to PluginQR and update it to match new source conventions.
Version code is bumped because there was a minor code change to avoid a
fatal lint error complaining about a memory leak.

Fixes #489.
2018-11-10 22:34:05 -08:00
Philipp Crocoll
c26ee7271b Merge branch 'master' of https://github.com/PhilippC/keepass2android 2018-11-11 06:36:40 +01:00
Philipp Crocoll
f37c0a9124 allow opening several databases which contain elements with same IDs (required as KeepassHttp stores their settings in an entry with a fixed ID) 2018-11-11 06:35:06 +01:00
Philipp Crocoll
80fbd656a7 Merge branch 'master' of https://github.com/PhilippC/keepass2android 2018-11-08 05:44:21 +01:00
Philipp Crocoll
3fb5749c86 avoid leakage of IOC username/password to logcat/debuglog for some protocols 2018-11-08 05:44:04 +01:00
PhilippC
1692130559 Merge pull request #608 from jakseb/patch-1
Fix formatting in docs/Keepass2Android-Apk.md
2018-11-08 04:41:00 +01:00
Sebastian Jakubiak
cf77a9eae2 Fix formatting in docs/Keepass2Android-Apk.md 2018-11-06 20:28:42 +01:00
PhilippC
26151af48a New translations strings.xml (Swedish) 2018-11-05 18:00:14 +01:00
PhilippC
c3b858f0fd New translations strings.xml (Swedish) 2018-11-05 17:50:08 +01:00
PhilippC
914e788ad8 New translations strings.xml (Swedish) 2018-11-05 17:40:09 +01:00
PhilippC
074178621c Merge pull request #604 from gilbsgilbs/fix-pcloud-filenames
Fix PCloud not overwriting uploaded files.
2018-11-03 19:21:16 +01:00
Gilbert Gilb's
25d1b6b695 Fix PCloud not overwriting uploaded files.
When uploading an existing file into PCloud, it appends a version number
by default (e.g. "MyDb (2).kdbx", "MyDb (3).kdbx" and so on). This
behavior is not desirable in K2PA case. The workaroundfor this is to upload
the file with a temporary name and then rename it to its final name.
This may also avoid corruption with failed uploads depending on how
PCloud handles uploads.

See https://github.com/PhilippC/keepass2android/issues/512#issuecomment-435475365
2018-11-02 23:30:59 +01:00
PhilippC
f121c73c4b New translations strings.xml (Azerbaijani) 2018-10-30 20:20:09 +01:00
PhilippC
3f79e7677c New translations strings.xml (Italian) 2018-10-29 12:50:10 +01:00
PhilippC
ca573f27be New translations strings.xml (Italian) 2018-10-29 11:30:08 +01:00
PhilippC
056a3342bf New translations strings.xml (Italian) 2018-10-29 11:20:10 +01:00
PhilippC
eaa661cf09 New translations strings.xml (Italian) 2018-10-29 11:10:11 +01:00
Philipp Crocoll
b2d791d6ea acknowledge gilbsgilbs for pcloud implementation 2018-10-29 08:39:05 +01:00
Philipp Crocoll
f1ea1935c5 Changelog and manifest for 1.07-pre1 2018-10-28 15:35:40 +01:00
Philipp Crocoll
d9c101debe remove NfcOtpActivity: not working with current multi-db approach, but also not working since Android has App links 2018-10-28 07:17:45 +01:00
PhilippC
e3a720a69d New translations strings.xml (Dutch) 2018-10-26 22:20:10 +02:00
Philipp Crocoll
4f3f18a0ad bug fixes and improvements after adding multi-database support 2018-10-25 06:03:08 +02:00
PhilippC
10a3a8324b New translations strings.xml (Russian) 2018-10-22 16:30:09 +02:00
Philipp Crocoll
a2dab72b25 first version to have multiple databases open at the same time. needs testing and bug fixing. 2018-10-16 06:33:00 +02:00
PhilippC
ca0a381d8c New translations strings.xml (Turkish) 2018-10-11 15:40:08 +02:00
PhilippC
a503e85a57 New translations strings.xml (Turkish) 2018-10-11 15:30:09 +02:00
PhilippC
0d668561b4 New translations strings.xml (Turkish) 2018-10-11 15:20:11 +02:00
PhilippC
c8d39a2c15 New translations strings.xml (Polish) 2018-10-10 17:40:08 +02:00
PhilippC
6146ac90c1 New translations strings.xml (Polish) 2018-10-10 17:30:13 +02:00
PhilippC
2bb00c948d New translations strings.xml (Polish) 2018-10-10 15:00:08 +02:00
PhilippC
01eadd986c New translations strings.xml (Spanish) 2018-10-07 19:30:09 +02:00
PhilippC
b482ea4ecc New translations strings.xml (Chinese Simplified) 2018-10-07 03:40:09 +02:00
PhilippC
19bb98c857 New translations strings.xml (Chinese Simplified) 2018-10-07 03:30:10 +02:00
PhilippC
225afb85e4 New translations strings.xml (Chinese Simplified) 2018-10-07 03:20:08 +02:00
PhilippC
2873ffdff7 New translations strings.xml (Spanish) 2018-10-05 19:30:09 +02:00
PhilippC
52ba506138 Merge pull request #579 from Zeustopher/patch-1
Added Logo to README.md
2018-10-05 05:56:43 +02:00
PhilippC
798f70a706 New translations strings.xml (Spanish) 2018-10-05 05:50:08 +02:00
Christopher Nash
d731d55a7a Added Logo to README.md
Added the Keepass2Android Logo to README.md to give it a little more "flare" when viewing it on Github.
2018-10-04 14:28:19 -06:00
PhilippC
1bfcea0227 New translations strings.xml (Spanish) 2018-10-04 18:20:10 +02:00
PhilippC
71a307bfef New translations strings.xml (German) 2018-10-01 15:30:06 +02:00
PhilippC
7a16a8eaff New translations strings.xml (German) 2018-10-01 15:20:07 +02:00
PhilippC
c1c2ccd940 New translations strings.xml (Russian) 2018-10-01 12:50:06 +02:00
Philipp Crocoll
8a993b7dcb rename StackDbActivity 2018-10-01 11:25:52 +02:00
Philipp Crocoll
977393a9aa refactoring, remove Loaded property from database. instead, make GetDb() return null if database is not loaded. 2018-10-01 11:12:37 +02:00
Philipp Crocoll
4f36de9900 refactoring: introduce StackBaseActivity which replaces PasswordActivity in its role as stack base and orchestrating activity. This is in preparation to allow multiple open databases. 2018-10-01 10:21:28 +02:00
PhilippC
ef658eb4cd New translations strings.xml (Ukrainian) 2018-09-29 14:40:05 +02:00
PhilippC
6f77577482 New translations strings.xml (Ukrainian) 2018-09-29 14:30:05 +02:00
Philipp Crocoll
bfdb1a8f62 disable notification badges ("1" icons) 2018-09-26 05:51:12 +02:00
PhilippC
0935d70ae4 New translations strings.xml (Slovak) 2018-09-23 12:40:06 +02:00
PhilippC
24e4e2b960 New translations strings.xml (Slovak) 2018-09-23 12:30:05 +02:00
PhilippC
e608d7463e New translations strings.xml (Catalan) 2018-09-23 12:20:05 +02:00
PhilippC
47453f1471 New translations strings.xml (Catalan) 2018-09-23 12:10:06 +02:00
PhilippC
362780f59a New translations strings.xml (French) 2018-09-21 14:00:06 +02:00
PhilippC
a2a511b3c0 New translations strings.xml (Vietnamese) 2018-09-21 13:50:38 +02:00
PhilippC
78cde8ab62 New translations strings.xml (Indonesian) 2018-09-21 13:50:35 +02:00
PhilippC
46b779c9d5 New translations strings.xml (Hungarian) 2018-09-21 13:50:32 +02:00
PhilippC
23129bf95a New translations strings.xml (Hebrew) 2018-09-21 13:50:29 +02:00
PhilippC
fba137bb3f New translations strings.xml (Greek) 2018-09-21 13:50:27 +02:00
PhilippC
e50a73b4bf New translations strings.xml (German) 2018-09-21 13:50:24 +02:00
PhilippC
31afe11d0e New translations strings.xml (Galician) 2018-09-21 13:50:21 +02:00
PhilippC
5dc1d047ac New translations strings.xml (French) 2018-09-21 13:50:18 +02:00
PhilippC
19e0cf406c New translations strings.xml (Finnish) 2018-09-21 13:50:15 +02:00
PhilippC
0bc1eece0a New translations strings.xml (Dutch) 2018-09-21 13:50:12 +02:00
PhilippC
f2e93e915b New translations strings.xml (Czech) 2018-09-21 13:50:09 +02:00
PhilippC
8db6a99194 New translations strings.xml (Croatian) 2018-09-21 13:50:06 +02:00
Philipp Crocoll
1490ebce03 minor refactoring 2018-09-21 06:26:04 +02:00
Philipp Crocoll
cd189e01dc use internal directory for offline caching. this reduces the likelihood of data loss. Users need to disable and then re-enable file caching to make sure all files are cached in the new directory. closes #83 https://github.com/PhilippC/keepass2android/issues/83 2018-09-18 06:18:17 +02:00
PhilippC
15467248ee New translations strings.xml (Chinese Simplified) 2018-09-18 04:31:09 +02:00
PhilippC
23008ab5b8 New translations strings.xml (Catalan) 2018-09-18 04:31:07 +02:00
PhilippC
041fbb10a1 New translations strings.xml (Bulgarian) 2018-09-18 04:31:04 +02:00
PhilippC
9ba0e59df5 New translations strings.xml (Danish) 2018-09-18 04:31:01 +02:00
PhilippC
0bb9f57919 New translations strings.xml (Basque) 2018-09-18 04:30:59 +02:00
PhilippC
106da869c1 New translations strings.xml (Italian) 2018-09-18 04:30:56 +02:00
PhilippC
d34a3352f2 New translations strings.xml (Korean) 2018-09-18 04:30:54 +02:00
PhilippC
4b5c922f11 New translations strings.xml (Ukrainian) 2018-09-18 04:30:52 +02:00
PhilippC
aacb415364 New translations strings.xml (Turkish) 2018-09-18 04:30:49 +02:00
PhilippC
bdc8bcfe5c New translations strings.xml (Swedish) 2018-09-18 04:30:46 +02:00
PhilippC
154238edf0 New translations strings.xml (Spanish) 2018-09-18 04:30:43 +02:00
PhilippC
eba789c200 New translations strings.xml (Slovenian) 2018-09-18 04:30:41 +02:00
PhilippC
63cb67a03c New translations strings.xml (Slovak) 2018-09-18 04:30:38 +02:00
PhilippC
1c299c6d5d New translations strings.xml (Serbian (Cyrillic)) 2018-09-18 04:30:36 +02:00
PhilippC
486c5310d7 New translations strings.xml (Japanese) 2018-09-18 04:30:34 +02:00
PhilippC
5ef4a97d5f New translations strings.xml (Russian) 2018-09-18 04:30:31 +02:00
PhilippC
03adb8f730 New translations strings.xml (Portuguese, Brazilian) 2018-09-18 04:30:29 +02:00
PhilippC
abdcd0b3f0 Merge pull request #555 from tobiasKaminsky/ncNaming
NextCloud -> Nextcloud
2018-09-18 04:29:26 +02:00
Philipp Crocoll
6e225808a9 add support for Binary Resource dictionaries of AnySoftKeyboard, fixes #245 2018-09-18 04:27:07 +02:00
tobiasKaminsky
382c96f587 NextCloud -> Nextcloud 2018-09-17 16:08:24 +02:00
PhilippC
80cb0119c7 New translations strings.xml (Portuguese) 2018-09-17 13:00:39 +02:00
PhilippC
e7bc5072c0 New translations strings.xml (Polish) 2018-09-17 13:00:36 +02:00
PhilippC
a65057679c New translations strings.xml (Persian) 2018-09-17 13:00:32 +02:00
PhilippC
025186d22f New translations strings.xml (Norwegian Bokmal) 2018-09-17 13:00:27 +02:00
PhilippC
e17217206f New translations strings.xml (Romanian) 2018-09-17 13:00:24 +02:00
PhilippC
c64ca44457 New translations strings.xml (Arabic) 2018-09-17 13:00:21 +02:00
PhilippC
c6e9a16274 Merge pull request #553 from PhilippC/1.07
1.07
2018-09-17 12:56:40 +02:00
PhilippC
f945380a87 New translations strings.xml (Chinese Traditional) 2018-09-17 11:11:12 +02:00
PhilippC
bb9664eafc New translations strings.xml (Japanese) 2018-09-17 11:10:38 +02:00
PhilippC
eaca802ecc New translations strings.xml (Portuguese, Brazilian) 2018-09-17 11:10:33 +02:00
PhilippC
2e6ca574b6 Merge pull request #552 from PhilippC/1.07
1.07
2018-09-17 11:03:58 +02:00
PhilippC
d4c61ce932 New translations strings.xml (Catalan) 2018-09-16 16:10:05 +02:00
PhilippC
7387ebe182 New translations strings.xml (Catalan) 2018-09-16 16:00:06 +02:00
PhilippC
d6f305cfa6 New translations strings.xml (Dutch) 2018-09-16 10:40:05 +02:00
PhilippC
73b9fbb435 New translations strings.xml (Dutch) 2018-09-16 10:30:05 +02:00
PhilippC
51c2f313d4 New translations strings.xml (Dutch) 2018-09-16 10:20:05 +02:00
PhilippC
0a390107a3 New translations strings.xml (Polish) 2018-09-12 22:40:06 +02:00
PhilippC
077bf997c6 New translations strings.xml (Vietnamese) 2018-09-12 17:10:23 +02:00
PhilippC
48cb473ecb New translations strings.xml (Japanese) 2018-09-12 17:10:19 +02:00
PhilippC
40dc542302 New translations strings.xml (Chinese Simplified) 2018-09-12 17:10:13 +02:00
PhilippC
28bb4894b2 New translations strings.xml (Catalan) 2018-09-12 17:10:08 +02:00
PhilippC
774d17dd25 New translations strings.xml (Chinese Traditional) 2018-09-12 17:01:33 +02:00
PhilippC
790637f1bd New translations strings.xml (Croatian) 2018-09-12 17:01:31 +02:00
PhilippC
99fb5d3b8e New translations strings.xml (Czech) 2018-09-12 17:01:28 +02:00
PhilippC
6676e62579 New translations strings.xml (Danish) 2018-09-12 17:01:25 +02:00
PhilippC
d735992f5c New translations strings.xml (Dutch) 2018-09-12 17:01:22 +02:00
PhilippC
8a32cfc185 New translations strings.xml (Finnish) 2018-09-12 17:01:19 +02:00
PhilippC
285fafc300 New translations strings.xml (French) 2018-09-12 17:01:16 +02:00
PhilippC
0c90433a34 New translations strings.xml (Galician) 2018-09-12 17:01:12 +02:00
PhilippC
d6070368b7 New translations strings.xml (German) 2018-09-12 17:01:09 +02:00
PhilippC
b42389500f New translations strings.xml (Greek) 2018-09-12 17:01:06 +02:00
PhilippC
daca972fc2 New translations strings.xml (Bulgarian) 2018-09-12 17:01:03 +02:00
PhilippC
8447e59d1f New translations strings.xml (Hebrew) 2018-09-12 17:01:00 +02:00
PhilippC
07ff8cd662 New translations strings.xml (Indonesian) 2018-09-12 17:00:57 +02:00
PhilippC
dbc734eee5 New translations strings.xml (Italian) 2018-09-12 17:00:54 +02:00
PhilippC
eaa95fdba4 New translations strings.xml (Japanese) 2018-09-12 17:00:49 +02:00
PhilippC
3ba1169e9c New translations strings.xml (Korean) 2018-09-12 17:00:46 +02:00
PhilippC
0117b53ea2 New translations strings.xml (Russian) 2018-09-12 17:00:43 +02:00
PhilippC
a2ec04b641 New translations strings.xml (Serbian (Cyrillic)) 2018-09-12 17:00:39 +02:00
PhilippC
8fdcef9c42 New translations strings.xml (Slovak) 2018-09-12 17:00:36 +02:00
PhilippC
d311de764d New translations strings.xml (Slovenian) 2018-09-12 17:00:33 +02:00
PhilippC
e9b16b2f70 New translations strings.xml (Spanish) 2018-09-12 17:00:29 +02:00
PhilippC
21a81b977b New translations strings.xml (Swedish) 2018-09-12 17:00:27 +02:00
PhilippC
9ce1c2b075 New translations strings.xml (Turkish) 2018-09-12 17:00:23 +02:00
PhilippC
b974cbd14c New translations strings.xml (Ukrainian) 2018-09-12 17:00:19 +02:00
PhilippC
1d96282fd9 New translations strings.xml (Hungarian) 2018-09-12 17:00:14 +02:00
PhilippC
48efda6bd9 New translations strings.xml (Basque) 2018-09-12 17:00:09 +02:00
PhilippC
aba3e0033f New translations strings.xml (Portuguese) 2018-09-12 05:00:37 +02:00
PhilippC
5bf61a63cc New translations strings.xml (Polish) 2018-09-12 05:00:35 +02:00
PhilippC
48095c0433 New translations strings.xml (Persian) 2018-09-12 05:00:31 +02:00
PhilippC
3e1599119a New translations strings.xml (Norwegian Nynorsk) 2018-09-12 05:00:29 +02:00
PhilippC
f488e8a7ab New translations strings.xml (Norwegian Bokmal) 2018-09-12 05:00:27 +02:00
PhilippC
b5c17bf7bc New translations strings.xml (Romanian) 2018-09-12 05:00:25 +02:00
PhilippC
77e994e9fd New translations strings.xml (Arabic) 2018-09-12 05:00:22 +02:00
PhilippC
bbd3fc4d1d Merge pull request #543 from PhilippC/1.07
first 1.07 features
2018-09-12 04:53:01 +02:00
PhilippC
2a57b94e08 New translations strings.xml (German) 2018-09-09 21:20:06 +02:00
PhilippC
366a37b765 New translations strings.xml (Polish) 2018-09-09 16:40:05 +02:00
PhilippC
a3806f7a81 New translations strings.xml (Greek) 2018-09-06 22:00:07 +02:00
PhilippC
cf28e373f7 Merge pull request #535 from gilbsgilbs/pcloud-integration
Implement requiresSetup for PCloud.
2018-09-06 03:45:20 +02:00
Gilbert Gilb's
8d80295e07 Implement requiresSetup for PCloud.
Also consider error 2095 as a logout, so that the user can re-login.
2018-09-04 20:59:00 +02:00
PhilippC
1f7ffe6ea0 New translations strings.xml (Catalan) 2018-09-03 15:00:07 +02:00
PhilippC
a740753175 New translations strings.xml (Czech) 2018-09-02 10:30:06 +02:00
PhilippC
c70f996915 New translations strings.xml (Ukrainian) 2018-08-30 15:40:06 +02:00
PhilippC
707dfc2a0b New translations strings.xml (Chinese Traditional) 2018-08-30 01:20:53 +02:00
PhilippC
77db3362fc New translations strings.xml (French) 2018-08-30 01:20:41 +02:00
PhilippC
c8e0687288 New translations strings.xml (Russian) 2018-08-30 01:20:24 +02:00
PhilippC
f61a6191ec New translations strings.xml (Slovak) 2018-08-30 01:20:20 +02:00
PhilippC
2648236bb4 New translations strings.xml (Spanish) 2018-08-30 01:20:16 +02:00
PhilippC
382e23f545 New translations strings.xml (Turkish) 2018-08-30 01:20:12 +02:00
PhilippC
2eddbe3669 New translations strings.xml (Ukrainian) 2018-08-30 01:20:09 +02:00
PhilippC
5e41517178 New translations strings.xml (Portuguese) 2018-08-28 21:00:25 +02:00
PhilippC
177c709e0a New translations strings.xml (Chinese Simplified) 2018-08-24 08:00:06 +02:00
PhilippC
699eb824a1 New translations strings.xml (Chinese Simplified) 2018-08-24 07:50:05 +02:00
PhilippC
6b19e305f3 New translations strings.xml (Chinese Simplified) 2018-08-21 20:40:44 +02:00
PhilippC
8b1b4044b3 New translations strings.xml (Portuguese) 2018-08-21 20:40:18 +02:00
351 changed files with 25781 additions and 7856 deletions

View File

@@ -4,3 +4,7 @@ files:
/src/keepass2android/Resources/values-%two_letters_code%/%original_file_name%
translate_attributes: '0'
content_segmentation: '0'
languages_mapping:
two_letters_code:
zh-CN: zh
zh-TW: zh-rTW

View File

@@ -2,7 +2,7 @@ Keepass2Android's apk is pretty big, e.g. when comparing to Keepassdroid. The ma
Here's a list of what is contained in the Keepass2Android 0.9.1 application package:
{{
```
Mono for Android
.net dlls 5.0 MB
Runtime 2.5 MB
@@ -22,4 +22,4 @@ Java/Mono bindings 0.5 MB
rest 0.3 MB
TOTAL 13 MB
}}
```

View File

@@ -1,3 +1,6 @@
<h1 align="center"><img src="/src/keepass2android/Resources/mipmap-xxxhdpi/ic_launcher_online.png" align="center" width="100" alt="Keepass2Android Logo">Keepass2Android</h1>
# What is Keepass2Android?
Keepass2Android is a password manager app. It allows to store and retrieve passwords and other sensitive information in a file called "database". This database is secured with a so-called master password. The master password typically is a strong password and can be complemented with a second factor for additional security.
The password database file can be synchronized across different devices. This works best using one of the built-in cloud storage options, but can also be performed with third-party apps. Keepass2Android is compatible with Keepass 1 and Keepass 2 on Windows and KeepassX on Linux.

View File

@@ -81,10 +81,6 @@
</XamarinComponentReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AdalBindings\AdalBindings.csproj">
<Project>{0b109c0e-0514-4340-8779-5bd6a0dde84e}</Project>
<Name>AdalBindings</Name>
</ProjectReference>
<ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj" />
</ItemGroup>
<ItemGroup>

View File

@@ -29,8 +29,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCloudBindings", "PCloudBindings\PCloudBindings.csproj", "{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdalBindings", "AdalBindings\AdalBindings.csproj", "{0B109C0E-0514-4340-8779-5BD6A0DDE84E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -317,30 +315,6 @@ Global
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Win32.Build.0 = ReleaseNoNet|Any CPU
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|x64.Build.0 = ReleaseNoNet|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Win32.ActiveCfg = Debug|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Win32.Build.0 = Debug|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|x64.ActiveCfg = Debug|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|x64.Build.0 = Debug|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Any CPU.Build.0 = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Win32.ActiveCfg = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Win32.Build.0 = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|x64.ActiveCfg = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|x64.Build.0 = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -21,7 +21,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using keepass2android;
#if KeePassUAP
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
@@ -144,6 +144,7 @@ namespace KeePassLib.Cryptography.KeyDerivation
public static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
ulong uNumRounds)
{
Kp2aLog.Log("Warning: transforming key managed. Expect this to be slow!");
#if KeePassUAP
KeyParameter kp = new KeyParameter(pbKeySeed32);
AesEngine aes = new AesEngine();

View File

@@ -38,9 +38,11 @@ namespace KeePassLib.Keys
get;
}
// /// <summary>
// /// Clear the key and securely erase all security-critical information.
// /// </summary>
// void Clear();
// /// <summary>
// /// Clear the key and securely erase all security-critical information.
// /// </summary>
// void Clear();
uint GetMinKdbxVersion();
}
}

View File

@@ -45,7 +45,12 @@ namespace KeePassLib.Keys
get { return m_pbKey; }
}
public KcpCustomKey(string strName, byte[] pbKeyData, bool bPerformHash)
public uint GetMinKdbxVersion()
{
return 0;
}
public KcpCustomKey(string strName, byte[] pbKeyData, bool bPerformHash)
{
Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
Debug.Assert(pbKeyData != null); if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");

View File

@@ -64,7 +64,12 @@ namespace KeePassLib.Keys
get { return m_pbKeyData; }
}
public IOConnectionInfo Ioc
public uint GetMinKdbxVersion()
{
return 0;
}
public IOConnectionInfo Ioc
{
get { return m_ioc; }
}

View File

@@ -53,7 +53,12 @@ namespace KeePassLib.Keys
get { return m_pbKeyData; }
}
public KcpPassword(byte[] pbPasswordUtf8)
public uint GetMinKdbxVersion()
{
return 0;
}
public KcpPassword(byte[] pbPasswordUtf8)
{
SetKey(pbPasswordUtf8);
}

View File

@@ -60,7 +60,12 @@ namespace KeePassLib.Keys
get { return m_pbKeyData; }
}
/// <summary>
public uint GetMinKdbxVersion()
{
return 0;
}
/// <summary>
/// Construct a user account key.
/// </summary>
public KcpUserAccount()

View File

@@ -85,8 +85,8 @@ namespace keepass2android
{
if (!File.Exists(LogFilename))
{
File.Create(LogFilename);
_logToFile = true;
File.Create(LogFilename).Dispose();
_logToFile = true;
}
@@ -100,8 +100,7 @@ namespace keepass2android
int count = 0;
while (File.Exists(LogFilename + "." + count))
count++;
if (count > 0)
File.Move(LogFilename, LogFilename + "." + count);
File.Move(LogFilename, LogFilename + "." + count);
}

View File

@@ -302,7 +302,7 @@ namespace KeePassLib.Native
}
catch (Exception e)
{
Kp2aLog.Log(e.Message);
Kp2aLog.Log(e.ToString());
return false;
}

View File

@@ -485,12 +485,6 @@ namespace KeePassLib
set { m_pbHashOfLastIO = value; }
}
public bool UseFileTransactions
{
get { return m_bUseFileTransactions; }
set { m_bUseFileTransactions = value; }
}
public bool UseFileLocks
{
get { return m_bUseFileLocks; }

View File

@@ -360,5 +360,12 @@ namespace KeePassLib.Serialization
m_ioCredProtMode = IOCredProtMode.None;
}
}
public bool IsSameFileAs(IOConnectionInfo other)
{
if (other == null)
return false;
return Path == other.Path && UserName == other.UserName;
}
}
}

View File

@@ -23,6 +23,7 @@ using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security;
using System.Text;
using System.Xml;
@@ -126,8 +127,8 @@ namespace KeePassLib.Serialization
/// </summary>
private const uint FileVersion32 = 0x00040000;
internal const uint FileVersion32_4 = 0x00040000; // First of 4.x series
internal const uint FileVersion32_3 = 0x00030001; // Old format 3.1
public const uint FileVersion32_4 = 0x00040000; // First of 4.x series
public const uint FileVersion32_3 = 0x00030001; // Old format 3.1
private const uint FileVersionCriticalMask = 0xFFFF0000;
@@ -372,16 +373,19 @@ namespace KeePassLib.Serialization
{
if(m_uForceVersion != 0) return m_uForceVersion;
// See also KeePassKdb2x3.Export (KDBX 3.1 export module)
AesKdf kdfAes = new AesKdf();
// See also KeePassKdb2x3.Export (KDBX 3.1 export module)
uint minVersionForKeys = m_pwDatabase.MasterKey.UserKeys.Select(key => key.GetMinKdbxVersion()).Max();
AesKdf kdfAes = new AesKdf();
if(!kdfAes.Uuid.Equals(m_pwDatabase.KdfParameters.KdfUuid))
return FileVersion32;
return Math.Max(FileVersion32, minVersionForKeys);
if(m_pwDatabase.PublicCustomData.Count > 0)
return FileVersion32;
return Math.Max(FileVersion32, minVersionForKeys);
bool bCustomData = false;
bool bCustomData = false;
GroupHandler gh = delegate(PwGroup pg)
{
if(pg == null) { Debug.Assert(false); return true; }
@@ -396,9 +400,10 @@ namespace KeePassLib.Serialization
};
gh(m_pwDatabase.RootGroup);
m_pwDatabase.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh);
if(bCustomData) return FileVersion32;
if(bCustomData)
return Math.Max(FileVersion32, minVersionForKeys);
return FileVersion32_3; // KDBX 3.1 is sufficient
return Math.Max(FileVersion32_3, minVersionForKeys); ; // KDBX 3.1 is sufficient
}
private void ComputeKeys(out byte[] pbCipherKey, int cbCipherKey,

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using keepass2android.Io;
using KeePassLib;
using KeePassLib.Interfaces;
using KeePassLib.Utility;
namespace keepass2android
{
public class ElementAndDatabaseId
{
private const char Separator = '+';
public ElementAndDatabaseId(Database db, IStructureItem element)
{
DatabaseId = db.IocAsHexString();
ElementIdString = element.Uuid.ToHexString();
}
public ElementAndDatabaseId(string fullId)
{
string[] parts = fullId.Split(Separator);
if (parts.Length != 2)
throw new Exception("Invalid full id " + fullId);
DatabaseId = parts[0];
ElementIdString = parts[1];
}
public string DatabaseId { get; set; }
public string ElementIdString { get; set; }
public PwUuid ElementId { get { return new PwUuid(MemUtil.HexStringToByteArray(ElementIdString));} }
public string FullId
{
get { return DatabaseId + Separator + ElementIdString; }
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Android.App;
@@ -9,6 +10,7 @@ using KeePassLib;
using KeePassLib.Keys;
using KeePassLib.Serialization;
using keepass2android.Io;
using KeePassLib.Interfaces;
#if !NoNet
using Keepass2android.Javafilestorage;
#endif
@@ -33,31 +35,41 @@ namespace keepass2android
/// This also contains methods which are UI specific and should be replacable for testing.
public interface IKp2aApp : ICertificateValidationHandler
{
/// <summary>
/// Locks the currently open database, quicklocking if available (unless false is passed for allowQuickUnlock)
/// </summary>
void LockDatabase(bool allowQuickUnlock = true);
/// <summary>
/// Locks all currently open databases, quicklocking if available (unless false is passed for allowQuickUnlock)
/// </summary>
void Lock(bool allowQuickUnlock);
/// <summary>
/// Loads the specified data as the currently open database, as unlocked.
/// </summary>
void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey,
ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat);
/// <summary>
/// Returns the current database
/// </summary>
Database GetDb();
/// <summary>
/// Loads the specified data as the currently open database, as unlocked.
/// </summary>
Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat, bool makeCurrent);
/// <summary>
/// Tell the app that the file from ioc was opened with keyfile.
/// </summary>
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile, string displayName = "");
HashSet<PwGroup> DirtyGroups { get; }
void MarkAllGroupsAsDirty();
/// <summary>
/// Returns the current database
/// </summary>
Database CurrentDb { get; }
IEnumerable<Database> OpenDatabases { get; }
void CloseDatabase(Database db);
Database FindDatabaseForElement(IStructureItem element);
/// <summary>
/// Tell the app that the file from ioc was opened with keyfile.
/// </summary>
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile, bool updateTimestamp, string displayName = "");
/// <summary>
/// Creates a new database and returns it
/// </summary>
Database CreateNewDatabase();
Database CreateNewDatabase(bool makeCurrent);
/// <summary>
/// Returns the user-displayable string identified by stringKey
@@ -76,7 +88,8 @@ namespace keepass2android
EventHandler<DialogClickEventArgs> yesHandler,
EventHandler<DialogClickEventArgs> noHandler,
EventHandler<DialogClickEventArgs> cancelHandler,
Context ctx);
Context ctx,
string messageSuffix = "");
/// <summary>
/// Asks the user the question "messageKey" with the options Yes/No/Cancel, but the yes/no strings can be selected freely, calls the handler corresponding to the answer.
@@ -86,7 +99,8 @@ namespace keepass2android
EventHandler<DialogClickEventArgs> yesHandler,
EventHandler<DialogClickEventArgs> noHandler,
EventHandler<DialogClickEventArgs> cancelHandler,
Context ctx);
Context ctx,
string messageSuffix = "");
/// <summary>
/// Returns a Handler object which can run tasks on the UI thread
@@ -111,6 +125,10 @@ namespace keepass2android
bool CheckForDuplicateUuids { get; }
#if !NoNet
ICertificateErrorHandler CertificateErrorHandler { get; }
#endif
}
}

View File

@@ -207,8 +207,7 @@ namespace keepass2android.Io
public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
{
//TODO: required for OTP Aux file retrieval
throw new NotImplementedException();
return IoUtil.GetParentPath(ioc);
}
public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)

View File

@@ -255,7 +255,8 @@ namespace keepass2android.Io
if (ioc.IsLocalFile())
{
bool requiresPermission = !(ioc.Path.StartsWith(activity.Activity.FilesDir.CanonicalPath)
|| ioc.Path.StartsWith(IoUtil.GetInternalDirectory(activity.Activity).CanonicalPath));
|| ioc.Path.StartsWith(IoUtil.GetInternalDirectory(activity.Activity).CanonicalPath)
|| ioc.Path.StartsWith(IoUtil.GetInternalDirectory(activity.Activity).CanonicalPath));
var extDirectory = activity.Activity.GetExternalFilesDir(null);
if ((extDirectory != null) && (ioc.Path.StartsWith(extDirectory.CanonicalPath)))

View File

@@ -65,22 +65,28 @@ namespace keepass2android.Io
protected readonly OfflineSwitchableFileStorage _cachedStorage;
private readonly ICacheSupervisor _cacheSupervisor;
private readonly string _streamCacheDir;
private readonly string _legacyCacheDir;
private readonly string _cacheDir;
public CachingFileStorage(IFileStorage cachedStorage, string cacheDir, ICacheSupervisor cacheSupervisor)
public CachingFileStorage(IFileStorage cachedStorage, Context cacheDirContext, ICacheSupervisor cacheSupervisor)
{
_cachedStorage = new OfflineSwitchableFileStorage(cachedStorage);
_cacheSupervisor = cacheSupervisor;
_streamCacheDir = cacheDir + Java.IO.File.Separator + "OfflineCache" + Java.IO.File.Separator;
if (!Directory.Exists(_streamCacheDir))
Directory.CreateDirectory(_streamCacheDir);
}
_legacyCacheDir = cacheDirContext.CacheDir.Path + Java.IO.File.Separator + "OfflineCache" + Java.IO.File.Separator;
if (!Directory.Exists(_legacyCacheDir))
Directory.CreateDirectory(_legacyCacheDir);
_cacheDir = IoUtil.GetInternalDirectory(cacheDirContext).Path + Java.IO.File.Separator + "OfflineCache" + Java.IO.File.Separator;
if (!Directory.Exists(_cacheDir))
Directory.CreateDirectory(_cacheDir);
}
public void ClearCache()
{
IoUtil.DeleteDir(new Java.IO.File(_streamCacheDir), true);
}
IoUtil.DeleteDir(new Java.IO.File(_legacyCacheDir), true);
IoUtil.DeleteDir(new Java.IO.File(_cacheDir), true);
}
public IEnumerable<string> SupportedProtocols { get { return _cachedStorage.SupportedProtocols; } }
@@ -105,7 +111,11 @@ namespace keepass2android.Io
{
SHA256Managed sha256 = new SHA256Managed();
string iocAsHexString = MemUtil.ByteArrayToHexString(sha256.ComputeHash(Encoding.Unicode.GetBytes(ioc.Path.ToCharArray())))+".cache";
return _streamCacheDir + iocAsHexString;
if (File.Exists(_legacyCacheDir + iocAsHexString))
return _legacyCacheDir + iocAsHexString;
return _cacheDir + iocAsHexString;
}
public bool IsCached(IOConnectionInfo ioc)
@@ -168,7 +178,9 @@ namespace keepass2android.Io
if (!IsCached(ioc))
throw;
Kp2aLog.Log("couldn't open from remote " + ioc.Path);
#if DEBUG
Kp2aLog.Log("couldn't open from remote " + ioc.Path);
#endif
Kp2aLog.Log(ex.ToString());
_cacheSupervisor.CouldntOpenFromRemote(ioc, ex);

View File

@@ -233,7 +233,6 @@ namespace keepass2android.Io
public FileDescription GetFileDescription(IOConnectionInfo ioc)
{
Kp2aLog.Log("GetFileDescription "+ioc.Path);
try
{
return ConvertToFileDescription(Jfs.GetFileEntry(IocToPath(ioc)));
@@ -302,7 +301,9 @@ namespace keepass2android.Io
public void OnResume(IFileStorageSetupActivity activity)
{
#if DEBUG
Kp2aLog.Log("JFS/OnResume Ioc.Path=" +activity.Ioc.Path+". Path="+((IJavaFileStorageFileStorageSetupActivity)activity).Path);
#endif
_jfs.OnResume(((IJavaFileStorageFileStorageSetupActivity) activity));
}
@@ -366,4 +367,4 @@ namespace keepass2android.Io
}
}
#endif
}
}

View File

@@ -91,7 +91,7 @@
<Compile Include="database\CheckDatabaseForChanges.cs" />
<Compile Include="database\edit\AddTemplateEntries.cs" />
<Compile Include="database\edit\CopyEntry.cs" />
<Compile Include="database\edit\DeleteMultipleItems.cs" />
<Compile Include="database\edit\DeleteMultipleItemsFromOneDatabase.cs" />
<Compile Include="database\edit\EditGroup.cs" />
<Compile Include="database\edit\MoveElements.cs" />
<Compile Include="database\KdbDatabaseFormat.cs" />
@@ -103,6 +103,7 @@
<Compile Include="DataExchange\Formats\KeePassKdb2x.cs" />
<Compile Include="DataExchange\Formats\KeePassXml2x.cs" />
<Compile Include="DataExchange\PwExportInfo.cs" />
<Compile Include="ElementAndDatabaseId.cs" />
<Compile Include="Io\AndroidContentStorage.cs" />
<Compile Include="Io\BuiltInFileStorage.cs" />
<Compile Include="Io\CachingFileStorage.cs" />
@@ -156,10 +157,6 @@
<Compile Include="Utils\Spr\SprEngine.PickChars.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AdalBindings\AdalBindings.csproj">
<Project>{0b109c0e-0514-4340-8779-5bd6a0dde84e}</Project>
<Name>AdalBindings</Name>
</ProjectReference>
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj">
<Project>{48574278-4779-4b3a-a9e4-9cf1bc285d0b}</Project>
<Name>JavaFileStorageBindings</Name>

View File

@@ -52,7 +52,8 @@ namespace keepass2android
public void UpdateMessage (String message)
{
_message = message;
Kp2aLog.Log("status message: " + message);
_message = message;
if ( _app!= null && _progressDialog != null && _handler != null ) {
_handler.Post(() => {_progressDialog.SetMessage(message); } );
}
@@ -60,6 +61,7 @@ namespace keepass2android
public void UpdateSubMessage(String submessage)
{
Kp2aLog.Log("status submessage: " + submessage);
_submessage = submessage;
if (_app != null && _progressDialog != null && _handler != null)
{

View File

@@ -23,7 +23,7 @@ namespace keepass2android
/// <summary>
/// EqualityComparer implementation to compare PwGroups based on their Id
/// </summary>
class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup>
public class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup>
{
#region IEqualityComparer implementation
public bool Equals (PwGroup x, PwGroup y)

View File

@@ -103,7 +103,7 @@ namespace keepass2android
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch) {IsVirtual = true};
if (String.IsNullOrWhiteSpace(host))
return pgResults;
foreach (PwEntry entry in database.Entries.Values)
foreach (PwEntry entry in database.EntriesById.Values)
{
string otherUrl = entry.Strings.ReadSafe(PwDefs.UrlField);
otherUrl = SprEngine.Compile(otherUrl, new SprContext(entry, database.KpDatabase, SprCompileFlags.References));

View File

@@ -86,6 +86,8 @@ namespace keepass2android
ReadOnlyReason_PreKitKat,
ReadOnlyReason_ReadOnlyFlag,
ReadOnlyReason_ReadOnlyKitKat,
ReadOnlyReason_LocalBackup
ReadOnlyReason_LocalBackup,
Ok,
cancel
}
}

View File

@@ -29,7 +29,7 @@ namespace keepass2android
{
try
{
IOConnectionInfo ioc = _app.GetDb().Ioc;
IOConnectionInfo ioc = _app.CurrentDb.Ioc;
IFileStorage fileStorage = _app.GetFileStorage(ioc);
if (fileStorage is CachingFileStorage)
{
@@ -49,7 +49,7 @@ namespace keepass2android
hashingRemoteStream.CopyTo(remoteData);
hashingRemoteStream.Close();
if (!MemUtil.ArraysEqual(_app.GetDb().KpDatabase.HashOfFileOnDisk, hashingRemoteStream.Hash))
if (!MemUtil.ArraysEqual(_app.CurrentDb.KpDatabase.HashOfFileOnDisk, hashingRemoteStream.Hash))
{
_app.TriggerReload(_context);
Finish(true);

View File

@@ -26,6 +26,7 @@ using KeePassLib;
using KeePassLib.Keys;
using KeePassLib.Serialization;
using keepass2android.Io;
using KeePassLib.Interfaces;
using KeePassLib.Utility;
using Exception = System.Exception;
using String = System.String;
@@ -33,27 +34,23 @@ using String = System.String;
namespace keepass2android
{
public class Database {
public Dictionary<PwUuid, PwGroup> Groups = new Dictionary<PwUuid, PwGroup>(new PwUuidEqualityComparer());
public Dictionary<PwUuid, PwEntry> Entries = new Dictionary<PwUuid, PwEntry>(new PwUuidEqualityComparer());
public HashSet<PwGroup> Dirty = new HashSet<PwGroup>(new PwGroupEqualityFromIdComparer());
public class Database
{
public HashSet<IStructureItem> Elements = new HashSet<IStructureItem>();
public Dictionary<PwUuid, PwGroup> GroupsById = new Dictionary<PwUuid, PwGroup>(new PwUuidEqualityComparer());
public Dictionary<PwUuid, PwEntry> EntriesById = new Dictionary<PwUuid, PwEntry>(new PwUuidEqualityComparer());
public PwGroup Root;
public PwDatabase KpDatabase;
public IOConnectionInfo Ioc
{
get
{
return KpDatabase == null ? null : KpDatabase.IOConnectionInfo;
return KpDatabase?.IOConnectionInfo;
}
}
/// <summary>
/// Information about the last opened entry. Includes the entry but also transformed fields.
/// </summary>
public PwEntryOutput LastOpenedEntry { get; set; }
/// <summary>
/// if an OTP key was used, this property tells the location of the OTP auxiliary file.
/// Must be set after loading.
@@ -73,31 +70,14 @@ namespace keepass2android
_app = app;
CanWrite = true; //default
}
private bool _loaded;
private bool _reloadRequested;
private IDatabaseFormat _databaseFormat = new KdbxDatabaseFormat(KdbxFormat.Default);
private IDatabaseFormat _databaseFormat = new KdbxDatabaseFormat(KdbxFormat.Default);
public bool ReloadRequested
{
get { return _reloadRequested; }
set { _reloadRequested = value; }
}
public bool ReloadRequested { get; set; }
public bool Loaded {
get { return _loaded;}
set { _loaded = value; }
}
public bool DidOpenFileChange()
public bool DidOpenFileChange()
{
if (Loaded == false)
{
return false;
}
return _app.GetFileStorage(Ioc).CheckForFileChangeFast(Ioc, LastFileVersion);
}
@@ -112,32 +92,20 @@ namespace keepass2android
Stream s = databaseData ?? fileStorage.OpenFileForRead(iocInfo);
var fileVersion = _app.GetFileStorage(iocInfo).GetCurrentFileVersionFast(iocInfo);
PopulateDatabaseFromStream(pwDatabase, s, iocInfo, compositeKey, status, databaseFormat);
try
{
LastFileVersion = fileVersion;
LastFileVersion = fileVersion;
status.UpdateSubMessage("");
status.UpdateSubMessage("");
Root = pwDatabase.RootGroup;
PopulateGlobals(Root);
Root = pwDatabase.RootGroup;
PopulateGlobals(Root);
KpDatabase = pwDatabase;
SearchHelper = new SearchDbHelper(app);
KpDatabase = pwDatabase;
SearchHelper = new SearchDbHelper(app);
_databaseFormat = databaseFormat;
_databaseFormat = databaseFormat;
CanWrite = databaseFormat.CanWrite && !fileStorage.IsReadOnly(iocInfo);
Loaded = true;
}
catch (Exception)
{
Clear();
throw;
}
CanWrite = databaseFormat.CanWrite && !fileStorage.IsReadOnly(iocInfo);
}
/// <summary>
@@ -219,8 +187,7 @@ namespace keepass2android
public void SaveData() {
KpDatabase.UseFileTransactions = _app.GetBooleanPreference(PreferenceKey.UseFileTransactions);
using (IWriteTransaction trans = _app.GetFileStorage(Ioc).OpenWriteTransaction(Ioc, KpDatabase.UseFileTransactions))
using (IWriteTransaction trans = _app.GetFileStorage(Ioc).OpenWriteTransaction(Ioc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions)))
{
DatabaseFormat.Save(KpDatabase, trans.OpenFile());
@@ -239,14 +206,18 @@ namespace keepass2android
{
if (checkForDuplicateUuids)
{
if (Entries.ContainsKey(e.Uuid))
if (EntriesById.ContainsKey(e.Uuid))
{
throw new DuplicateUuidsException("Same UUID for entries '"+Entries[e.Uuid].Strings.ReadSafe(PwDefs.TitleField)+"' and '"+e.Strings.ReadSafe(PwDefs.TitleField)+"'.");
throw new DuplicateUuidsException("Same UUID for entries '"+EntriesById[e.Uuid].Strings.ReadSafe(PwDefs.TitleField)+"' and '"+e.Strings.ReadSafe(PwDefs.TitleField)+"'.");
}
}
Entries [e.Uuid] = e;
EntriesById [e.Uuid] = e;
Elements.Add(e);
}
GroupsById[currentGroup.Uuid] = currentGroup;
Elements.Add(currentGroup);
foreach (PwGroup g in childGroups)
{
if (checkForDuplicateUuids)
@@ -258,7 +229,6 @@ namespace keepass2android
}
* */
}
Groups[g.Uuid] = g;
PopulateGlobals(g);
}
}
@@ -266,33 +236,15 @@ namespace keepass2android
{
PopulateGlobals(currentGroup, _app.CheckForDuplicateUuids);
}
public void Clear() {
_loaded = false;
Groups.Clear();
Entries.Clear();
Dirty.Clear();
DrawableFactory.Clear();
Root = null;
KpDatabase = null;
CanWrite = true;
_reloadRequested = false;
OtpAuxFileIoc = null;
LastOpenedEntry = null;
}
public void MarkAllGroupsAsDirty() {
foreach ( PwGroup group in Groups.Values ) {
Dirty.Add(group);
}
}
public void UpdateGlobals()
{
EntriesById.Clear();
GroupsById.Clear();
Elements.Clear();
PopulateGlobals(Root);
}
}
[Serializable]

View File

@@ -216,9 +216,16 @@ namespace keepass2android
private DateTime JavaTimeToCSharp(long javatime)
{
try
{
var utcTime = new DateTime(1970, 1, 1).AddMilliseconds(javatime);
return TimeZoneInfo.ConvertTimeFromUtc(utcTime, TimeZoneInfo.Local);
}
catch (ArgumentOutOfRangeException)
{
return DateTime.MinValue;
}
var utcTime = new DateTime(1970, 1, 1).AddMilliseconds(javatime);
return TimeZoneInfo.ConvertTimeFromUtc(utcTime, TimeZoneInfo.Local);
}
#endif

View File

@@ -14,13 +14,13 @@ namespace keepass2android
public class PwEntryOutput
{
private readonly PwEntry _entry;
private readonly PwDatabase _db;
private readonly Database _db;
private readonly ProtectedStringDictionary _outputStrings = new ProtectedStringDictionary();
/// <summary>
/// Constructs the PwEntryOutput by replacing the placeholders
/// </summary>
public PwEntryOutput(PwEntry entry, PwDatabase db)
public PwEntryOutput(PwEntry entry, Database db)
{
_entry = entry;
_db = db;
@@ -34,7 +34,7 @@ namespace keepass2android
string GetStringAndReplacePlaceholders(string key)
{
String value = Entry.Strings.ReadSafe(key);
value = SprEngine.Compile(value, new SprContext(Entry, _db, SprCompileFlags.All));
value = SprEngine.Compile(value, new SprContext(Entry, _db.KpDatabase, SprCompileFlags.All));
return value;
}

View File

@@ -26,7 +26,7 @@ namespace keepass2android
{
try
{
IOConnectionInfo ioc = _app.GetDb().Ioc;
IOConnectionInfo ioc = _app.CurrentDb.Ioc;
IFileStorage fileStorage = _app.GetFileStorage(ioc);
if (!(fileStorage is CachingFileStorage))
{
@@ -70,10 +70,12 @@ namespace keepass2android
Finish(true, _app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
}
_saveDb = null;
}), false, remoteData);
}), _app.CurrentDb, false, remoteData);
_saveDb.Run();
_app.GetDb().MarkAllGroupsAsDirty();
_app.CurrentDb.UpdateGlobals();
_app.MarkAllGroupsAsDirty();
}
else
{
@@ -103,6 +105,7 @@ namespace keepass2android
}
catch (Exception e)
{
Kp2aLog.LogUnexpectedError(e);
Finish(false, e.Message);
}

View File

@@ -24,7 +24,7 @@ namespace keepass2android
public class AddEntry : RunnableOnFinish {
protected Database Db
{
get { return _app.GetDb(); }
get { return _app.CurrentDb; }
}
private readonly IKp2aApp _app;
@@ -37,13 +37,13 @@ namespace keepass2android
return new AddEntry(ctx, app, entry, parentGroup, finish);
}
protected AddEntry(Activity ctx, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(ctx, finish) {
public AddEntry(Activity ctx, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(ctx, finish) {
_ctx = ctx;
_parentGroup = parentGroup;
_app = app;
_entry = entry;
_onFinishToRun = new AfterAdd(ctx, app.GetDb(), entry, OnFinishToRun);
_onFinishToRun = new AfterAdd(ctx, app.CurrentDb, entry, app,OnFinishToRun);
}
@@ -60,7 +60,7 @@ namespace keepass2android
// Commit to disk
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun);
save.SetStatusLogger(StatusLogger);
save.Run();
}
@@ -68,12 +68,13 @@ namespace keepass2android
private class AfterAdd : OnFinish {
private readonly Database _db;
private readonly PwEntry _entry;
private readonly IKp2aApp _app;
public AfterAdd(Activity activity, Database db, PwEntry entry, OnFinish finish):base(activity, finish) {
public AfterAdd(Activity activity, Database db, PwEntry entry, IKp2aApp app, OnFinish finish):base(activity, finish) {
_db = db;
_entry = entry;
}
_app = app;
}
@@ -83,11 +84,12 @@ namespace keepass2android
PwGroup parent = _entry.ParentGroup;
// Mark parent group dirty
_db.Dirty.Add(parent);
_app.DirtyGroups.Add(parent);
// Add entry to global
_db.Entries[_entry.Uuid] = _entry;
_db.EntriesById[_entry.Uuid] = _entry;
_db.Elements.Add(_entry);
} else
{
StatusLogger.UpdateMessage(UiStringKey.UndoingChanges);

View File

@@ -26,13 +26,16 @@ namespace keepass2android
public class AddGroup : RunnableOnFinish {
internal Database Db
{
get { return _app.GetDb(); }
get { return _app.CurrentDb; }
}
private IKp2aApp _app;
public IKp2aApp App { get => _app; }
private IKp2aApp _app;
private readonly String _name;
private readonly int _iconId;
private readonly PwUuid _groupCustomIconId;
internal PwGroup Group;
public PwGroup Group;
internal PwGroup Parent;
protected bool DontSave;
readonly Activity _ctx;
@@ -67,9 +70,11 @@ namespace keepass2android
Group.CustomIconUuid = _groupCustomIconId;
}
Parent.AddGroup(Group, true);
_app.CurrentDb.GroupsById[Group.Uuid] = Group;
_app.CurrentDb.Elements.Add(Group);
// Commit to disk
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, DontSave);
// Commit to disk
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun, DontSave);
save.SetStatusLogger(StatusLogger);
save.Run();
}
@@ -86,13 +91,15 @@ namespace keepass2android
if ( Success ) {
// Mark parent group dirty
_addGroup.Db.Dirty.Add(_addGroup.Parent);
_addGroup.App.DirtyGroups.Add(_addGroup.Parent);
// Add group to global list
_addGroup.Db.Groups[_addGroup.Group.Uuid] = _addGroup.Group;
_addGroup.Db.GroupsById[_addGroup.Group.Uuid] = _addGroup.Group;
_addGroup.Db.Elements.Add(_addGroup.Group);
} else {
StatusLogger.UpdateMessage(UiStringKey.UndoingChanges);
_addGroup.Parent.Groups.Remove(_addGroup.Group);
}
base.Run();

View File

@@ -28,7 +28,7 @@ namespace keepass2android
{
public class AddTemplateEntries : RunnableOnFinish {
class TemplateEntry
public class TemplateEntry
{
public UiStringKey Title { get; set; }
public PwIcon Icon { get; set; }
@@ -47,11 +47,12 @@ namespace keepass2android
void AddToEntry(IKp2aApp app, PwEntry entry, int position);
}
internal enum FieldType
public enum FieldType
{
Inline, ProtectedInline
}
internal enum SpecialFieldKey
public enum SpecialFieldKey
{
ExpDate, OverrideUrl, Tags
}
@@ -125,7 +126,7 @@ namespace keepass2android
protected Database Db
{
get { return _app.GetDb(); }
get { return _app.CurrentDb; }
}
private readonly IKp2aApp _app;
@@ -140,7 +141,7 @@ namespace keepass2android
//_onFinishToRun = new AfterAdd(this, OnFinishToRun);
}
static readonly List<TemplateEntry> TemplateEntries = new List<TemplateEntry>()
public static readonly List<TemplateEntry> TemplateEntries = new List<TemplateEntry>()
{
new TemplateEntry()
{
@@ -285,12 +286,23 @@ namespace keepass2android
};
public static bool ContainsAllTemplates(IKp2aApp app)
public static bool ContainsAllTemplates(Database db)
{
return TemplateEntries.All(t => app.GetDb().Entries.ContainsKey(t.Uuid));
return TemplateEntries.All(t =>
{
string hexId = t.Uuid.ToHexString();
return db.EntriesById.Any(kvp => kvp.Key.Equals(t.Uuid) ||
kvp.Value.Strings.ReadSafe(TemplateIdStringKey) == hexId);
});
}
public override void Run() {
public static string TemplateIdStringKey
{
get { return "KP2A_TemplateId"; }
}
public override void Run() {
StatusLogger.UpdateMessage(UiStringKey.AddingEntry);
List<PwEntry> addedEntries;
@@ -298,10 +310,10 @@ namespace keepass2android
if (addedEntries.Any())
{
_app.GetDb().Dirty.Add(templateGroup);
_app.DirtyGroups.Add(templateGroup);
// Commit to disk
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun);
save.SetStatusLogger(StatusLogger);
save.Run();
}
@@ -315,26 +327,28 @@ namespace keepass2android
}
PwGroup templateGroup;
if (!_app.GetDb().Groups.TryGetValue(_app.GetDb().KpDatabase.EntryTemplatesGroup, out templateGroup))
if (!_app.CurrentDb.GroupsById.TryGetValue(_app.CurrentDb.KpDatabase.EntryTemplatesGroup, out templateGroup))
{
//create template group
templateGroup = new PwGroup(true, true, _app.GetResourceString(UiStringKey.TemplateGroupName), PwIcon.Folder);
_app.GetDb().KpDatabase.RootGroup.AddGroup(templateGroup, true);
_app.GetDb().KpDatabase.EntryTemplatesGroup = templateGroup.Uuid;
_app.GetDb().KpDatabase.EntryTemplatesGroupChanged = DateTime.Now;
_app.GetDb().Dirty.Add(_app.GetDb().KpDatabase.RootGroup);
_app.GetDb().Groups[templateGroup.Uuid] = templateGroup;
_app.CurrentDb.KpDatabase.RootGroup.AddGroup(templateGroup, true);
_app.CurrentDb.KpDatabase.EntryTemplatesGroup = templateGroup.Uuid;
_app.CurrentDb.KpDatabase.EntryTemplatesGroupChanged = DateTime.Now;
_app.DirtyGroups.Add(_app.CurrentDb.KpDatabase.RootGroup);
_app.CurrentDb.GroupsById[templateGroup.Uuid] = templateGroup;
_app.CurrentDb.Elements.Add(templateGroup);
}
addedEntries = new List<PwEntry>();
foreach (var template in TemplateEntries)
{
if (_app.GetDb().Entries.ContainsKey(template.Uuid))
if (_app.CurrentDb.EntriesById.ContainsKey(template.Uuid))
continue;
PwEntry entry = CreateEntry(template);
templateGroup.AddEntry(entry, true);
addedEntries.Add(entry);
_app.GetDb().Entries[entry.Uuid] = entry;
_app.CurrentDb.EntriesById[entry.Uuid] = entry;
}
return templateGroup;
}
@@ -373,8 +387,12 @@ namespace keepass2android
base.Run();
}
}
public static bool IsTemplateId(PwUuid pwUuid)
{
return TemplateEntries.Any(te => te.Uuid.Equals(pwUuid));
}
}
}

View File

@@ -27,23 +27,22 @@ namespace keepass2android
{
public class CreateDb : RunnableOnFinish {
private const ulong DefaultEncryptionRounds = PwDefs.DefaultKeyEncryptionRounds;
private readonly IOConnectionInfo _ioc;
private readonly IOConnectionInfo _ioc;
private readonly bool _dontSave;
private readonly Activity _ctx;
private readonly IKp2aApp _app;
private CompositeKey _key;
private readonly bool _makeCurrent;
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(ctx, finish) {
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave, bool makeCurrent): base(ctx, finish) {
_ctx = ctx;
_ioc = ioc;
_dontSave = dontSave;
_app = app;
_makeCurrent = makeCurrent;
_app = app;
}
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave, CompositeKey key)
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave, CompositeKey key, bool makeCurrent)
: base(ctx, finish)
{
_ctx = ctx;
@@ -51,12 +50,13 @@ namespace keepass2android
_dontSave = dontSave;
_app = app;
_key = key;
_makeCurrent = makeCurrent;
}
public override void Run() {
StatusLogger.UpdateMessage(UiStringKey.progress_create);
Database db = _app.CreateNewDatabase();
Database db = _app.CreateNewDatabase(_makeCurrent);
db.KpDatabase = new KeePassLib.PwDatabase();
@@ -74,7 +74,6 @@ namespace keepass2android
// Set Database state
db.Root = db.KpDatabase.RootGroup;
db.Loaded = true;
db.SearchHelper = new SearchDbHelper(_app);
// Add a couple default groups
@@ -88,12 +87,14 @@ namespace keepass2android
addTemplates.AddTemplates(out addedEntries);
// Commit changes
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, _dontSave);
SaveDb save = new SaveDb(_ctx, _app, db, OnFinishToRun, _dontSave);
save.SetStatusLogger(StatusLogger);
_onFinishToRun = null;
save.Run();
db.UpdateGlobals();
}
}

View File

@@ -31,7 +31,7 @@ namespace keepass2android
public DeleteEntry(Activity activiy, IKp2aApp app, PwEntry entry, OnFinish finish):base(activiy, finish, app) {
Ctx = activiy;
Db = app.GetDb();
Db = app.FindDatabaseForElement(entry);
_entry = entry;
}
@@ -40,7 +40,7 @@ namespace keepass2android
{
get
{
return App.GetDb().DatabaseFormat.CanRecycle && CanRecycleGroup(_entry.ParentGroup);
return Db.DatabaseFormat.CanRecycle && CanRecycleGroup(_entry.ParentGroup);
}
}

View File

@@ -47,7 +47,7 @@ namespace keepass2android
*/
private void SetMembers(Activity activity, IKp2aApp app, PwGroup group, bool dontSave)
{
base.SetMembers(activity, app.GetDb());
base.SetMembers(activity, app.FindDatabaseForElement(group));
_group = group;
DontSave = dontSave;
@@ -58,7 +58,7 @@ namespace keepass2android
{
get
{
return App.GetDb().DatabaseFormat.CanRecycle && CanRecycleGroup(_group);
return Db.DatabaseFormat.CanRecycle && CanRecycleGroup(_group);
}
}

View File

@@ -7,12 +7,12 @@ using KeePassLib.Interfaces;
namespace keepass2android
{
public class DeleteMultipleItems : DeleteRunnable
public class DeleteMultipleItemsFromOneDatabase : DeleteRunnable
{
private readonly List<IStructureItem> _elementsToDelete;
private readonly bool _canRecycle;
public DeleteMultipleItems(Activity activity, Database db, List<IStructureItem> elementsToDelete, OnFinish finish, IKp2aApp app)
public DeleteMultipleItemsFromOneDatabase(Activity activity, Database db, List<IStructureItem> elementsToDelete, OnFinish finish, IKp2aApp app)
: base(activity, finish, app)
{
_elementsToDelete = elementsToDelete;
@@ -21,12 +21,13 @@ namespace keepass2android
//determine once. The property is queried for each delete operation, but might return false
//after one entry/group is deleted (and thus in recycle bin and thus can't be recycled anymore)
_canRecycle = DetermineCanRecycle();
ShowDatabaseIocInStatus = true;
}
private bool DetermineCanRecycle()
{
Android.Util.Log.Debug("KP2A", "CanRecycle?");
if (!App.GetDb().DatabaseFormat.CanRecycle)
if (!Db.DatabaseFormat.CanRecycle)
{
Android.Util.Log.Debug("KP2A", "CanRecycle? No because of DB format.");
return false;

View File

@@ -100,7 +100,8 @@ namespace keepass2android
};
Db.KpDatabase.RootGroup.AddGroup(pgRecycleBin, true);
Db.Groups[pgRecycleBin.Uuid] = pgRecycleBin;
Db.GroupsById[pgRecycleBin.Uuid] = pgRecycleBin;
Db.Elements.Add(pgRecycleBin);
Db.KpDatabase.RecycleBinUuid = pgRecycleBin.Uuid;
bGroupListUpdateRequired = true;
@@ -121,24 +122,27 @@ namespace keepass2android
public void Start()
{
if (CanRecycle)
string messageSuffix = ShowDatabaseIocInStatus ? "(" + App.GetFileStorage(Db.Ioc).GetDisplayName(Db.Ioc) + ")" : "";
if (CanRecycle)
{
App.AskYesNoCancel(UiStringKey.AskDeletePermanently_title,
QuestionRecycleResourceId,
(dlgSender, dlgEvt) =>
{
DeletePermanently = true;
ProgressTask pt = new ProgressTask(App, Ctx, this);
pt.Run();
DeletePermanently = true;
ProgressTask pt = new ProgressTask(App, Ctx, this);
pt.Run();
},
(dlgSender, dlgEvt) =>
{
DeletePermanently = false;
ProgressTask pt = new ProgressTask(App, Ctx, this);
pt.Run();
DeletePermanently = false;
ProgressTask pt = new ProgressTask(App, Ctx, this);
pt.Run();
},
(dlgSender, dlgEvt) => { },
Ctx);
Ctx, messageSuffix);
@@ -149,12 +153,12 @@ namespace keepass2android
QuestionNoRecycleResourceId,
(dlgSender, dlgEvt) =>
{
ProgressTask pt = new ProgressTask(App, Ctx, this);
pt.Run();
ProgressTask pt = new ProgressTask(App, Ctx, this);
pt.Run();
},
null,
(dlgSender, dlgEvt) => { },
Ctx);
Ctx, messageSuffix);
}
@@ -182,7 +186,8 @@ namespace keepass2android
PwDeletedObject pdo = new PwDeletedObject(pe.Uuid, dtNow);
pd.DeletedObjects.Add(pdo);
touchedGroups.Add(pgParent);
Db.Entries.Remove(pe.Uuid);
Db.EntriesById.Remove(pe.Uuid);
Db.Elements.Remove(pe);
}
else // Recycle
{
@@ -215,31 +220,41 @@ namespace keepass2android
if (success)
{
foreach (var g in touchedGroups)
Db.Dirty.Add(g);
App.DirtyGroups.Add(g);
foreach (var g in permanentlyDeletedGroups)
{
//remove groups from global lists if present there
Db.Dirty.Remove(g);
Db.Groups.Remove(g.Uuid);
//remove groups from global lists if present there
App.DirtyGroups.Remove(g);
Db.GroupsById.Remove(g.Uuid);
Db.Elements.Remove(g);
}
}
else
{
// Let's not bother recovering from a failure to save. It is too much work.
App.LockDatabase(false);
App.Lock(false);
}
}, OnFinishToRun);
// Commit database
SaveDb save = new SaveDb(Ctx, App, OnFinishToRun, false);
save.SetStatusLogger(StatusLogger);
SaveDb save = new SaveDb(Ctx, App, Db, OnFinishToRun, false);
save.ShowDatabaseIocInStatus = ShowDatabaseIocInStatus;
save.SetStatusLogger(StatusLogger);
save.Run();
}
protected abstract void PerformDelete(List<PwGroup> touchedGroups, List<PwGroup> permanentlyDeletedGroups);
public bool ShowDatabaseIocInStatus
{
get;
set;
}
protected abstract void PerformDelete(List<PwGroup> touchedGroups, List<PwGroup> permanentlyDeletedGroups);
public abstract UiStringKey StatusMessage { get; }

View File

@@ -26,9 +26,12 @@ namespace keepass2android
public class EditGroup : RunnableOnFinish {
internal Database Db
{
get { return _app.GetDb(); }
get { return _app.FindDatabaseForElement(Group); }
}
private IKp2aApp _app;
public IKp2aApp App { get => _app; }
private IKp2aApp _app;
private readonly String _name;
private readonly PwIcon _iconId;
private readonly PwUuid _customIconId;
@@ -57,7 +60,7 @@ namespace keepass2android
Group.Touch(true);
// Commit to disk
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
SaveDb save = new SaveDb(_ctx, _app, Db, OnFinishToRun);
save.SetStatusLogger(StatusLogger);
save.Run();
}
@@ -76,10 +79,10 @@ namespace keepass2android
if ( Success ) {
// Mark parent group dirty
_editGroup.Db.Dirty.Add(_editGroup.Group.ParentGroup);
_editGroup.App.DirtyGroups.Add(_editGroup.Group.ParentGroup);
} else
{
_editGroup._app.LockDatabase(false);
_editGroup._app.Lock(false);
}
base.Run();

View File

@@ -21,6 +21,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Android.App;
using keepass2android.database.edit;
using KeePassLib;
using KeePassLib.Keys;
using KeePassLib.Serialization;
@@ -36,20 +37,25 @@ namespace keepass2android
private readonly bool _rememberKeyfile;
IDatabaseFormat _format;
public LoadDb(Activity activity, IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, String keyfileOrProvider, OnFinish finish): base(activity, finish)
public LoadDb(Activity activity, IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, String keyfileOrProvider, OnFinish finish, bool updateLastUsageTimestamp, bool makeCurrent): base(activity, finish)
{
_app = app;
_ioc = ioc;
_databaseData = databaseData;
_compositeKey = compositeKey;
_keyfileOrProvider = keyfileOrProvider;
_updateLastUsageTimestamp = updateLastUsageTimestamp;
_makeCurrent = makeCurrent;
_rememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
_rememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
}
public override void Run()
protected bool success = false;
private bool _updateLastUsageTimestamp;
private readonly bool _makeCurrent;
public override void Run()
{
try
{
@@ -78,6 +84,10 @@ namespace keepass2android
//ok, try to load the database. Let's start with Kdbx format and retry later if that is the wrong guess:
_format = new KdbxDatabaseFormat(KdbpFile.GetFormatToUse(_ioc));
TryLoad(databaseStream);
success = true;
}
catch (Exception e)
{
@@ -89,7 +99,7 @@ namespace keepass2android
{
Kp2aLog.Log("KeyFileException");
Finish(false, /*TODO Localize: use Keepass error text KPRes.KeyFileError (including "or invalid format")*/
_app.GetResourceString(UiStringKey.keyfile_does_not_exist), Exception);
_app.GetResourceString(UiStringKey.keyfile_does_not_exist), false, Exception);
}
catch (AggregateException e)
{
@@ -100,20 +110,20 @@ namespace keepass2android
// Override the message shown with the last (hopefully most recent) inner exception
Kp2aLog.LogUnexpectedError(innerException);
}
Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + message, Exception);
Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + message, false, Exception);
return;
}
catch (DuplicateUuidsException e)
{
Kp2aLog.Log(e.ToString());
Finish(false, _app.GetResourceString(UiStringKey.DuplicateUuidsError) + " " + e.Message + _app.GetResourceString(UiStringKey.DuplicateUuidsErrorAdditional), Exception);
Finish(false, _app.GetResourceString(UiStringKey.DuplicateUuidsError) + " " + e.Message + _app.GetResourceString(UiStringKey.DuplicateUuidsErrorAdditional), false, Exception);
return;
}
catch (Exception e)
{
if (!(e is InvalidCompositeKeyException))
Kp2aLog.LogUnexpectedError(e);
Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, Exception);
Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, false, Exception);
return;
}
@@ -125,7 +135,7 @@ namespace keepass2android
/// </summary>
public Exception Exception { get; set; }
private void TryLoad(MemoryStream databaseStream)
Database TryLoad(MemoryStream databaseStream)
{
//create a copy of the stream so we can try again if we get an exception which indicates we should change parameters
//This is not optimal in terms of (short-time) memory usage but is hard to avoid because the Keepass library closes streams also in case of errors.
@@ -138,19 +148,16 @@ namespace keepass2android
//now let's go:
try
{
_app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, _format);
Database newDb = _app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, _format, _makeCurrent);
Kp2aLog.Log("LoadDB OK");
//make sure the stored access time for the actual file is more recent than that of its backup
Thread.Sleep(10);
SaveFileData(_ioc, _keyfileOrProvider);
Finish(true, _format.SuccessMessage);
return newDb;
}
catch (OldFormatException)
{
_format = new KdbDatabaseFormat(_app);
TryLoad(databaseStream);
return TryLoad(databaseStream);
}
catch (InvalidCompositeKeyException)
{
@@ -162,7 +169,7 @@ namespace keepass2android
//retry without password:
_compositeKey.RemoveUserKey(passwordKey);
//retry:
TryLoad(databaseStream);
return TryLoad(databaseStream);
}
else throw;
}
@@ -175,7 +182,7 @@ namespace keepass2android
{
keyfileOrProvider = "";
}
_app.StoreOpenedFileAsRecent(ioc, keyfileOrProvider);
_app.StoreOpenedFileAsRecent(ioc, keyfileOrProvider, _updateLastUsageTimestamp);
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Android.App;
@@ -50,10 +51,19 @@ namespace keepass2android.database.edit
}
HashSet<Database> removeDatabases = new HashSet<Database>();
Database addDatabase = _app.FindDatabaseForElement(_targetGroup);
if (addDatabase == null)
{
Finish(false, "Did not find target database. Did you lock it?");
return;
}
foreach (var elementToMove in _elementsToMove)
{
_app.GetDb().Dirty.Add(elementToMove.ParentGroup);
_app.DirtyGroups.Add(elementToMove.ParentGroup);
PwGroup pgParent = elementToMove.ParentGroup;
if (pgParent != _targetGroup)
@@ -63,8 +73,14 @@ namespace keepass2android.database.edit
PwEntry entry = elementToMove as PwEntry;
if (entry != null)
{
var dbRem = _app.FindDatabaseForElement(entry);
removeDatabases.Add(dbRem);
dbRem.EntriesById.Remove(entry.Uuid);
dbRem.Elements.Remove(entry);
pgParent.Entries.Remove(entry);
_targetGroup.AddEntry(entry, true, true);
addDatabase.EntriesById.Add(entry.Uuid, entry);
addDatabase.Elements.Add(entry);
}
else
{
@@ -74,27 +90,60 @@ namespace keepass2android.database.edit
Finish(false, _app.GetResourceString(UiStringKey.CannotMoveGroupHere));
return;
}
var dbRem = _app.FindDatabaseForElement(@group);
if (dbRem == null)
{
Finish(false, "Did not find source database. Did you lock it?");
return;
}
dbRem.GroupsById.Remove(group.Uuid);
dbRem.Elements.Remove(group);
removeDatabases.Add(dbRem);
pgParent.Groups.Remove(group);
_targetGroup.AddGroup(group, true, true);
addDatabase.GroupsById.Add(group.Uuid, group);
addDatabase.Elements.Add(group);
}
}
}
}
_onFinishToRun = new ActionOnFinish(ActiveActivity, (success, message, activity) =>
{
if (!success)
{ // Let's not bother recovering from a failure.
_app.LockDatabase(false);
}
}, OnFinishToRun);
// Save
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, false);
save.SetStatusLogger(StatusLogger);
save.Run();
//first save the database where we added the elements
var allDatabasesToSave = new List<Database> {addDatabase};
//then all databases where we removed elements:
removeDatabases.RemoveWhere(db => db == addDatabase);
allDatabasesToSave.AddRange(removeDatabases);
int indexToSave = 0;
bool allSavesSuccess = true;
void ContinueSave(bool success, string message, Activity activeActivity)
{
allSavesSuccess &= success;
indexToSave++;
if (indexToSave == allDatabasesToSave.Count)
{
OnFinishToRun.SetResult(allSavesSuccess);
OnFinishToRun.Run();
return;
}
SaveDb saveDb = new SaveDb(_ctx, _app, allDatabasesToSave[indexToSave], new ActionOnFinish(activeActivity, ContinueSave), false);
saveDb.SetStatusLogger(StatusLogger);
saveDb.ShowDatabaseIocInStatus = allDatabasesToSave.Count > 1;
saveDb.Run();
}
SaveDb save = new SaveDb(_ctx, _app, allDatabasesToSave[0], new ActionOnFinish(ActiveActivity, ContinueSave), false);
save.SetStatusLogger(StatusLogger);
save.ShowDatabaseIocInStatus = allDatabasesToSave.Count > 1;
save.Run();
}
}
}

View File

@@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System;
using Android;
using Android.App;
using Android.Content;
using Android.OS;
@@ -28,8 +29,14 @@ namespace keepass2android
protected bool Success;
protected String Message;
protected Exception Exception;
protected OnFinish BaseOnFinish;
protected bool ImportantMessage
{
get;
set;
}
protected OnFinish BaseOnFinish;
protected Handler Handler;
private ProgressDialogStatusLogger _statusLogger = new ProgressDialogStatusLogger(); //default: no logging but not null -> can be used whenever desired
private Activity _activeActivity;
@@ -77,20 +84,22 @@ namespace keepass2android
Handler = null;
}
public void SetResult(bool success, string message, Exception exception) {
public void SetResult(bool success, string message, bool importantMessage, Exception exception) {
Success = success;
Message = message;
ImportantMessage = importantMessage;
Exception = exception;
}
public void SetResult(bool success) {
public void SetResult(bool success) {
Success = success;
}
public virtual void Run() {
if (BaseOnFinish == null) return;
// Pass on result on call finish
BaseOnFinish.SetResult(Success, Message, Exception);
BaseOnFinish.SetResult(Success, Message, ImportantMessage, Exception);
if ( Handler != null ) {
Handler.Post(BaseOnFinish.Run);
@@ -100,14 +109,31 @@ namespace keepass2android
}
protected void DisplayMessage(Context ctx) {
DisplayMessage(ctx, Message);
DisplayMessage(ctx, Message, ImportantMessage);
}
public static void DisplayMessage(Context ctx, string message)
public static void DisplayMessage(Context ctx, string message, bool makeDialog)
{
if ( !String.IsNullOrEmpty(message) ) {
Kp2aLog.Log("OnFinish message: "+message);
Toast.MakeText(ctx ?? Application.Context, message, ToastLength.Long).Show();
Kp2aLog.Log("OnFinish message: " + message);
if (makeDialog && ctx != null)
{
try
{
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.SetMessage(message)
.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => ((Dialog)sender).Dismiss())
.Show();
}
catch (Exception)
{
Toast.MakeText(ctx, message, ToastLength.Long).Show();
}
}
else
Toast.MakeText(ctx ?? Application.Context, message, ToastLength.Long).Show();
}
}
}

View File

@@ -50,9 +50,9 @@ namespace keepass2android
}
}
protected void Finish(bool result, String message, Exception exception = null) {
protected void Finish(bool result, String message, bool importantMessage = false, Exception exception = null) {
if ( OnFinishToRun != null ) {
OnFinishToRun.SetResult(result, message, exception);
OnFinishToRun.SetResult(result, message, importantMessage, exception);
OnFinishToRun.Run();
}
}

View File

@@ -34,7 +34,8 @@ namespace keepass2android
public class SaveDb : RunnableOnFinish {
private readonly IKp2aApp _app;
private readonly bool _dontSave;
private readonly Database _db;
private readonly bool _dontSave;
/// <summary>
/// stream for reading the data from the original file. If this is set to a non-null value, we know we need to sync
@@ -43,9 +44,10 @@ namespace keepass2android
private readonly Context _ctx;
private Thread _workerThread;
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish, bool dontSave)
public SaveDb(Activity ctx, IKp2aApp app, Database db, OnFinish finish, bool dontSave)
: base(ctx, finish)
{
_db = db;
_ctx = ctx;
_app = app;
_dontSave = dontSave;
@@ -59,46 +61,55 @@ namespace keepass2android
/// <param name="finish"></param>
/// <param name="dontSave"></param>
/// <param name="streamForOrigFile">Stream for reading the data from the (changed) original location</param>
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish, bool dontSave, Stream streamForOrigFile)
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish, Database db, bool dontSave, Stream streamForOrigFile)
: base(ctx, finish)
{
_db = db;
_ctx = ctx;
_app = app;
_dontSave = dontSave;
_streamForOrigFile = streamForOrigFile;
}
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish)
public SaveDb(Activity ctx, IKp2aApp app, Database db, OnFinish finish)
: base(ctx, finish)
{
_ctx = ctx;
_app = app;
_dontSave = false;
_db = db;
_dontSave = false;
}
public override void Run ()
public bool ShowDatabaseIocInStatus { get; set; }
public override void Run ()
{
if (!_dontSave)
{
try
{
if (_app.GetDb().CanWrite == false)
if (_db.CanWrite == false)
{
//this should only happen if there is a problem in the UI so that the user sees an edit interface.
Finish(false,"Cannot save changes. File is read-only!");
return;
}
StatusLogger.UpdateMessage(UiStringKey.saving_database);
IOConnectionInfo ioc = _app.GetDb().Ioc;
string message = _app.GetResourceString(UiStringKey.saving_database);
if (ShowDatabaseIocInStatus)
message += " (" + _app.GetFileStorage(_db.Ioc).GetDisplayName(_db.Ioc) + ")";
StatusLogger.UpdateMessage(message);
IOConnectionInfo ioc = _db.Ioc;
IFileStorage fileStorage = _app.GetFileStorage(ioc);
if (_streamForOrigFile == null)
{
if ((!_app.GetBooleanPreference(PreferenceKey.CheckForFileChangesOnSave))
|| (_app.GetDb().KpDatabase.HashOfFileOnDisk == null)) //first time saving
|| (_db.KpDatabase.HashOfFileOnDisk == null)) //first time saving
{
PerformSaveWithoutCheck(fileStorage, ioc);
Finish(true);
@@ -109,8 +120,8 @@ namespace keepass2android
if (
(_streamForOrigFile != null)
|| fileStorage.CheckForFileChangeFast(ioc, _app.GetDb().LastFileVersion) //first try to use the fast change detection
|| (FileHashChanged(ioc, _app.GetDb().KpDatabase.HashOfFileOnDisk) == FileHashChange.Changed) //if that fails, hash the file and compare:
|| fileStorage.CheckForFileChangeFast(ioc, _db.LastFileVersion) //first try to use the fast change detection
|| (FileHashChanged(ioc, _db.KpDatabase.HashOfFileOnDisk) == FileHashChange.Changed) //if that fails, hash the file and compare:
)
{
@@ -128,6 +139,7 @@ namespace keepass2android
//small.
MergeIn(fileStorage, ioc);
PerformSaveWithoutCheck(fileStorage, ioc);
_db.UpdateGlobals();
Finish(true);
};
RunInWorkerThread(runHandler);
@@ -217,13 +229,13 @@ namespace keepass2android
StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.SynchronizingDatabase));
PwDatabase pwImp = new PwDatabase();
PwDatabase pwDatabase = _app.GetDb().KpDatabase;
PwDatabase pwDatabase = _db.KpDatabase;
pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey);
pwImp.MemoryProtection = pwDatabase.MemoryProtection.CloneDeep();
pwImp.MasterKey = pwDatabase.MasterKey;
var stream = GetStreamForBaseFile(fileStorage, ioc);
_app.GetDb().DatabaseFormat.PopulateDatabaseFromStream(pwImp, stream, null);
_db.DatabaseFormat.PopulateDatabaseFromStream(pwImp, stream, null);
pwDatabase.MergeIn(pwImp, PwMergeMethod.Synchronize, null);
@@ -249,8 +261,8 @@ namespace keepass2android
private void PerformSaveWithoutCheck(IFileStorage fileStorage, IOConnectionInfo ioc)
{
StatusLogger.UpdateSubMessage("");
_app.GetDb().SaveData();
_app.GetDb().LastFileVersion = fileStorage.GetCurrentFileVersionFast(ioc);
_db.SaveData();
_db.LastFileVersion = fileStorage.GetCurrentFileVersionFast(ioc);
}
public byte[] HashOriginalFile(IOConnectionInfo iocFile)

View File

@@ -52,7 +52,7 @@ namespace keepass2android
public override void Run ()
{
StatusLogger.UpdateMessage(UiStringKey.SettingPassword);
PwDatabase pm = _app.GetDb().KpDatabase;
PwDatabase pm = _app.CurrentDb.KpDatabase;
CompositeKey newKey = new CompositeKey ();
if (String.IsNullOrEmpty (_password) == false) {
newKey.AddUserKey (new KcpPassword (_password));
@@ -74,7 +74,7 @@ namespace keepass2android
// Save Database
_onFinishToRun = new AfterSave(ActiveActivity, previousKey, previousMasterKeyChanged, pm, OnFinishToRun);
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, _dontSave);
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun, _dontSave);
save.SetStatusLogger(StatusLogger);
save.Run();
}

View File

@@ -36,7 +36,7 @@ namespace keepass2android
public override void Run() {
// Commit to disk
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun);
save.SetStatusLogger(StatusLogger);
save.Run();
}
@@ -59,7 +59,7 @@ namespace keepass2android
if ( parent != null ) {
// Mark parent group dirty
_app.GetDb().Dirty.Add(parent);
_app.DirtyGroups.Add(parent);
}

View File

@@ -67,5 +67,4 @@
<ItemGroup>
<Folder Include="libs\" />
</ItemGroup>
</Project>
</Project>

Binary file not shown.

Binary file not shown.

View File

@@ -67,7 +67,7 @@
<None Include="Jars\AboutJars.txt" />
<None Include="Additions\AboutAdditions.txt" />
<LibraryProjectZip Include="Jars\pcloud-sdk-android-1.0.1.aar" />
<LibraryProjectZip Include="Jars\pcloud-sdk-android-1.1.0.aar" />
</ItemGroup>
<ItemGroup>
<TransformFile Include="Transforms\Metadata.xml" />
@@ -84,7 +84,7 @@
</Target>
-->
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\pcloud-sdk-java-core-1.0.1.jar" />
<EmbeddedReferenceJar Include="Jars\pcloud-sdk-java-core-1.1.0.jar" />
</ItemGroup>
</Project>

View File

@@ -26,5 +26,5 @@ using Android.App;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]

View File

@@ -53,8 +53,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<LibraryProjectZip Include="..\java\Keepass2AndroidPluginSDK2\app\build\outputs\aar\app-release.aar">
<Link>Jars\app-release.aar</Link>
<LibraryProjectZip Include="..\java\Keepass2AndroidPluginSDK2\app\build\outputs\aar\Keepass2AndroidPluginSDK2-release.aar">
<Link>Jars\Keepass2AndroidPluginSDK2-release.aar</Link>
</LibraryProjectZip>
<None Include="Jars\AboutJars.txt" />
<None Include="Additions\AboutAdditions.txt" />

View File

@@ -7,4 +7,7 @@ call gradlew assemble
cd ..\Keepass2AndroidPluginSDK2
call gradlew assemble
cd ..\..\build-scripts
cd ..\PluginQR
call gradlew assemble
cd ..\..\build-scripts

View File

@@ -15,4 +15,8 @@ pushd Keepass2AndroidPluginSDK2
./gradlew assemble
popd
pushd PluginQR
./gradlew assemble
popd
popd

View File

@@ -35,8 +35,12 @@ dependencies {
compile('com.onedrive.sdk:onedrive-sdk-android:1.2.0') {
transitive = false
}
compile 'com.pcloud.sdk:java-core:1.0.1'
compile 'com.pcloud.sdk:android:1.0.1'
compile 'com.pcloud.sdk:java-core:1.1.0'
compile 'com.pcloud.sdk:android:1.1.0'
compile('com.microsoft.graph:msgraph-sdk-android:1.2.+')
compile ('com.microsoft.identity.client:msal:0.1.+') {
exclude group: 'com.android.support', module: 'appcompat-v7'
}
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.microsoft.services.msa:msa-auth:0.8.6'
compile 'com.microsoft.aad:adal:1.14.0'

View File

@@ -0,0 +1,486 @@
package keepass2android.javafilestorage;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.microsoft.graph.core.ClientException;
import com.microsoft.graph.core.DefaultClientConfig;
import com.microsoft.graph.core.GraphErrorCodes;
import com.microsoft.graph.extensions.DriveItem;
import com.microsoft.graph.extensions.GraphServiceClient;
import com.microsoft.graph.extensions.IDriveItemCollectionPage;
import com.microsoft.graph.extensions.IDriveItemCollectionRequestBuilder;
import com.microsoft.graph.extensions.IDriveItemRequest;
import com.microsoft.graph.extensions.IDriveItemRequestBuilder;
import com.microsoft.graph.extensions.IGraphServiceClient;
import com.microsoft.identity.client.AuthenticationCallback;
import com.microsoft.identity.client.AuthenticationResult;
import com.microsoft.identity.client.MsalException;
import com.microsoft.identity.client.PublicClientApplication;
import com.microsoft.identity.client.User;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import keepass2android.javafilestorage.onedrive2.GraphServiceClientManager;
/**
* Created by Philipp on 20.11.2016.
*/
public class OneDriveStorage2 extends JavaFileStorageBase
{
PublicClientApplication mPublicClientApp;
final HashMap<String /*userid*/, IGraphServiceClient> mClientByUser = new HashMap<String /*userid*/, IGraphServiceClient>();
private static final String[] scopes = {"openid","offline_access", "https://graph.microsoft.com/Files.ReadWrite","https://graph.microsoft.com/User.Read"};
public OneDriveStorage2(final Activity context, final String clientId) {
mPublicClientApp = new PublicClientApplication(context, clientId);
initAuthenticator(context);
}
@Override
public boolean requiresSetup(String path)
{
return !isConnected(null);
}
@Override
public void startSelectFile(FileStorageSetupInitiatorActivity activity, boolean isForSave, int requestCode) {
initAuthenticator((Activity)activity.getActivity());
String path = getProtocolId()+":///";
Log.d("KP2AJ", "startSelectFile "+path+", connected: "+path);
if (isConnected(null))
{
Intent intent = new Intent();
intent.putExtra(EXTRA_IS_FOR_SAVE, isForSave);
intent.putExtra(EXTRA_PATH, path);
activity.onImmediateResult(requestCode, RESULT_FILECHOOSER_PREPARED, intent);
}
else
{
activity.startSelectFileProcess(path, isForSave, requestCode);
}
}
private boolean isConnected(String path) {
try {
if (tryGetMsGraphClient(path) == null)
try {
final CountDownLatch latch = new CountDownLatch(1);
Log.d("KP2AJ", "trying silent login");
String userId = extractUserId(path);
final MsalException[] _exception = {null};
final AuthenticationResult[] _result = {null};
User user = mPublicClientApp.getUser(userId);
mPublicClientApp.acquireTokenSilentAsync(scopes, user,
new AuthenticationCallback() {
@Override
public void onSuccess(AuthenticationResult authenticationResult) {
_result[0] = authenticationResult;
latch.countDown();
}
@Override
public void onError(MsalException exception) {
_exception[0] = exception;
latch.countDown();
}
@Override
public void onCancel() {
latch.countDown();
}
});
latch.await();
if (_result[0] != null) {
buildClient(_result[0]);
} else if (_exception[0] != null){
_exception[0].printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return tryGetMsGraphClient(path) != null;
}
catch (Exception e)
{
return false;
}
}
private IGraphServiceClient tryGetMsGraphClient(String path) throws Exception
{
String userId = extractUserId(path);
if (mClientByUser.containsKey(userId))
return mClientByUser.get(userId);
return null;
}
private String extractUserId(String path) throws Exception {
String pathWithoutProtocol = removeProtocol(path);
String[] parts = pathWithoutProtocol.split("/",1);
if (parts.length != 2 || ("".equals(parts[0])))
{
throw new Exception("path does not contain user");
}
return parts[0];
}
private void initAuthenticator(Activity activity) {
}
@Override
public void prepareFileUsage(FileStorageSetupInitiatorActivity activity, String path, int requestCode, boolean alwaysReturnSuccess) {
initAuthenticator((Activity)activity.getActivity());
if (isConnected(path))
{
Intent intent = new Intent();
intent.putExtra(EXTRA_PATH, path);
activity.onImmediateResult(requestCode, RESULT_FILEUSAGE_PREPARED, intent);
}
else
{
activity.startFileUsageProcess(path, requestCode, alwaysReturnSuccess);
}
}
@Override
public String getProtocolId() {
return "onedrive";
}
@Override
public void prepareFileUsage(Context appContext, String path) throws UserInteractionRequiredException {
if (!isConnected(null))
{
throw new UserInteractionRequiredException();
}
}
@Override
public void onCreate(FileStorageSetupActivity activity, Bundle savedInstanceState) {
Log.d("KP2AJ", "OnCreate");
}
@Override
public void onResume(final FileStorageSetupActivity activity) {
}
private IGraphServiceClient buildClient(AuthenticationResult authenticationResult) throws InterruptedException {
IGraphServiceClient newClient = new GraphServiceClient.Builder()
.fromConfig(DefaultClientConfig.createWithAuthenticationProvider(new GraphServiceClientManager(authenticationResult.getAccessToken())))
.buildClient();
mClientByUser.put(authenticationResult.getUser().getUserIdentifier(), newClient);
return newClient;
}
String removeProtocol(String path) throws Exception {
if (path == null)
return null;
return path.substring(getProtocolId().length()+3);
}
@Override
public String getDisplayName(String path) {
if (path == null)
return null;
return path;
}
@Override
public String getFilename(String path) throws Exception {
return path.substring(path.lastIndexOf("/")+1);
}
@Override
public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception {
return false;
}
@Override
public String getCurrentFileVersionFast(String path) {
return null;
}
class ClientAndPath
{
public IGraphServiceClient client;
public String oneDrivePath;
public IDriveItemRequestBuilder getPathItem()
{
IDriveItemRequestBuilder pathItem = client.getDrive().getRoot();
if ("".equals(oneDrivePath) == false) {
pathItem = pathItem.getItemWithPath(oneDrivePath);
}
return pathItem;
}
}
@Override
public InputStream openFileForRead(String path) throws Exception {
try {
ClientAndPath clientAndpath = getOneDriveClientAndPath(path);
logDebug("openFileForRead. Path="+path);
InputStream result = clientAndpath.client.getDrive()
.getRoot()
.getItemWithPath(clientAndpath.oneDrivePath)
.getContent()
.buildRequest()
.get();
logDebug("ok");
return result;
}
catch (ClientException e)
{
throw convertException(e);
}
}
private ClientAndPath getOneDriveClientAndPath(String path) throws Exception {
ClientAndPath result = new ClientAndPath();
String pathWithoutProtocol = removeProtocol(path);
String[] parts = pathWithoutProtocol.split("/",2);
if (parts.length != 2 || ("".equals(parts[0])))
{
throw new Exception("path does not contain user");
}
result.client = mClientByUser.get(parts[0]);
result.oneDrivePath = parts[1];
return result;
}
private Exception convertException(ClientException e) {
if (e.isError(GraphErrorCodes.ItemNotFound))
return new FileNotFoundException(e.getMessage());
return e;
}
@Override
public void uploadFile(String path, byte[] data, boolean writeTransactional) throws Exception {
try {
ClientAndPath clientAndPath = getOneDriveClientAndPath(path);
clientAndPath.client.getDrive()
.getRoot()
.getItemWithPath(clientAndPath.oneDrivePath)
.getContent()
.buildRequest()
.put(data);
} catch (ClientException e) {
throw convertException(e);
}
}
@Override
public String createFolder(String parentPath, String newDirName) throws Exception {
throw new Exception("not implemented.");
}
@Override
public String createFilePath(String parentPath, String newFileName) throws Exception {
String path = parentPath;
if (!path.endsWith("/"))
path = path + "/";
path = path + newFileName;
return path;
}
@Override
public List<FileEntry> listFiles(String parentPath) throws Exception {
try {
ArrayList<FileEntry> result = new ArrayList<FileEntry>();
ClientAndPath clientAndPath = getOneDriveClientAndPath(parentPath);
parentPath = clientAndPath.oneDrivePath;
IDriveItemCollectionPage itemsPage = clientAndPath.getPathItem()
.getChildren()
.buildRequest()
.get();
if (parentPath.endsWith("/"))
parentPath = parentPath.substring(0,parentPath.length()-1);
while (true)
{
List<DriveItem> items = itemsPage.getCurrentPage();
if (items.isEmpty())
return result;
for (DriveItem i: items)
{
FileEntry e = getFileEntry(parentPath + "/" + i.name, i);
Log.d("KP2AJ", e.path);
result.add(e);
}
IDriveItemCollectionRequestBuilder nextPageReqBuilder = itemsPage.getNextPage();
if (nextPageReqBuilder == null)
return result;
itemsPage = nextPageReqBuilder.buildRequest().get();
}
} catch (ClientException e) {
throw convertException(e);
}
}
private FileEntry getFileEntry(String path, DriveItem i) {
FileEntry e = new FileEntry();
if (i.size != null)
e.sizeInBytes = i.size;
else if ((i.remoteItem != null) && (i.remoteItem.size != null))
e.sizeInBytes = i.remoteItem.size;
e.displayName = i.name;
e.canRead = e.canWrite = true;
e.path = getProtocolId() +"://"+path;
if (i.lastModifiedDateTime != null)
e.lastModifiedTime = i.lastModifiedDateTime.getTimeInMillis();
else if ((i.remoteItem != null)&&(i.remoteItem.lastModifiedDateTime != null))
e.lastModifiedTime = i.remoteItem.lastModifiedDateTime.getTimeInMillis();
e.isDirectory = (i.folder != null) || ((i.remoteItem != null) && (i.remoteItem.folder != null));
return e;
}
@Override
public FileEntry getFileEntry(String filename) throws Exception {
try {
ClientAndPath clientAndPath = getOneDriveClientAndPath(filename);
IDriveItemRequestBuilder pathItem = clientAndPath.getPathItem();
IDriveItemRequest request = pathItem.buildRequest();
DriveItem item = request.get();
return getFileEntry(filename, item);
} catch (ClientException e) {
throw convertException(e);
}
}
@Override
public void delete(String path) throws Exception {
try {
ClientAndPath clientAndPath = getOneDriveClientAndPath(path);
clientAndPath.client.getDrive()
.getRoot()
.getItemWithPath(clientAndPath.oneDrivePath)
.buildRequest()
.delete();
} catch (ClientException e) {
throw convertException(e);
}
}
boolean acquireTokenRunning = false;
@Override
public void onStart(final FileStorageSetupActivity activity) {
Log.d("KP2AJ", "onStart " + activity.getPath());
if (activity.getProcessName().equals(PROCESS_NAME_SELECTFILE))
activity.getState().putString(EXTRA_PATH, activity.getPath());
String userId = activity.getState().getString("OneDriveUser");
if (mClientByUser.containsKey(userId)) {
finishActivityWithSuccess(activity);
return;
}
JavaFileStorage.FileStorageSetupActivity storageSetupAct = activity;
final CountDownLatch latch = new CountDownLatch(1);
final AuthenticationResult[] _authenticationResult = {null};
MsalException _exception[] = {null};
if (!acquireTokenRunning) {
acquireTokenRunning = true;
mPublicClientApp.acquireToken((Activity) activity, scopes, new AuthenticationCallback() {
@Override
public void onSuccess(AuthenticationResult authenticationResult) {
Log.i(TAG, "authenticating successful");
try {
buildClient(authenticationResult);
} catch (InterruptedException e) {
e.printStackTrace();
}
activity.getState().putString(EXTRA_PATH, getProtocolPrefix() + authenticationResult.getUser().getUserIdentifier() + "/");
finishActivityWithSuccess(activity);
acquireTokenRunning = false;
return;
}
@Override
public void onError(MsalException exception) {
Log.i(TAG, "authenticating not successful");
Intent data = new Intent();
data.putExtra(EXTRA_ERROR_MESSAGE, "authenticating not successful");
((Activity) activity).setResult(Activity.RESULT_CANCELED, data);
((Activity) activity).finish();
acquireTokenRunning = false;
}
@Override
public void onCancel() {
Log.i(TAG, "authenticating cancelled");
Intent data = new Intent();
data.putExtra(EXTRA_ERROR_MESSAGE, "authenticating not cancelled");
((Activity) activity).setResult(Activity.RESULT_CANCELED, data);
((Activity) activity).finish();
acquireTokenRunning = false;
}
});
}
}
@Override
public void onActivityResult(FileStorageSetupActivity activity, int requestCode, int resultCode, Intent data) {
mPublicClientApp.handleInteractiveRequestRedirect(requestCode, resultCode, data);
}
}

View File

@@ -14,6 +14,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.UUID;
import java.util.regex.Pattern;
import com.pcloud.sdk.ApiClient;
@@ -27,6 +28,7 @@ import com.pcloud.sdk.PCloudSdk;
import com.pcloud.sdk.RemoteEntry;
import com.pcloud.sdk.RemoteFile;
import com.pcloud.sdk.RemoteFolder;
import com.pcloud.sdk.UploadOptions;
/**
* FileStorage implementation for PCloud provider.
@@ -52,7 +54,7 @@ public class PCloudFileStorage extends JavaFileStorageBase
@Override
public boolean requiresSetup(String path) {
return true;
return !this.isConnected();
}
@Override
@@ -136,7 +138,9 @@ public class PCloudFileStorage extends JavaFileStorageBase
RemoteFolder remoteFolder = this.getRemoteFolderByPath(filePath);
try {
this.apiClient.createFile(remoteFolder, filename, dataSource).execute();
RemoteFile remoteFile = this.apiClient.createFile(
remoteFolder, filename, dataSource, null, null, UploadOptions.OVERRIDE_FILE
).execute();
} catch (ApiError e) {
throw convertApiError(e);
}
@@ -372,7 +376,7 @@ public class PCloudFileStorage extends JavaFileStorageBase
private Exception convertApiError(ApiError e) {
String strErrorCode = String.valueOf(e.errorCode());
if (strErrorCode.startsWith("1") || "2000".equals(strErrorCode)) {
if (strErrorCode.startsWith("1") || "2000".equals(strErrorCode) || "2095".equals(strErrorCode)) {
this.clearAuthToken();
return new UserInteractionRequiredException("Unlinked from PCloud! User must re-link.", e);
} else if (strErrorCode.startsWith("2")) {

View File

@@ -24,7 +24,6 @@ import com.jcraft.jsch.UserInfo;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
public class SftpStorage extends JavaFileStorageBase {
@@ -358,12 +357,10 @@ public class SftpStorage extends JavaFileStorageBase {
}
@NonNull
private String getBaseDir() {
return _appContext.getFilesDir().getAbsolutePath();
}
@NonNull
private String getKeyFileName() {
return getBaseDir() + "/id_kp2a_rsa";
}

View File

@@ -29,6 +29,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
@@ -70,9 +71,18 @@ public class WebDavStorage extends JavaFileStorageBase {
String scheme = filename.substring(0, filename.indexOf("://"));
filename = filename.substring(scheme.length() + 3);
String userPwd = filename.substring(0, filename.indexOf('@'));
ci.username = decode(userPwd.substring(0, userPwd.indexOf(":")));
ci.password = decode(userPwd.substring(userPwd.indexOf(":") + 1));
int idxAt = filename.indexOf('@');
if (idxAt >= 0)
{
String userPwd = filename.substring(0, idxAt);
int idxColon = userPwd.indexOf(":");
if (idxColon >= 0);
{
ci.username = decode(userPwd.substring(0, idxColon));
ci.password = decode(userPwd.substring(idxColon + 1));
}
}
ci.URL = scheme + "://" +filename.substring(filename.indexOf('@') + 1);
return ci;
}
@@ -149,13 +159,19 @@ public class WebDavStorage extends JavaFileStorageBase {
sslContext.init(null, new TrustManager[] { trustManager }, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
builder = builder.sslSocketFactory(sslSocketFactory, trustManager)
.hostnameVerifier(new DecoratedHostnameVerifier(OkHostnameVerifier.INSTANCE, mCertificateErrorHandler));
builder.connectTimeout(25, TimeUnit.SECONDS);
builder.readTimeout(25, TimeUnit.SECONDS);
builder.writeTimeout(25, TimeUnit.SECONDS);
}
OkHttpClient client = builder.build();
return client;
}

View File

@@ -0,0 +1,45 @@
package keepass2android.javafilestorage.onedrive2;
import com.microsoft.graph.authentication.IAuthenticationProvider;
import com.microsoft.graph.core.DefaultClientConfig;
import com.microsoft.graph.core.IClientConfig;
import com.microsoft.graph.extensions.GraphServiceClient;
import com.microsoft.graph.extensions.IGraphServiceClient;
import com.microsoft.graph.http.IHttpRequest;
/**
* Singleton class that manages a GraphServiceClient object.
* It implements IAuthentication provider to authenticate requests using an access token.
*/
public class GraphServiceClientManager implements IAuthenticationProvider {
private IGraphServiceClient mGraphServiceClient;
private String mAccessToken;
public GraphServiceClientManager(String accessToken) {
mAccessToken = accessToken;
}
@Override
public void authenticateRequest(IHttpRequest request) {
try {
request.addHeader("Authorization", "Bearer " + mAccessToken);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
public synchronized IGraphServiceClient getGraphServiceClient() {
return getGraphServiceClient(this);
}
public synchronized IGraphServiceClient getGraphServiceClient(IAuthenticationProvider authenticationProvider) {
if (mGraphServiceClient == null) {
IClientConfig clientConfig = DefaultClientConfig.createWithAuthenticationProvider(
authenticationProvider
);
mGraphServiceClient = new GraphServiceClient.Builder().fromConfig(clientConfig).buildClient();
}
return mGraphServiceClient;
}
}

View File

@@ -10,6 +10,8 @@ android {
targetSdkVersion 23
versionCode 1
versionName "1.0"
multiDexEnabled true
}
buildTypes {

View File

@@ -59,6 +59,18 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.microsoft.identity.client.BrowserTabActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/msalPrefix"
android:host="auth" />
</intent-filter>
</activity>
</application>
@@ -68,6 +80,8 @@
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

View File

@@ -89,6 +89,8 @@ extends Activity implements JavaFileStorage.FileStorageSetupActivity {
@Override
public String getPath() {
// TODO Auto-generated method stub
if (getState().containsKey(JavaFileStorage.EXTRA_PATH))
return getState().getString(JavaFileStorage.EXTRA_PATH);
return getIntent().getStringExtra(JavaFileStorage.EXTRA_PATH);
}

View File

@@ -135,7 +135,6 @@ package com.crocoapps.javafilestoragetest;
import group.pals.android.lib.ui.filechooser.FileChooserActivity;
import group.pals.android.lib.ui.filechooser.providers.BaseFileProviderUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -146,11 +145,9 @@ import java.util.ArrayList;
import java.util.List;
//import keepass2android.javafilestorage.DropboxCloudRailStorage;
import keepass2android.javafilestorage.DropboxV2Storage;
import keepass2android.javafilestorage.ICertificateErrorHandler;
import keepass2android.javafilestorage.JavaFileStorage;
import keepass2android.javafilestorage.JavaFileStorage.FileEntry;
import keepass2android.javafilestorage.OneDriveStorage;
import keepass2android.javafilestorage.OneDriveStorage2;
import keepass2android.javafilestorage.SftpStorage;
import keepass2android.javafilestorage.UserInteractionRequiredException;
import keepass2android.javafilestorage.WebDavStorage;
@@ -206,10 +203,17 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
}
catch (Exception e)
{
Log.d("KP2AJ",e.toString());
//if exception because folder exists
path = fs.createFilePath(parentPath, testPath);
}
String textToUpload2 = "abcdefg";
String filename2 = fs.createFilePath(parentPath, "file.txt");
/*if (!path.endsWith("/"))
path += "/";
String filename = path+"file.text";*/
fs.uploadFile(filename2,textToUpload2.getBytes(),true);
FileEntry e1 = fs.getFileEntry(parentPath);
FileEntry e2 = fs.getFileEntry(path);
@@ -531,9 +535,11 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
}
static JavaFileStorage createStorageToTest(Context ctx, Context appContext, boolean simulateRestart) {
storageToTest = new SftpStorage(ctx.getApplicationContext());
//storageToTest = new SftpStorage(ctx.getApplicationContext());
//storageToTest = new SkyDriveFileStorage("000000004010C234", appContext);
//storageToTest = new OneDriveStorage(appContext, "000000004010C234");
storageToTest = new OneDriveStorage2((Activity) ctx, "8374f801-0f55-407d-80cc-9a04fe86d9b2");
//storageToTest = new GoogleDriveFileStorage();
/*storageToTest = new WebDavStorage(new ICertificateErrorHandler() {
@Override
@@ -620,7 +626,7 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
Toast.makeText(this, "requestCode: "+requestCode, Toast.LENGTH_LONG).show();
if (requestCode == 1)
//new PerformTestTask().execute(path,"TestFileStorage<67>", storageToTest); //use an umlaut to see how that works
new PerformTestTask().execute(path,"TestFileStorage", storageToTest);
new PerformTestTask().execute(path,"TestFileStorage", storageToTest);
else
if (requestCode == 2)
{

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="msalPrefix">msal8374f801-0f55-407d-80cc-9a04fe86d9b2</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="title_activity_file_storage_setup">FileStorageSetupActivity</string>

View File

@@ -2,10 +2,14 @@ package keepass2android.softkeyboard;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.Channels;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.xmlpull.v1.XmlPullParserException;
@@ -17,9 +21,11 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.util.Log;
//based on https://github.com/klausw/hackerskeyboard/blob/master/java/src/org/pocketworkstation/pckeyboard/PluginManager.java
public class PluginManager extends BroadcastReceiver {
private static String TAG = "PCKeyboard";
private static String HK_INTENT_DICT = "org.pocketworkstation.DICT";
@@ -120,6 +126,46 @@ public class PluginManager extends BroadcastReceiver {
}
}
}
static private class DictPluginSpecResourceSoftKeyboard
extends DictPluginSpecBase {
int[] resId;
Resources pluginRes;
public DictPluginSpecResourceSoftKeyboard(String pkg, int[] resId, Resources pluginRes) {
mPackageName = pkg;
this.resId = resId;
this.pluginRes = pluginRes;
}
@Override
InputStream[] getStreams(Resources res) {
final InputStream[] is = new InputStream[resId.length];
try {
// merging separated dictionary into one if dictionary is separated
int total = 0;
for (int i = 0; i < resId.length; i++) {
// http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/
// NOTE: the resource file can not be larger than 1MB
is[i] = pluginRes.openRawResource(resId[i]);
final int dictSize = is[i].available();
Log.d(TAG, "Will load a resource dictionary id " + resId[i] + " whose size is " + dictSize + " bytes.");
total += dictSize;
}
return is;
} catch (IOException e) {
Log.w(TAG, "No available memory for binary dictionary: " + e.getMessage());
}
return null;
}
}
@Override
public void onReceive(Context context, Intent intent) {
@@ -129,21 +175,59 @@ public class PluginManager extends BroadcastReceiver {
mIME.toggleLanguage(true, true);
}
public interface MemRelatedOperation {
void operation();
}
static final int GC_TRY_LOOP_MAX = 5;
static void doGarbageCollection(final String tag) {
System.gc();
try {
Thread.sleep(1000 /*ms*/);
} catch (InterruptedException e) {
Log.e(tag, "Sleep was interrupted.");
}
}
static public void performOperationWithMemRetry(final String tag, MemRelatedOperation operation) {
int retryCount = GC_TRY_LOOP_MAX;
while (true) {
try {
operation.operation();
return;
} catch (OutOfMemoryError e) {
if (retryCount == 0) throw e;
retryCount--;
Log.w(tag, "WOW! No memory for operation... I'll try to release some.");
doGarbageCollection(tag);
}
}
}
static void getSoftKeyboardDictionaries(PackageManager packageManager) {
Intent dictIntent = new Intent(SOFTKEYBOARD_INTENT_DICT);
List<ResolveInfo> dictPacks = packageManager.queryBroadcastReceivers(
dictIntent, PackageManager.GET_RECEIVERS);
for (ResolveInfo ri : dictPacks) {
ApplicationInfo appInfo = ri.activityInfo.applicationInfo;
String pkgName = appInfo.packageName;
boolean success = false;
final String pkgName = appInfo.packageName;
final boolean[] success = {false};
try {
Resources res = packageManager.getResourcesForApplication(appInfo);
final Resources res = packageManager.getResourcesForApplication(appInfo);
Log.i("KP2AK", "Found dictionary plugin package: " + pkgName);
int dictId = res.getIdentifier("dictionaries", "xml", pkgName);
if (dictId == 0) continue;
if (dictId == 0)
{
Log.i("KP2AK", "dictId == 0");
continue;
}
XmlResourceParser xrp = res.getXml(dictId);
int dictResourceId = 0;
String assetName = null;
String lang = null;
try {
@@ -157,12 +241,21 @@ public class PluginManager extends BroadcastReceiver {
String convLang = SOFTKEYBOARD_LANG_MAP.get(lang);
if (convLang != null) lang = convLang;
String type = xrp.getAttributeValue(null, "type");
if (type == null || type.equals("raw") || type.equals("binary")) {
if (type == null || type.equals("raw") || type.equals("binary"))
{
assetName = xrp.getAttributeValue(null, "dictionaryAssertName"); // sic
} else {
if (assetName != null) {
Log.i(TAG, "asset=" + assetName + " lang=" + lang);
}
} else if (type.equals("binary_resource"))
{
dictResourceId = xrp.getAttributeResourceValue(null, "dictionaryResourceId",0);
}
else {
Log.w(TAG, "Unsupported AnySoftKeyboard dict type " + type);
}
//Log.i(TAG, "asset=" + assetName + " lang=" + lang);
}
}
}
@@ -175,15 +268,55 @@ public class PluginManager extends BroadcastReceiver {
Log.e(TAG, "Dictionary XML IOException");
}
if (assetName == null || lang == null) continue;
DictPluginSpec spec = new DictPluginSpecSoftKeyboard(pkgName, assetName);
mPluginDicts.put(lang, spec);
Log.i("KP2AK", "Found plugin dictionary: lang=" + lang + ", pkg=" + pkgName);
success = true;
if (lang == null)
continue;
if (assetName != null) {
DictPluginSpec spec = new DictPluginSpecSoftKeyboard(pkgName, assetName);
mPluginDicts.put(lang, spec);
Log.i("KP2AK", "Found plugin dictionary: lang=" + lang + ", pkg=" + pkgName);
success[0] = true;
}
else if (dictResourceId != 0)
{
Resources pkgRes = packageManager.getResourcesForApplication(appInfo);
final int[] resId;
// is it an array of dictionaries? Or a ref to raw?
final String dictResType = pkgRes.getResourceTypeName(dictResourceId);
if (dictResType.equalsIgnoreCase("raw")) {
resId = new int[]{dictResourceId};
} else {
TypedArray a = pkgRes.obtainTypedArray(dictResourceId);
resId = new int[a.length()];
for (int index = 0; index < a.length(); index++)
resId[index] = a.getResourceId(index, 0);
a.recycle();
}
final String finalLang = lang;
performOperationWithMemRetry(TAG, new MemRelatedOperation() {
@Override
public void operation() {
// The try-catch is for issue 878:
// http://code.google.com/p/softkeyboard/issues/detail?id=878
try {
DictPluginSpec spec = new DictPluginSpecResourceSoftKeyboard(pkgName, resId, res);
mPluginDicts.put(finalLang, spec);
Log.i("KP2AK", "Found plugin dictionary: lang=" + finalLang + ", pkg=" + pkgName);
success[0] = true;
} catch (UnsatisfiedLinkError ex) {
Log.w(TAG, "Failed to load binary JNI connection! Error: " + ex.getMessage());
}
}
});
}
} catch (NameNotFoundException e) {
Log.i("KP2AK", "bad");
} finally {
if (!success) {
if (!success[0]) {
Log.i("KP2AK", "failed to load plugin dictionary spec from " + pkgName);
}
}
@@ -193,6 +326,7 @@ public class PluginManager extends BroadcastReceiver {
static void getHKDictionaries(PackageManager packageManager) {
Intent dictIntent = new Intent(HK_INTENT_DICT);
List<ResolveInfo> dictPacks = packageManager.queryIntentActivities(dictIntent, 0);
Log.i("KP2AK", "Searching for HK dictionaries. Found " + dictPacks.size() + " packages");
for (ResolveInfo ri : dictPacks) {
ApplicationInfo appInfo = ri.activityInfo.applicationInfo;
String pkgName = appInfo.packageName;

View File

@@ -6,6 +6,7 @@ import java.util.Iterator;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -65,7 +66,16 @@ public abstract class PluginActionBroadcastReceiver extends BroadcastReceiver {
protected String[] getProtectedFieldsListFromIntent()
{
return _intent.getStringArrayExtra(Strings.EXTRA_PROTECTED_FIELDS_LIST);
try {
JSONArray json = new JSONArray(_intent.getStringExtra(Strings.EXTRA_PROTECTED_FIELDS_LIST));
String[] res = new String[json.length()];
for(int i = 0; i < json.length(); i++)
res[i] = json.getString(i);
return res;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}

1
src/java/PluginQR/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

1
src/java/PluginQR/app/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "keepass2android.plugin.qr"
minSdkVersion 14
targetSdkVersion 19
versionCode 3
versionName "1.0.2"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
lintOptions {
disable 'ExtraTranslation'
disable 'MissingTranslation'
}
}
dependencies {
compile project(':Keepass2AndroidPluginSDK2')
compile 'com.google.zxing:core:2.3.0'
}

View File

@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="keepass2android.plugin.qr"
android:versionCode="2"
android:versionName="1.0.1" >
package="keepass2android.plugin.qr" >
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission
@@ -15,10 +13,6 @@
<uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
<uses-feature android:name="android.hardware.screen.portrait" android:required="false"/>
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"

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