1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-05 23:53:33 +00:00

Compare commits

...

225 Commits

Author SHA1 Message Date
Kyle Spearrin
aeb01ba292 break if too many iterations 2018-02-10 09:39:45 -05:00
Kyle Spearrin
2b1a556e9e re-enable vs update 2018-02-10 09:38:12 -05:00
Kyle Spearrin
d5c3ae3d19 guard against infinite recursion and loops 2018-02-10 09:35:14 -05:00
Kyle Spearrin
7654bb7088 check if child is same as parent 2018-02-10 00:38:52 -05:00
Kyle Spearrin
64c301caeb password gen fixes 2018-02-09 22:02:56 -05:00
Kyle Spearrin
e875b530b1 bail out if recursiveIterations >= 100 2018-02-09 16:23:51 -05:00
Kyle Spearrin
ee8c2b5272 thread sleeps 2018-02-09 15:00:54 -05:00
Kyle Spearrin
9b8bdb0639 remove log spam 2018-02-09 14:02:17 -05:00
Kyle Spearrin
1a99bbb040 more log info 2018-02-08 22:08:00 -05:00
Kyle Spearrin
0982b45473 more log spam 2018-02-08 17:44:48 -05:00
Kyle Spearrin
bcd210d504 log spam 2018-02-08 17:27:56 -05:00
Kyle Spearrin
c71608824b fix null ref with e.source 2018-02-08 17:07:01 -05:00
Kyle Spearrin
170876ac16 event info logs 2018-02-08 16:36:49 -05:00
Kyle Spearrin
a6b172c445 log and throw accessibility exceptions 2018-02-08 16:33:52 -05:00
Kyle Spearrin
e625450100 disable vs update 2018-02-08 16:00:11 -05:00
Kyle Spearrin
fca5447094 revert accessibility throttling 2018-02-03 09:47:16 -05:00
Kyle Spearrin
89f32beec5 throttle accessibility events 2018-02-03 09:21:27 -05:00
Kyle Spearrin
65eb7662ad remove appveyor debugging. just update vs 2018-02-03 00:00:05 -05:00
Kyle Spearrin
ea090dbe18 just update 2018-02-02 23:48:46 -05:00
Kyle Spearrin
5750817620 quiet update with echos 2018-02-02 22:30:00 -05:00
Kyle Spearrin
93386d0e8b passive update 2018-02-02 22:23:39 -05:00
Kyle Spearrin
e9dd7b8f98 update vs 2018-02-02 22:19:36 -05:00
Kyle Spearrin
5010e7cb7a update visual studio manually 2018-02-02 22:00:58 -05:00
Kyle Spearrin
fb35f4fbca Previous Visual Studio 2017 2018-02-02 13:49:44 -05:00
Kyle Spearrin
00c0a93a6b revert preview image 2018-02-02 13:45:26 -05:00
Kyle Spearrin
cd9a312e0b use VS preview image 2018-02-02 13:38:49 -05:00
Kyle Spearrin
8cdb27fe43 check modal stack before popping 2018-02-01 23:38:18 -05:00
Kyle Spearrin
d84d11d064 update xamarin forms 2018-02-01 23:38:06 -05:00
Kyle Spearrin
5d646a6112 various android crash fixes 2018-02-01 23:25:48 -05:00
Kyle Spearrin
dd334858ff add timeout on timers 2018-02-01 21:20:35 -05:00
Kyle Spearrin
dfd39ebc95 check installed launchers to skip 2018-02-01 21:20:28 -05:00
Kyle Spearrin
9dbb1f15a4 filter nova prime 2018-02-01 17:26:41 -05:00
Kyle Spearrin
32fd04a7d9 more filters 2018-02-01 17:23:41 -05:00
Kyle Spearrin
3a33ff375d turn back on autofill stuff 2018-02-01 17:17:18 -05:00
Kyle Spearrin
8877e71bd2 add back SystemUiPackage 2018-02-01 17:01:37 -05:00
Kyle Spearrin
5b5385c01d add FilteredPackageNames 2018-02-01 16:56:54 -05:00
Kyle Spearrin
9c365ecc48 log events 2018-02-01 16:27:08 -05:00
Kyle Spearrin
99d1a6d043 read RootInActiveWindow after launcher checks 2018-02-01 16:12:30 -05:00
Kyle Spearrin
854ef7e645 log any exceptions 2018-02-01 15:54:39 -05:00
Kyle Spearrin
a8eeb12325 just read RootInActiveWindow 2018-02-01 15:42:07 -05:00
Kyle Spearrin
86a3f516b1 test: start processing some event info 2018-02-01 15:29:41 -05:00
Kyle Spearrin
d6818939b3 test: turn some things back on 2018-02-01 15:21:22 -05:00
Kyle Spearrin
c51449e607 test: dont even init appsettings 2018-02-01 15:03:44 -05:00
Kyle Spearrin
333894ddeb test: do nothing for autofill service 2018-02-01 15:00:43 -05:00
Kyle Spearrin
052e227b65 comment out test nodes 2018-02-01 14:31:53 -05:00
Kyle Spearrin
4dd6df5bbe set package and website independently 2018-01-26 12:15:54 -05:00
Kyle Spearrin
8847991bba show attachments properly if an organization 2018-01-26 11:48:43 -05:00
Kyle Spearrin
0ffc6e4a1a show attachments if premium or org item 2018-01-26 11:02:35 -05:00
Kyle Spearrin
9a399e06f3 decrypt attachment with org id 2018-01-26 09:13:30 -05:00
Kyle Spearrin
6afccc2aea add duckduckgo support 2018-01-26 08:56:43 -05:00
Kyle Spearrin
8cd3a21468 null and length check on name when sorting 2018-01-25 21:20:45 -05:00
Kyle Spearrin
8b6d2d2b83 comment typo 2018-01-25 09:07:19 -05:00
Kyle Spearrin
a39f4d5987 split by no-break space for yandex 2018-01-25 09:06:01 -05:00
Kyle Spearrin
e236d045b0 use MasterPasswordConfirmationValMessage 2018-01-24 20:21:54 -05:00
Alistair Francis
592c7951df UWP: Add a ExtendedTableViewRenderer (#260)
Add a base ExtendedTableViewRenderer we can use.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-19 14:04:58 -05:00
Kyle Spearrin
41efa96291 unsub from yubikey events on disappearing 2018-01-18 13:24:23 -05:00
Kyle Spearrin
53f406a267 log out after 5 failed pin attempts 2018-01-18 13:18:08 -05:00
Kyle Spearrin
1390df48b6 use random key for double hmac comparisons 2018-01-18 09:31:22 -05:00
Kyle Spearrin
01878ef00c check that mac always exists if key has MacKey 2018-01-18 08:39:34 -05:00
Kyle Spearrin
6f119f25f4 missing props on TokenCell 2018-01-18 08:09:18 -05:00
Alistair Francis
3f31d78db1 Add YubiKey keyboard support (#248)
* App: Pages: Fix the YubiKey image source

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Allow YubiKey keyboard output on apps

On Android and UWP it's possible to use the YubiKey to enter text
instead of using the NFC. Allow people to do that.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Pages: Enable YubiKey support on Windows platforms

Windows platforms should always have YubiKey support.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-18 07:55:06 -05:00
Alistair Francis
014bf7777b Update some images (#257)
* UWP.Images: Update the launch.png image size

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Pages: Update login toolbar button

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-17 08:29:59 -05:00
Kyle Spearrin
7191969e9c Update README.md 2018-01-14 21:43:25 -05:00
Kyle Spearrin
0950510526 scope if shorthand 2018-01-11 12:07:13 -05:00
Kyle Spearrin
9eba3064a7 formatting 2018-01-11 12:02:03 -05:00
Kyle Spearrin
a4d785258e build for configuration release 2018-01-11 09:04:58 -05:00
Kyle Spearrin
efef49f976 Revert "choose/when fdroid conditional on packages"
This reverts commit b3573f9482.
2018-01-11 09:03:05 -05:00
Kyle Spearrin
32a7b5bafb Revert "clean and rebuild FDroid"
This reverts commit 5fa080063c.
2018-01-11 09:00:29 -05:00
Kyle Spearrin
5fa080063c clean and rebuild FDroid 2018-01-11 08:52:47 -05:00
Kyle Spearrin
b3573f9482 choose/when fdroid conditional on packages 2018-01-11 08:36:37 -05:00
Kyle Spearrin
916b7ee46b reenc keystore 2018-01-10 23:26:44 -05:00
Kyle Spearrin
bfe8ad2034 quiet output 2018-01-10 23:00:10 -05:00
Kyle Spearrin
bb9db7bf9d full android project path 2018-01-10 22:36:51 -05:00
Kyle Spearrin
d7f7c8c568 build script fixes 2018-01-10 22:30:30 -05:00
Kyle Spearrin
10839588dd Invoke-Expression 2018-01-10 22:20:22 -05:00
Kyle Spearrin
12cd2b67cd ci build apks script 2018-01-10 22:10:32 -05:00
Kyle Spearrin
9a13036f4e fdroid-build script 2018-01-10 18:32:57 -05:00
Kyle Spearrin
2f025d51ff remove rdp from appveyor 2018-01-10 18:01:48 -05:00
Kyle Spearrin
6cb6d3a358 run nuget restore 2018-01-10 17:19:56 -05:00
Kyle Spearrin
0bb01d14bd clean fdroid 2018-01-10 16:53:09 -05:00
Kyle Spearrin
2229c4e4d1 enable rdp for appveyor debugging 2018-01-10 16:37:05 -05:00
Kyle Spearrin
5c90c62378 msbuild android proj only 2018-01-10 16:10:47 -05:00
Kyle Spearrin
b7ed0a29fe clean with msbuild 2018-01-10 15:55:07 -05:00
Kyle Spearrin
796c2ed58c build solution again for fdroid 2018-01-10 15:40:17 -05:00
Kyle Spearrin
39bd573d9d backup original csproj files and clean bin folders 2018-01-10 15:26:27 -05:00
Kyle Spearrin
d4aaa547a7 remove libs for fdroid build 2018-01-10 14:55:18 -05:00
Kyle Spearrin
f7e2382847 AndroidApkSigningAlgorithm of SHA1withRSA 2018-01-10 13:38:08 -05:00
Kyle Spearrin
4bb16e7d93 version bump 2018-01-10 12:18:48 -05:00
Kyle Spearrin
e7e00e4ebf add target framework to PropertyGroup conditional 2018-01-10 11:52:53 -05:00
Kyle Spearrin
55d050fca7 fdroid artifacts for build 2018-01-10 09:35:47 -05:00
Kyle Spearrin
98d4fef0ee fdroid builds without Google and Hockey services 2018-01-10 09:28:30 -05:00
Kyle Spearrin
5521892736 secure note option handled 2018-01-10 08:47:20 -05:00
Kyle Spearrin
8f0fd0dfef F-Droid build configuration 2018-01-10 00:41:29 -05:00
Kyle Spearrin
514eab0b98 Merge branch 'master' of github.com:bitwarden/mobile 2018-01-09 11:31:14 -05:00
Kyle Spearrin
e35c84245d added org.mozilla.klar to whitelist 2018-01-09 11:31:00 -05:00
Kyle Spearrin
4a2391eb1b New Crowdin translations (#247)
* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Estonian)
2018-01-08 21:19:45 -05:00
Kyle Spearrin
04eb497e10 version bump 2018-01-08 21:17:05 -05:00
Kyle Spearrin
a9a5da6dc6 update ffimageloading lib 2018-01-08 11:51:23 -05:00
Kyle Spearrin
3f1aab27d6 android back on main pages goes to vault first 2018-01-08 11:33:51 -05:00
Kyle Spearrin
8f77df4ebb Don't animate loading alert 2018-01-08 09:10:58 -05:00
Alistair Francis
65a8b3fcd4 UWP.Images: Reduce the size of the camera icon (#245)
Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-05 16:33:34 -05:00
Alistair Francis
71dd4e512e App: Pages: Add a null check in OnSelectTemplate() (#243)
To avoid accessing a null poiter add a null check in OnSelectTemplate().

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-04 23:33:10 -05:00
Alistair Francis
ca03a5ecf4 App: Controls: Improve the vault view images (#240)
* App: Controls: Improve the vault view images

Make the buttons smaller and ensure the background is transparent.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* UWP.Images: Use smaller size images

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* UWP.Images: Remove unused image

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-04 23:32:50 -05:00
Kyle Spearrin
694efb9508 unit FFImageLoading with fast renderer; TLS 1.2 2018-01-04 13:07:50 -05:00
Kyle Spearrin
c60a112039 update FFImageLoading and disable gifs on ios 2018-01-04 12:46:29 -05:00
Alistair Francis
c3570dd07a Improve the UWP toast notification colours (#239)
* UWP: Services: Improve the toast notifcation colours

This commit improves the toast notification colours and makes the
notification slightly transparent.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* UWP: Services: Remove the unused Alignment options

These Alignment options don't have an effect on UWP, so just remove
them.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-04 08:32:18 -05:00
Kyle Spearrin
b680b190d4 update app store screenshots 2018-01-03 17:07:47 -05:00
Kyle Spearrin
310d51d859 handle null conditions from action sheet 2018-01-03 17:07:33 -05:00
Kyle Spearrin
cf9e820227 version bump 2018-01-03 14:15:45 -05:00
Kyle Spearrin
b91d2f4fb1 always use CustomTableViewModelRenderer 2018-01-03 13:37:04 -05:00
Kyle Spearrin
9456f5dc31 redraw stack layouts on ios tableviews 2018-01-03 12:18:15 -05:00
Kyle Spearrin
fa9e22730a get rid of old refection and memory services 2018-01-02 16:41:06 -05:00
Kyle Spearrin
7261fd7ed9 version bump 2018-01-02 10:44:59 -05:00
Kyle Spearrin
ad9e5fbf07 appcompat fixes for android 4.4 2018-01-02 10:41:11 -05:00
Kyle Spearrin
c242117230 version bump 2018-01-01 09:17:25 -05:00
Kyle Spearrin
d7c1b23fa2 New Crowdin translations (#234)
* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Estonian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Estonian)
2018-01-01 09:15:45 -05:00
Kyle Spearrin
25e9919bb3 new languages info 2017-12-30 21:48:32 -05:00
Kyle Spearrin
912c01457a New Crowdin translations (#233)
* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Swedish)

* New translations copy.resx (Norwegian Bokmal)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations copy.resx (Estonian)

* New translations copy.resx (Estonian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Norwegian Bokmal)
2017-12-30 21:34:14 -05:00
Kyle Spearrin
8083390eab style for ExtendedListView 2017-12-30 21:33:29 -05:00
Kyle Spearrin
44baa4cc1e fix compile error in renderer 2017-12-30 21:31:01 -05:00
Kyle Spearrin
f0662bb878 adjust bottom paddings on listviews/tableviews 2017-12-30 21:18:24 -05:00
Kyle Spearrin
fbe1a6d4c5 floating action button on android 2017-12-30 14:05:51 -05:00
Kyle Spearrin
2235f1f7af change dot to bullet 2017-12-30 12:02:51 -05:00
Kyle Spearrin
3f46f83ec8 reduce padding 2017-12-29 13:04:19 -05:00
Kyle Spearrin
d537d4a27e make cogs icon larger 2017-12-28 21:37:02 -05:00
Kyle Spearrin
c67250da2d base lock timer off of Stopwatch class 2017-12-28 21:14:30 -05:00
Kyle Spearrin
6027406eef cleanup old icons. make cogs larger 2017-12-28 17:42:29 -05:00
Kyle Spearrin
fdc51f33ad bottom navigation tab page on android 2017-12-28 17:31:44 -05:00
Kyle Spearrin
ea7290afab CheckForLockInBackground removed 2017-12-28 16:48:40 -05:00
Kyle Spearrin
be65597d57 detect TW language. resolves #228 2017-12-28 12:38:15 -05:00
Kyle Spearrin
253ed75800 lock not required during app ext setup 2017-12-27 23:50:35 -05:00
Kyle Spearrin
e4f3671ae0 no lock time updates from ios extension 2017-12-27 23:39:55 -05:00
Kyle Spearrin
c60cefd188 internal timer for lock checking 2017-12-27 22:18:11 -05:00
Kyle Spearrin
175a41f275 logic adjustments for first lock check 2017-12-27 17:05:33 -05:00
Kyle Spearrin
bd5fd72459 _firstLockCheck logic adjustments 2017-12-27 16:36:01 -05:00
Kyle Spearrin
98b70a647b resource fixes 2017-12-27 15:56:12 -05:00
Kyle Spearrin
3eee5e696d support for pr-BR 2017-12-27 15:42:46 -05:00
Kyle Spearrin
d92c6cc6c6 always locked if not running in memory 2017-12-27 15:39:51 -05:00
Kyle Spearrin
488485da54 New Crowdin translations (#230)
* New translations AppResources.resx (Chinese Simplified)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Romanian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Turkish)

* New translations copy.resx (Vietnamese)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Swedish)

* New translations copy.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (German)

* New translations copy.resx (Vietnamese)
2017-12-27 15:19:27 -05:00
Kyle Spearrin
a3f0254fb2 background timer for locking 2017-12-27 11:14:53 -05:00
Kyle Spearrin
ab5f1385c5 update to net471 2017-12-26 22:38:04 -05:00
Kyle Spearrin
cde5b09943 dismiss previous toasts on android 2017-12-23 23:48:47 -05:00
Kyle Spearrin
db42b6a3a5 null coalesce 2017-12-23 23:40:41 -05:00
Kyle Spearrin
ece35b96db dismiss previous toast & cleanup 2017-12-23 23:34:46 -05:00
Kyle Spearrin
c4c24ee240 toast layout updates 2017-12-23 23:22:47 -05:00
Kyle Spearrin
c7ba465970 TabBarVisible logic fix 2017-12-23 22:56:17 -05:00
Kyle Spearrin
937ad444da OK => Allow 2017-12-23 08:53:12 -05:00
Kyle Spearrin
0c0a928e87 adjust toast bottom margin depending on tab bar 2017-12-23 00:34:07 -05:00
Kyle Spearrin
2823a86b4e remove old grouping binding 2017-12-23 00:23:07 -05:00
Kyle Spearrin
1a06683611 fix arc remains in ios projects 2017-12-23 00:19:45 -05:00
Kyle Spearrin
50fa74adfe noop device action service 2017-12-23 00:10:48 -05:00
Kyle Spearrin
4ebd249356 user dialogs on UWP for loading 2017-12-23 00:04:52 -05:00
Kyle Spearrin
4dc388015c remove arc dialogs. create custom loading actions 2017-12-22 23:56:45 -05:00
Kyle Spearrin
0270cf6e45 convert user dialogs to native XF options 2017-12-22 22:41:48 -05:00
Kyle Spearrin
7a19c50ec0 autofill fixes 2017-12-22 18:34:46 -05:00
Kyle Spearrin
e2fc5fff23 Fixes for toast on iOS 2017-12-22 16:59:36 -05:00
Kyle Spearrin
839df123ff custom toast for ios 2017-12-22 16:18:16 -05:00
Kyle Spearrin
f897193f79 noop toast 2017-12-22 15:05:09 -05:00
Kyle Spearrin
9f23f4ead7 custom toast implementations 2017-12-22 15:00:11 -05:00
Kyle Spearrin
45ab6d47de upper section titles for autofill listing 2017-12-22 13:33:18 -05:00
Kyle Spearrin
35bc94f4bd revert uneven padding 2017-12-22 11:59:20 -05:00
Kyle Spearrin
94a4a38798 layout adjustments 2017-12-22 11:36:09 -05:00
Kyle Spearrin
7f431dbd01 Deprecate XF.Context and give context to renderers 2017-12-22 11:23:03 -05:00
Kyle Spearrin
d0257df134 custom thumb on slider for android 2017-12-22 09:30:30 -05:00
Alistair Francis
be3ed16d3c UWP: Generate UWP Assets (#220)
Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-22 00:14:44 -05:00
Kyle Spearrin
b651becf66 simplify push in UWP as well 2017-12-21 23:33:13 -05:00
Kyle Spearrin
bcf49ab396 cleanup and simplify ios push reg/handling 2017-12-21 23:26:46 -05:00
Kyle Spearrin
fb76ecf198 dont register on login anymore for android 2017-12-21 22:46:19 -05:00
Kyle Spearrin
1bed49b4c6 decrypt google-services.json for prod builds 2017-12-21 22:39:04 -05:00
Kyle Spearrin
c34376820a register android push on my vault page too 2017-12-21 22:28:09 -05:00
Kyle Spearrin
582e6ee322 switch from GCM to FCM 2017-12-21 22:28:09 -05:00
Kyle Spearrin
2b4ffaa357 add type to deviceinfo to avoid using XF 2017-12-21 22:28:09 -05:00
Kyle Spearrin
379a82972a null checks on appearing 2017-12-21 22:28:08 -05:00
Alistair Francis
713796a4f7 UWP: Fix images when compiling with .NET Native Toolchain (#219)
Following the instructions here:
https://github.com/luberda-molinet/FFImageLoading/wiki/Xamarin.Forms-API#windows-uwp---compile-with-net-native-tool-chain-note
fix the UWP App.xaml.cs to ensure images are loaded when building UWP
apps for release.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-21 08:55:24 -05:00
Kyle Spearrin
54161aaf39 list no folder items on my vault when no collects. 2017-12-20 13:55:59 -05:00
Kyle Spearrin
4054519f38 generated password color is black 2017-12-20 12:08:48 -05:00
Kyle Spearrin
e5d5d8b434 add autofill service support for web browsers 2017-12-20 11:55:16 -05:00
Kyle Spearrin
519fd212d9 fix cancel display logic 2017-12-20 10:30:57 -05:00
Kyle Spearrin
4b21660fd6 only show cancel when coming from another page 2017-12-20 10:22:39 -05:00
Kyle Spearrin
ac5c9e7242 combine password generator options 2017-12-20 09:55:19 -05:00
Kyle Spearrin
4c8431bd5b move password generator to main nav 2017-12-20 09:39:38 -05:00
Kyle Spearrin
a4a93f0999 remove my vault as default page options 2017-12-20 00:11:15 -05:00
Kyle Spearrin
b6a4efa7ba move favorites to top of grouping page 2017-12-19 23:59:12 -05:00
Kyle Spearrin
a4fbd521e3 device-type header on login 2017-12-18 13:58:36 -05:00
Kyle Spearrin
6fe5e89ecc position indicator when not UWP for spinner 2017-12-18 09:23:46 -05:00
Alistair Francis
bc40c95f20 Vault: Don't specify page options for ActivityLoading (#215)
When specifying page options the loader doesn't appear properly on UWP
applications. I also couldn't see the options documented here:
https://developer.xamarin.com/api/type/Xamarin.Forms.ActivityIndicator/

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-18 09:19:06 -05:00
Kyle Spearrin
acd35ac8a2 add net47 target framework 2017-12-18 09:18:16 -05:00
Alistair Francis
c9d9ec1c77 UWP.Images: Add the smile image (#213)
Somehow this was left out in the Windows Hello support commit
(f300d1bafd). Add it now.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-17 22:18:15 -05:00
Alistair Francis
08c4e2d465 UWP: Enable Collection Services (#214)
Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-17 22:17:53 -05:00
Alistair Francis
f300d1bafd Add support for Windows Hello (#212)
Windows Hello is currently supported in the UWP app, but all of the
strings just point to using fingerprint. Windows Hello instead will
adjust based on what the user has avaliable and registered with the
Windows OS. To reflect that it isn't just fingerprints update the
strings when on UWP.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-15 11:20:36 -05:00
Kyle Spearrin
d395115cc9 add support for Device-Type header 2017-12-15 09:48:25 -05:00
Kyle Spearrin
8571755daa netcoreapp20. path for publisher 2017-12-14 11:05:01 -05:00
Kyle Spearrin
9f3368ba1f convert publisher to netcoreapp 2017-12-14 10:54:51 -05:00
Kyle Spearrin
919df1edd5 remove old amazon resource 2017-12-14 10:21:12 -05:00
Kyle Spearrin
c180422e8b fixes for UWP 2017-12-14 10:19:50 -05:00
Kyle Spearrin
e90501a986 update hockeyapp 2017-12-14 10:02:59 -05:00
Kyle Spearrin
545af007b4 updating forms lib 2017-12-14 09:26:32 -05:00
Kyle Spearrin
e189ece487 update some packages 2017-12-13 23:59:45 -05:00
Kyle Spearrin
cebc2b5bdb Revert "update various packages"
This reverts commit c06df3889b.
2017-12-13 23:45:49 -05:00
Kyle Spearrin
444d48a259 Revert "Update to Forms 2.4"
This reverts commit 09ef1b66cc.
2017-12-13 23:30:43 -05:00
Kyle Spearrin
4fd70ad252 downgrade ios GA 2017-12-13 23:23:48 -05:00
Kyle Spearrin
293326b647 Revert "update image lib"
This reverts commit b071238eda.
2017-12-13 21:42:08 -05:00
Kyle Spearrin
b071238eda update image lib 2017-12-13 21:15:47 -05:00
Kyle Spearrin
09ef1b66cc Update to Forms 2.4 2017-12-13 21:04:51 -05:00
Kyle Spearrin
c06df3889b update various packages 2017-12-13 17:35:49 -05:00
Kyle Spearrin
280fc78f7e convert publisher to package ref 2017-12-13 17:20:24 -05:00
Kyle Spearrin
7b9fc04704 remove app config and consolidate packages 2017-12-13 17:14:54 -05:00
Kyle Spearrin
00e60f2592 not preview 2017-12-13 17:04:31 -05:00
Kyle Spearrin
45e9c762a7 update nuget 2017-12-13 16:59:14 -05:00
Kyle Spearrin
77dcb91741 try VS 2017 preview on appveyor 2017-12-13 16:47:05 -05:00
Kyle Spearrin
383c683716 update to netstandard2.0 and nuget ref packages
also removed old test projects no longer in use
2017-12-13 16:41:57 -05:00
Kyle Spearrin
ca3c380493 close folder page, not cancel 2017-12-13 10:37:18 -05:00
Kyle Spearrin
57ec5cb036 remove android 26 manual install for ci 2017-12-13 09:10:53 -05:00
Alistair Francis
177b48ac90 Add Windows support for QR code scanning (#207)
* UWP: Add support for QR code scanning

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* Pages: ScanPage: Set the close button on Windows

A previous commit mistakenly removed the close button, even though the
scan page is not modal. This means there is no way to navigate away if
running on Windows 10. Revert this change to add a back button.

We need to use a modal page here as we need it to pop up over the entire
view.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-13 08:57:49 -05:00
Alistair Francis
b4e7fd6fa8 Improve the navigation on Windows platforms (#199)
* App: Don't default to modal pushes on Windows

On Windows we generally want to avoid modal pushes as that doesn't give
us a back arrow on Windows 10. Default to non-modal pushes.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: LoginPage.cs: Don't add the cancel button on Windows

With Windows Phone having a HW back buton and the UWP toolbar now
supporting a back button we no longer need a cancel button.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* src: Set a icon for UWP cancel buttons

We can't always use modal pages and in that case we need to set a icon
for UWP otherwise the button can't be seen on the toolbar.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Pages: Don't add Cancel/Close button on Windows

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* Update DismissModalToolBarItem.cs
2017-12-12 16:03:25 -05:00
Alistair Francis
baf785d9f1 App: LoginPage.cs: Use a logo for the login button (#200)
* App: LoginPage.cs: Use a logo for the login button

This adds a helper function which we can use to set logos for Windows
platforms to ensure the user can see the UWP toolbar actions. This won't
have an effect on non-Windows platforms.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Pages: Set an icon for the save button on Windows

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Pages: Set an icon for submit, save and continue

Set an icon for the submit, save and continue buttons when running on
Windows platforms.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Pages: Valut: Set an icon for the edit button

Set the cog icon for the edit button when running on Windows platforms.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-11 15:51:16 -05:00
Kyle Spearrin
25b75fd6e4 make sure PIN doesnt show on screen. adjust focus. 2017-12-11 14:29:50 -05:00
Kyle Spearrin
0c4c8534b4 target sdk 23 2017-12-11 11:38:43 -05:00
Kyle Spearrin
a559dbfe06 remove targetSdkVersion to fix webview jsbridge
ref https://github.com/xamarin/Xamarin.Forms/issues/1376
2017-12-11 11:11:36 -05:00
Alistair Francis
de20bb22d9 App: Use Windows helper instead of WinPhone (#203)
Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-10 23:26:58 -05:00
Kyle Spearrin
45c0ec9035 word wrap name cell 2017-12-08 09:03:44 -05:00
Kyle Spearrin
b16da90e42 disclosure update 2017-12-06 22:45:04 -05:00
Kyle Spearrin
ce7bcfa666 Merge branch 'master' of github.com:bitwarden/mobile 2017-12-06 11:31:54 -05:00
Kyle Spearrin
f6833699a6 null checks 2017-12-06 11:31:41 -05:00
Alistair Francis
040dc72877 Login page fixes (#193)
* App: LoginPage.cs: Correct the Windows device specifier

The WinPhone device specifier doesn't correctly take effect, use the
Windows decvice instead.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: LoginPage.cs: Fix the FormEntryCell imageSource

The images don't appear (at least on UWP) without the file extension.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2017-12-06 10:26:30 -05:00
382 changed files with 14659 additions and 16367 deletions

View File

@@ -6,15 +6,15 @@
<a href="https://play.google.com/store/apps/details?id=com.x8bit.bitwarden" target="_blank"><img alt="Get it on Google Play" src="https://imgur.com/YQzmZi9.png" width="153" height="46"></a> <a href="https://itunes.apple.com/us/app/bitwarden-free-password-manager/id1137397744?mt=8" target="_blank"><img src="https://imgur.com/GdGqPMY.png" width="135" height="40"></a>
The bitwarden mobile application is written in C# with Xamarin Android, Xamarin iOS, and Xamarin Forms.
The bitwarden mobile application is written in C# with Xamarin Android, Xamarin iOS, UWP, and Xamarin Forms.
<img src="https://i.imgur.com/Ty8wkSO.png" alt="" width="300" height="533" /> <img src="https://i.imgur.com/BYb4gVc.png" alt="" width="300" height="533" />
<img src="https://i.imgur.com/R7H2tkQ.png" alt="" width="300" height="533" /> <img src="https://i.imgur.com/3BO1Wcg.png" alt="" width="300" height="533" />
# Build/Run
**Requirements**
- [Visual Studio w/ Xamarin -or- Xamarin Studio](https://store.xamarin.com/)
- [Visual Studio](https://store.xamarin.com/)
By default the app is targeting the production API. If you are running the [Core](https://github.com/bitwarden/core) API locally,
you'll need to switch the app to target your local instance. Open `src/App/Utilities/ApiHttpClient.cs` and `src/App/Utilities/IdentityHttpClient.cs` and set the `BaseAddress` to your local

View File

@@ -1,20 +1,22 @@
init:
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/bitwarden/mobile/master/install-android26.ps1'))
install:
- appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
- appveyor DownloadFile https://aka.ms/vs/15/release/vs_community.exe
- vs_community.exe update --wait --quiet --norestart --installPath "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community"
before_build:
- nuget restore
- IF DEFINED keystore_dec_secret nuget install secure-file -ExcludeVersion
- IF DEFINED google_services_dec_secret secure-file\tools\secure-file -decrypt src\Android\google-services.json.enc -secret %google_services_dec_secret%
after_build:
- ps: IF($env:keystore_dec_secret) { .\src\Android\increment-version.ps1 $($env:APPVEYOR_BUILD_FOLDER) $($env:APPVEYOR_BUILD_NUMBER) }
- IF DEFINED keystore_dec_secret secure-file\tools\secure-file -decrypt src\Android\8bit.keystore.enc -secret %keystore_dec_secret%
- IF DEFINED keystore_password msbuild "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" "/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=%keystore_password%" "/p:AndroidSigningKeyStore=8bit.keystore" "/p:AndroidSigningStorePass=%keystore_password%" "src\Android\Android.csproj"
- ps: IF($env:keystore_dec_secret) { copy-item src\Android\bin\Release\com.x8bit.bitwarden-Signed.apk .\com.x8bit.bitwarden-$($env:APPVEYOR_BUILD_NUMBER).apk }
- ps: IF($env:keystore_dec_secret) { .\src\Android\ci-build-apks.ps1 }
on_success:
- IF DEFINED play_dec_secret secure-file\tools\secure-file -decrypt store\google\Publisher\play_creds.json.enc -secret %play_dec_secret%
- IF DEFINED play_dec_secret store\google\Publisher\bin\Debug\Publisher.exe %APPVEYOR_BUILD_FOLDER%\store\google\Publisher\play_creds.json %APPVEYOR_BUILD_FOLDER%\src\Android\bin\Release\com.x8bit.bitwarden-Signed.apk alpha
- IF DEFINED play_dec_secret dotnet store\google\Publisher\bin\Release\netcoreapp2.0\Publisher.dll %APPVEYOR_BUILD_FOLDER%\store\google\Publisher\play_creds.json %APPVEYOR_BUILD_FOLDER%\com.x8bit.bitwarden-%APPVEYOR_BUILD_NUMBER%.apk alpha
artifacts:
- path: com.x8bit.bitwarden-%APPVEYOR_BUILD_NUMBER%.apk
- path: com.x8bit.bitwarden-fdroid-%APPVEYOR_BUILD_NUMBER%.apk
branches:
except:
- l10n_master
skip_tags: true
configuration: Release
image: Visual Studio 2017

View File

@@ -1,14 +1,12 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2009
VisualStudioVersion = 15.0.27130.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Android", "src\Android\Android.csproj", "{04B18ED2-B76D-4947-8474-191F8FD2B5E0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS", "src\iOS\iOS.csproj", "{1F78403F-9A28-405B-9289-B9DBEB55F074}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "App", "src\App\App.csproj", "{B490C5DA-639E-4994-ABD2-54222B8A348E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0D790714-ECF8-4A83-BE4A-E9C84DD1BB5D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EC730FD9-F623-4B6C-B503-95CDCFBCF277}"
@@ -19,20 +17,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Extension", "src\iOS.Ex
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{B2538ADA-B605-4D6F-ACD2-62A409680F84}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Test", "test\iOS.Test\iOS.Test.csproj", "{6702027A-F726-4149-863E-7CB924674B9A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Android.Test", "test\Android.Test\Android.Test.csproj", "{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "store", "store", "{92470CBD-9047-4C3C-8EA3-D972D6622D84}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "google", "google", "{2E399654-26A2-46F6-B9CA-1B496A3F370A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Publisher", "store\google\Publisher\Publisher.csproj", "{428CACAB-CC26-4F41-9062-1E4A9BC82640}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UWP", "src\UWP\UWP.csproj", "{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "UWP.Images", "src\UWP.Images\UWP.Images.shproj", "{0BE54BBB-7772-4289-BD51-1FDBB0CC2446}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "src\App\App.csproj", "{8A279EE4-4537-4656-9C93-44945E594556}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Publisher", "store\google\Publisher\Publisher.csproj", "{D5D91152-CB01-4F24-A503-304D3A94408B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F0E2E596-C3DB-474A-9C88-7824662894FA}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
@@ -66,6 +62,12 @@ Global
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
FDroid|Any CPU = FDroid|Any CPU
FDroid|ARM = FDroid|ARM
FDroid|iPhone = FDroid|iPhone
FDroid|iPhoneSimulator = FDroid|iPhoneSimulator
FDroid|x64 = FDroid|x64
FDroid|x86 = FDroid|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|iPhone = Release|iPhone
@@ -114,6 +116,24 @@ Global
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|x86.ActiveCfg = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|x86.Build.0 = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|x86.Deploy.0 = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|Any CPU.Deploy.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|ARM.ActiveCfg = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|ARM.Build.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|ARM.Deploy.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhone.Build.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhone.Deploy.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhoneSimulator.Deploy.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x64.ActiveCfg = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x64.Build.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x64.Deploy.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x86.ActiveCfg = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x86.Build.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x86.Deploy.0 = FDroid|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|Any CPU.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|Any CPU.Deploy.0 = Release|Any CPU
@@ -153,6 +173,18 @@ Global
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|x64.ActiveCfg = Debug|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|x86.ActiveCfg = Debug|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|x86.Build.0 = Debug|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|Any CPU.ActiveCfg = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|Any CPU.Build.0 = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|ARM.ActiveCfg = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|ARM.Build.0 = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|iPhone.ActiveCfg = Release|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|iPhone.Build.0 = Release|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|x64.ActiveCfg = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|x64.Build.0 = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|x86.ActiveCfg = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|x86.Build.0 = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|Any CPU.ActiveCfg = Release|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|ARM.ActiveCfg = Release|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|iPhone.ActiveCfg = Release|iPhone
@@ -161,54 +193,6 @@ Global
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|x64.ActiveCfg = Release|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|x86.ActiveCfg = Release|iPhone
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|Any CPU.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|ARM.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|ARM.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|iPhone.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|x64.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|x64.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|x86.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.AppStore|x86.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|ARM.Build.0 = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|iPhone.Build.0 = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|x64.ActiveCfg = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|x64.Build.0 = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|x86.ActiveCfg = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Debug|x86.Build.0 = Debug|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|Any CPU.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|ARM.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|ARM.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|iPhone.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|iPhone.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|x64.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|x64.Build.0 = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|x86.ActiveCfg = Release|Any CPU
{B490C5DA-639E-4994-ABD2-54222B8A348E}.Release|x86.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
@@ -238,6 +222,18 @@ Global
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|x64.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|x86.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|x86.Build.0 = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|Any CPU.Build.0 = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|ARM.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|ARM.Build.0 = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|iPhone.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|iPhone.Build.0 = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|iPhoneSimulator.Build.0 = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|x64.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|x64.Build.0 = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|x86.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|x86.Build.0 = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|Any CPU.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|ARM.ActiveCfg = Release|Any CPU
@@ -273,6 +269,18 @@ Global
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|x64.ActiveCfg = Debug|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|x86.ActiveCfg = Debug|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|x86.Build.0 = Debug|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|Any CPU.ActiveCfg = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|Any CPU.Build.0 = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|ARM.ActiveCfg = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|ARM.Build.0 = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|iPhone.ActiveCfg = Release|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|iPhone.Build.0 = Release|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|x64.ActiveCfg = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|x64.Build.0 = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|x86.ActiveCfg = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|x86.Build.0 = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|Any CPU.ActiveCfg = Release|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|ARM.ActiveCfg = Release|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|iPhone.ActiveCfg = Release|iPhone
@@ -314,6 +322,18 @@ Global
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|x64.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|x86.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|x86.Build.0 = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|Any CPU.Build.0 = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|ARM.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|ARM.Build.0 = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|iPhone.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|iPhone.Build.0 = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|iPhoneSimulator.Build.0 = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|x64.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|x64.Build.0 = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|x86.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|x86.Build.0 = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|ARM.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|iPhone.ActiveCfg = Release|Any CPU
@@ -324,155 +344,6 @@ Global
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x64.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x86.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x86.Build.0 = Release|Any CPU
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|ARM.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|iPhone.Build.0 = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|x64.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|x86.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|ARM.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|iPhone.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|iPhone.Build.0 = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|x64.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|x86.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|Any CPU.ActiveCfg = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|ARM.ActiveCfg = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|iPhone.ActiveCfg = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|iPhone.Build.0 = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Release|x64.ActiveCfg = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|x86.ActiveCfg = Release|iPhone
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|ARM.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|x64.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Ad-Hoc|x86.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|Any CPU.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|ARM.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|ARM.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|ARM.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|iPhone.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|iPhone.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|x64.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|x64.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|x64.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|x86.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|x86.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.AppStore|x86.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|ARM.ActiveCfg = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|ARM.Build.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|ARM.Deploy.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|iPhone.Build.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|iPhone.Deploy.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|x64.ActiveCfg = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|x86.ActiveCfg = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|x86.Build.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Debug|x86.Deploy.0 = Debug|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|Any CPU.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|Any CPU.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|ARM.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|ARM.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|ARM.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|iPhone.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|iPhone.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|iPhone.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|x64.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|x64.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|x64.Deploy.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|x86.ActiveCfg = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|x86.Build.0 = Release|Any CPU
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE}.Release|x86.Deploy.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|Any CPU.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|ARM.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|ARM.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|iPhone.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|x64.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|x64.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|x86.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.AppStore|x86.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|Any CPU.Build.0 = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|ARM.ActiveCfg = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|ARM.Build.0 = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|iPhone.Build.0 = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|x64.ActiveCfg = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|x86.ActiveCfg = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Debug|x86.Build.0 = Debug|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|Any CPU.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|Any CPU.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|ARM.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|ARM.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|iPhone.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|iPhone.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|x64.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|x64.Build.0 = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|x86.ActiveCfg = Release|Any CPU
{428CACAB-CC26-4F41-9062-1E4A9BC82640}.Release|x86.Build.0 = Release|Any CPU
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|Any CPU.ActiveCfg = Release|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|Any CPU.Build.0 = Release|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|Any CPU.Deploy.0 = Release|x64
@@ -521,6 +392,24 @@ Global
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|x86.ActiveCfg = Debug|x86
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|x86.Build.0 = Debug|x86
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|x86.Deploy.0 = Debug|x86
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|Any CPU.ActiveCfg = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|Any CPU.Build.0 = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|Any CPU.Deploy.0 = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|ARM.ActiveCfg = Debug|ARM
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|ARM.Build.0 = Debug|ARM
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|ARM.Deploy.0 = Debug|ARM
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|iPhone.ActiveCfg = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|iPhone.Build.0 = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|iPhone.Deploy.0 = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|iPhoneSimulator.ActiveCfg = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|iPhoneSimulator.Build.0 = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|iPhoneSimulator.Deploy.0 = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|x64.ActiveCfg = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|x64.Build.0 = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|x64.Deploy.0 = Debug|x64
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|x86.ActiveCfg = Debug|x86
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|x86.Build.0 = Debug|x86
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.FDroid|x86.Deploy.0 = Debug|x86
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|Any CPU.ActiveCfg = Release|x86
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|ARM.ActiveCfg = Release|ARM
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|ARM.Build.0 = Release|ARM
@@ -533,6 +422,126 @@ Global
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|x86.ActiveCfg = Release|x86
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|x86.Build.0 = Release|x86
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|x86.Deploy.0 = Release|x86
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|ARM.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|iPhone.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|x64.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|x64.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|x86.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|x86.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|ARM.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|iPhone.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|x64.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|x64.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|x86.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|x86.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|ARM.ActiveCfg = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|ARM.Build.0 = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|iPhone.Build.0 = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|x64.ActiveCfg = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|x64.Build.0 = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|x86.ActiveCfg = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|x86.Build.0 = FDroid|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|Any CPU.Build.0 = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|ARM.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|ARM.Build.0 = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|iPhone.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|iPhone.Build.0 = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|x64.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|x64.Build.0 = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|x86.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|x86.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|ARM.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|iPhone.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|x64.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|x64.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|x86.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|x86.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|ARM.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|iPhone.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|x64.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|x64.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|x86.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|x86.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|Any CPU.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|ARM.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|ARM.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|iPhone.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|iPhone.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|x64.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|x64.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|x86.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|x86.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|Any CPU.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|ARM.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|ARM.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|iPhone.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|iPhone.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x64.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x64.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x86.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -540,16 +549,14 @@ Global
GlobalSection(NestedProjects) = preSolution
{04B18ED2-B76D-4947-8474-191F8FD2B5E0} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{1F78403F-9A28-405B-9289-B9DBEB55F074} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{B490C5DA-639E-4994-ABD2-54222B8A348E} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{A300DCE1-8D10-4267-B96A-CB01AEB7C220} = {0D790714-ECF8-4A83-BE4A-E9C84DD1BB5D}
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{B2538ADA-B605-4D6F-ACD2-62A409680F84} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{6702027A-F726-4149-863E-7CB924674B9A} = {0D790714-ECF8-4A83-BE4A-E9C84DD1BB5D}
{FA507A17-D4E3-46DF-ACD8-D7E6D7D4E3AE} = {0D790714-ECF8-4A83-BE4A-E9C84DD1BB5D}
{2E399654-26A2-46F6-B9CA-1B496A3F370A} = {92470CBD-9047-4C3C-8EA3-D972D6622D84}
{428CACAB-CC26-4F41-9062-1E4A9BC82640} = {2E399654-26A2-46F6-B9CA-1B496A3F370A}
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{0BE54BBB-7772-4289-BD51-1FDBB0CC2446} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{8A279EE4-4537-4656-9C93-44945E594556} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{D5D91152-CB01-4F24-A503-304D3A94408B} = {2E399654-26A2-46F6-B9CA-1B496A3F370A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {318CB2DF-0118-43A3-AC83-56BADCF71CCD}

View File

@@ -7,14 +7,6 @@ files:
zh-TW: zh-Hant
pt-PT: pt-PT
pt-BR: pt-BR
- source: /store/amazon/en/copy.resx
translation: /store/amazon/%two_letters_code%/copy.resx
languages_mapping:
two_letters_code:
zh-CN: zh-Hans
zh-TW: zh-Hant
pt-PT: pt-PT
pt-BR: pt-BR
- source: /store/apple/en/copy.resx
translation: /store/apple/%two_letters_code%/copy.resx
languages_mapping:

View File

@@ -1,30 +0,0 @@
$AndroidToolPath = "${env:ProgramFiles(x86)}\Android\android-sdk\tools\android"
Function Get-AndroidSDKs() {
$output = & $AndroidToolPath list sdk --all
$sdks = $output |% {
if ($_ -match '(?<index>\d+)- (?<sdk>.+), revision (?<revision>[\d\.]+)') {
$sdk = New-Object PSObject
Add-Member -InputObject $sdk -MemberType NoteProperty -Name Index -Value $Matches.index
Add-Member -InputObject $sdk -MemberType NoteProperty -Name Name -Value $Matches.sdk
Add-Member -InputObject $sdk -MemberType NoteProperty -Name Revision -Value $Matches.revision
$sdk
}
}
$sdks
}
Function Install-AndroidSDK() {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true, Position=0)]
[PSObject[]]$sdks
)
$sdkIndexes = $sdks |% { $_.Index }
$sdkIndexArgument = [string]::Join(',', $sdkIndexes)
Echo 'y' | & $AndroidToolPath update sdk -u -a -t $sdkIndexArgument
}
# install android 26
$sdks = Get-AndroidSDKs |? { $_.name -like 'sdk platform*API 26*' }
Install-AndroidSDK -sdks $sdks

Binary file not shown.

View File

@@ -3,8 +3,6 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{04B18ED2-B76D-4947-8474-191F8FD2B5E0}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
@@ -48,6 +46,7 @@
<AotAssemblies>False</AotAssemblies>
<EnableLLVM>False</EnableLLVM>
<EnableProguard>False</EnableProguard>
<AndroidTlsProvider>btls</AndroidTlsProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -71,222 +70,46 @@
<AndroidLinkSkip>PushNotification.Plugin;PushNotification.Plugin.Abstractions;Xamarin.GooglePlayServices.Base;Xamarin.GooglePlayServices.Basement;Xamarin.GooglePlayServices.Measurement;Xamarin.GooglePlayServices.Gcm;BitwardenAndroid;BitwardenApp;SQLite-net;Xamarin.Android.Net</AndroidLinkSkip>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
<AndroidSupportedAbis>armeabi;armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
<AndroidTlsProvider>btls</AndroidTlsProvider>
<AndroidApkSigningAlgorithm>SHA1withRSA</AndroidApkSigningAlgorithm>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'FDroid|AnyCPU'">
<OutputPath>bin\FDroid\</OutputPath>
<DefineConstants>TRACE;FDROID</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
<AndroidLinkMode>Full</AndroidLinkMode>
<AndroidLinkSkip>BitwardenAndroid;BitwardenApp;SQLite-net;Xamarin.Android.Net</AndroidLinkSkip>
<AndroidTlsProvider>btls</AndroidTlsProvider>
<AndroidSupportedAbis>armeabi;armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
<AndroidApkSigningAlgorithm>SHA1withRSA</AndroidApkSigningAlgorithm>
</PropertyGroup>
<ItemGroup>
<Reference Include="Acr.Support.Android, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Acr.Support.2.1.0\lib\MonoAndroid10\Acr.Support.Android.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Acr.UserDialogs, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Acr.UserDialogs.6.3.10\lib\MonoAndroid10\Acr.UserDialogs.dll</HintPath>
</Reference>
<Reference Include="Acr.UserDialogs.Interface, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Acr.UserDialogs.6.3.10\lib\MonoAndroid10\Acr.UserDialogs.Interface.dll</HintPath>
</Reference>
<Reference Include="AndHUD, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\AndHUD.1.2.0\lib\MonoAndroid\AndHUD.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
<HintPath>..\..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FFImageLoading, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.FFImageLoading.2.2.9\lib\MonoAndroid10\FFImageLoading.dll</HintPath>
</Reference>
<Reference Include="FFImageLoading.Forms, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.FFImageLoading.Forms.2.2.9\lib\MonoAndroid10\FFImageLoading.Forms.dll</HintPath>
</Reference>
<Reference Include="FFImageLoading.Forms.Droid, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.FFImageLoading.Forms.2.2.9\lib\MonoAndroid10\FFImageLoading.Forms.Droid.dll</HintPath>
</Reference>
<Reference Include="FFImageLoading.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.FFImageLoading.2.2.9\lib\MonoAndroid10\FFImageLoading.Platform.dll</HintPath>
</Reference>
<Reference Include="FormsViewGroup, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.4.267\lib\MonoAndroid10\FormsViewGroup.dll</HintPath>
</Reference>
<Reference Include="HockeySDK, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\HockeySDK.Xamarin.4.1.5\lib\MonoAndroid403\HockeySDK.dll</HintPath>
</Reference>
<Reference Include="HockeySDK.AndroidBindings, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\HockeySDK.Xamarin.4.1.5\lib\MonoAndroid403\HockeySDK.AndroidBindings.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Practices.ServiceLocation, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Mono.Android" />
<Reference Include="Mono.Android.Export" />
<Reference Include="mscorlib" />
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PCLCrypto, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d4421c8a4786956c, processorArchitecture=MSIL">
<HintPath>..\..\packages\PCLCrypto.2.0.147\lib\MonoAndroid23\PCLCrypto.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PInvoke.BCrypt, Version=0.5.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.BCrypt.0.5.97\lib\portable-net45+win8+wpa81\PInvoke.BCrypt.dll</HintPath>
</Reference>
<Reference Include="PInvoke.Kernel32, Version=0.5.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.Kernel32.0.5.97\lib\portable-net45+win8+wpa81\PInvoke.Kernel32.dll</HintPath>
</Reference>
<Reference Include="PInvoke.NCrypt, Version=0.5.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.NCrypt.0.5.97\lib\portable-net45+win8+wpa81\PInvoke.NCrypt.dll</HintPath>
</Reference>
<Reference Include="PInvoke.Windows.Core, Version=0.5.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.Windows.Core.0.5.97\lib\portable-net45+win8+wpa81\PInvoke.Windows.Core.dll</HintPath>
</Reference>
<Reference Include="Plugin.Connectivity, Version=3.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugin.Connectivity.3.0.2\lib\MonoAndroid10\Plugin.Connectivity.dll</HintPath>
</Reference>
<Reference Include="Plugin.Connectivity.Abstractions, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugin.Connectivity.3.0.2\lib\MonoAndroid10\Plugin.Connectivity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Plugin.CurrentActivity, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Plugin.CurrentActivity.1.0.1\lib\MonoAndroid10\Plugin.CurrentActivity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.Fingerprint, Version=1.4.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Plugin.Fingerprint.1.4.6-beta4\lib\MonoAndroid\Plugin.Fingerprint.dll</HintPath>
</Reference>
<Reference Include="Plugin.Fingerprint.Abstractions, Version=1.4.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Plugin.Fingerprint.1.4.6-beta4\lib\MonoAndroid\Plugin.Fingerprint.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Plugin.Fingerprint.Android.Samsung, Version=1.4.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Plugin.Fingerprint.1.4.6-beta4\lib\MonoAndroid\Plugin.Fingerprint.Android.Samsung.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugins.Settings.3.0.1\lib\MonoAndroid10\Plugin.Settings.dll</HintPath>
</Reference>
<Reference Include="Plugin.Settings.Abstractions, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugins.Settings.3.0.1\lib\MonoAndroid10\Plugin.Settings.Abstractions.dll</HintPath>
</Reference>
<Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\..\packages\SimpleInjector.4.0.8\lib\netstandard1.3\SimpleInjector.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Splat.1.6.2\lib\monoandroid\Splat.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SQLite-net, Version=1.5.166.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\sqlite-net-pcl.1.5.166-beta\lib\netstandard1.1\SQLite-net.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.batteries_green, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a84b7dcfb1391f7f, processorArchitecture=MSIL">
<HintPath>..\..\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\MonoAndroid\SQLitePCLRaw.batteries_green.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.batteries_v2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8226ea5df37bcae9, processorArchitecture=MSIL">
<HintPath>..\..\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\MonoAndroid\SQLitePCLRaw.batteries_v2.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1488e028ca7ab535, processorArchitecture=MSIL">
<HintPath>..\..\packages\SQLitePCLRaw.core.1.1.8\lib\MonoAndroid\SQLitePCLRaw.core.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.lib.e_sqlite3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e4ad490600e2234c, processorArchitecture=MSIL">
<HintPath>..\..\packages\SQLitePCLRaw.lib.e_sqlite3.android.1.1.8\lib\MonoAndroid\SQLitePCLRaw.lib.e_sqlite3.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.provider.e_sqlite3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9c301db686d0bd12, processorArchitecture=MSIL">
<HintPath>..\..\packages\SQLitePCLRaw.provider.e_sqlite3.android.1.1.8\lib\MonoAndroid\SQLitePCLRaw.provider.e_sqlite3.dll</HintPath>
<Reference Include="Naxam.Ittianyu.BottomNavExtension, Version=1.2.2.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>.\Naxam.Ittianyu.BottomNavExtension.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Net.Http" />
<Reference Include="Validation, Version=2.3.0.0, Culture=neutral, PublicKeyToken=2fc06f0d701809a7, processorArchitecture=MSIL">
<HintPath>..\..\packages\Validation.2.3.7\lib\dotnet\Validation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Android.Support.Animated.Vector.Drawable, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Animated.Vector.Drawable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Android.Support.Design, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Android.Support.Design.23.3.0\lib\MonoAndroid43\Xamarin.Android.Support.Design.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Android.Support.v4, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Android.Support.v4.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Android.Support.v7.AppCompat, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Android.Support.v7.AppCompat.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.AppCompat.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Android.Support.v7.CardView, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Android.Support.v7.CardView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.CardView.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Android.Support.v7.MediaRouter, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Android.Support.v7.MediaRouter.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.MediaRouter.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Android.Support.v7.RecyclerView, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Android.Support.v7.RecyclerView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.RecyclerView.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Android.Support.Vector.Drawable, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Vector.Drawable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.4.267\lib\MonoAndroid10\Xamarin.Forms.Core.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.4.267\lib\MonoAndroid10\Xamarin.Forms.Platform.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Platform.Android, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.4.267\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.4.267\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll</HintPath>
</Reference>
<Reference Include="Xamarin.GooglePlayServices.Analytics, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.GooglePlayServices.Analytics.29.0.0.2\lib\MonoAndroid41\Xamarin.GooglePlayServices.Analytics.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.GooglePlayServices.Base, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.GooglePlayServices.Base.29.0.0.2\lib\MonoAndroid41\Xamarin.GooglePlayServices.Base.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.GooglePlayServices.Basement, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.GooglePlayServices.Basement.29.0.0.2\lib\MonoAndroid41\Xamarin.GooglePlayServices.Basement.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.GooglePlayServices.Gcm, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.GooglePlayServices.Gcm.29.0.0.2\lib\MonoAndroid41\Xamarin.GooglePlayServices.Gcm.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.GooglePlayServices.Measurement, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.GooglePlayServices.Measurement.29.0.0.2\lib\MonoAndroid41\Xamarin.GooglePlayServices.Measurement.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="XLabs.Ioc, Version=2.0.5782.12218, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\XLabs.IoC.2.0.5782\lib\portable-net45+netcore45+wp8+MonoAndroid1+MonoTouch1\XLabs.Ioc.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="XLabs.Ioc.SimpleInjector, Version=2.0.5782.12229, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\XLabs.IoC.SimpleInjector.2.0.5782\lib\portable-net45+netcore45+wp8+MonoAndroid1+MonoTouch1\XLabs.Ioc.SimpleInjector.dll</HintPath>
</Reference>
<Reference Include="ZXing.Net.Mobile.Core, Version=2.1.47.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\ZXing.Net.Mobile.2.1.47\lib\MonoAndroid403\ZXing.Net.Mobile.Core.dll</HintPath>
</Reference>
<Reference Include="ZXing.Net.Mobile.Forms, Version=2.1.47.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\ZXing.Net.Mobile.Forms.2.1.47\lib\MonoAndroid403\ZXing.Net.Mobile.Forms.dll</HintPath>
</Reference>
<Reference Include="ZXing.Net.Mobile.Forms.Android, Version=2.1.47.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\ZXing.Net.Mobile.Forms.2.1.47\lib\MonoAndroid403\ZXing.Net.Mobile.Forms.Android.dll</HintPath>
</Reference>
<Reference Include="zxing.portable, Version=2.1.47.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\ZXing.Net.Mobile.2.1.47\lib\MonoAndroid403\zxing.portable.dll</HintPath>
</Reference>
<Reference Include="ZXingNetMobile, Version=2.1.47.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\ZXing.Net.Mobile.2.1.47\lib\MonoAndroid403\ZXingNetMobile.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AutofillActivity.cs" />
<Compile Include="AutofillCredentials.cs" />
<Compile Include="Controls\CustomSliderRenderer.cs" />
<Compile Include="Controls\ExtendedListViewRenderer.cs" />
<Compile Include="FirebaseInstanceIdService.cs" />
<Compile Include="FirebaseMessagingService.cs" />
<Compile Include="Autofill\Field.cs" />
<Compile Include="Autofill\FieldCollection.cs" />
<Compile Include="Autofill\AutofillService.cs" />
@@ -309,22 +132,20 @@
<Compile Include="Controls\ExtendedPickerRenderer.cs" />
<Compile Include="Controls\ExtendedEntryRenderer.cs" />
<Compile Include="MyVaultTileService.cs" />
<Compile Include="Services\AndroidPushNotificationService.cs" />
<Compile Include="Services\GoogleAnalyticsService.cs" />
<Compile Include="Services\HttpService.cs" />
<Compile Include="Services\AndroidKeyStoreStorageService.cs" />
<Compile Include="Services\LocalizeService.cs" />
<Compile Include="MainApplication.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Services\DeviceInfoService.cs" />
<Compile Include="Services\GoogleAnalyticsService.cs" />
<Compile Include="Services\AppInfoService.cs" />
<Compile Include="Services\DeviceActionService.cs" />
<Compile Include="Services\BouncyCastleKeyDerivationService.cs" />
<Compile Include="MainActivity.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\LogService.cs" />
<Compile Include="Services\MemoryService.cs" />
<Compile Include="Services\AndroidPushNotificationService.cs" />
<Compile Include="Services\ReflectionService.cs" />
<Compile Include="Services\SqlService.cs" />
<Compile Include="SplashActivity.cs" />
<Compile Include="PackageReplacedReceiver.cs" />
@@ -333,15 +154,14 @@
</ItemGroup>
<ItemGroup>
<None Include="8bit.keystore.enc" />
<None Include="app.config">
<SubType>Designer</SubType>
</None>
<None Include="increment-version.ps1" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
<GoogleServicesJson Include="google-services.json" />
<None Include="ci-build-apks.ps1" />
<None Include="google-services.json.enc" />
<None Include="Resources\AboutResources.txt" />
<None Include="Assets\AboutAssets.txt" />
<AndroidResource Include="Resources\drawable\slider_thumb.xml">
<SubType>Designer</SubType>
</AndroidResource>
<AndroidResource Include="Resources\layout\tabs.axml">
<SubType>AndroidResource</SubType>
</AndroidResource>
@@ -355,12 +175,6 @@
<ItemGroup>
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\App\App.csproj">
<Project>{b490c5da-639e-4994-abd2-54222b8a348e}</Project>
<Name>App</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\values-v21\styles.xml" />
</ItemGroup>
@@ -610,66 +424,6 @@
<ItemGroup>
<AndroidResource Include="Resources\drawable\splash_screen.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\tools_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\cogs_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\fa_lock_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\star_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\fa_lock_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\star_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\cogs_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\cogs_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\fa_lock_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\star_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\cogs_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\fa_lock_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\star_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\fa_lock_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\star_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\cogs_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\tools_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\tools_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\tools_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\tools_selected.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\cogs.png" />
</ItemGroup>
@@ -685,36 +439,21 @@
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\cogs.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\star.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\fa_lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\star.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\fa_lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\star.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\fa_lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\star.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\fa_lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\fa_lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\star.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\tools.png" />
</ItemGroup>
@@ -919,9 +658,6 @@
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\paperclip.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\trash.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\trash.png" />
</ItemGroup>
@@ -1129,23 +865,46 @@
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\autofill_use.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\App\App.csproj">
<Project>{8a279ee4-4537-4656-9c93-44945e594556}</Project>
<Name>App</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Firebase.Messaging">
<Version>42.1021.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.GooglePlayServices.Analytics">
<Version>42.1021.1</Version>
</PackageReference>
<PackageReference Include="SimpleInjector">
<Version>4.0.12</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat">
<Version>25.4.0.2</Version>
</PackageReference>
<PackageReference Include="XLabs.IoC.SimpleInjector" Version="2.0.5782" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.3" />
<PackageReference Include="Plugin.CurrentActivity" Version="1.0.1" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\bottom_nav_bg.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\pencil.png" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<Import Project="..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets" Condition="Exists('..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\build\Xamarin.Android.Support.Vector.Drawable.targets'))" />
<Error Condition="!Exists('..\..\packages\Xamarin.GooglePlayServices.Basement.29.0.0.2\build\Xamarin.GooglePlayServices.Basement.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.GooglePlayServices.Basement.29.0.0.2\build\Xamarin.GooglePlayServices.Basement.targets'))" />
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.2.3.4.267\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.2.3.4.267\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets'))" />
</Target>
<Import Project="..\..\packages\Xamarin.GooglePlayServices.Basement.29.0.0.2\build\Xamarin.GooglePlayServices.Basement.targets" Condition="Exists('..\..\packages\Xamarin.GooglePlayServices.Basement.29.0.0.2\build\Xamarin.GooglePlayServices.Basement.targets')" />
<Import Project="..\..\packages\Xamarin.Forms.2.3.4.267\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.2.3.4.267\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -88,7 +88,10 @@ namespace Bit.Android.Autofill
switch(savedItem.Type)
{
case CipherType.Login:
intent.PutExtra("autofillFrameworkName", parser.Uri.Replace(Constants.AndroidAppProtocol, string.Empty));
intent.PutExtra("autofillFrameworkName", parser.Uri
.Replace(Constants.AndroidAppProtocol, string.Empty)
.Replace("https://", string.Empty)
.Replace("http://", string.Empty));
intent.PutExtra("autofillFrameworkUri", parser.Uri);
intent.PutExtra("autofillFrameworkUsername", savedItem.Login.Username);
intent.PutExtra("autofillFrameworkPassword", savedItem.Login.Password);

View File

@@ -5,6 +5,7 @@ using Android.Views;
using Android.Views.Autofill;
using static Android.App.Assist.AssistStructure;
using Android.Text;
using static Android.Views.ViewStructure;
namespace Bit.Android.Autofill
{
@@ -24,7 +25,9 @@ namespace Bit.Android.Autofill
Clickable = node.IsClickable;
Visible = node.Visibility == ViewStates.Visible;
Hints = FilterForSupportedHints(node.GetAutofillHints());
Hint = node.Hint;
AutofillOptions = node.GetAutofillOptions()?.ToList();
HtmlInfo = node.HtmlInfo;
Node = node;
if(node.AutofillValue != null)
@@ -63,6 +66,7 @@ namespace Bit.Android.Autofill
UpdateSaveTypeFromHints();
}
}
public string Hint { get; set; }
public int Id { get; private set; }
public string IdEntry { get; set; }
public AutofillId AutofillId { get; private set; }
@@ -77,6 +81,7 @@ namespace Bit.Android.Autofill
public long? DateValue { get; set; }
public int? ListValue { get; set; }
public bool? ToggleValue { get; set; }
public HtmlInfo HtmlInfo { get; private set; }
public ViewNode Node { get; private set; }
private void UpdateSaveTypeFromHints()

View File

@@ -59,9 +59,9 @@ namespace Bit.Android.Autofill
else
{
_passwordFields = Fields
.Where(f =>
!f.IdEntry.ToLowerInvariant().Contains("search") &&
(!f.Node.Hint?.ToLowerInvariant().Contains("search") ?? true) &&
.Where(f =>
(!f.IdEntry?.ToLowerInvariant().Contains("search") ?? true) &&
(!f.Hint?.ToLowerInvariant().Contains("search") ?? true) &&
(
f.InputType.HasFlag(InputTypes.TextVariationPassword) ||
f.InputType.HasFlag(InputTypes.TextVariationVisiblePassword) ||
@@ -70,7 +70,9 @@ namespace Bit.Android.Autofill
).ToList();
if(!_passwordFields.Any())
{
_passwordFields = Fields.Where(f => f.IdEntry?.ToLower().Contains("password") ?? false).ToList();
_passwordFields = Fields.Where(f =>
(f.IdEntry?.ToLowerInvariant().Contains("password") ?? false)
|| (f.Hint?.ToLowerInvariant().Contains("password") ?? false)).ToList();
}
}
@@ -103,7 +105,7 @@ namespace Bit.Android.Autofill
{
foreach(var passwordField in PasswordFields)
{
var usernameField = Fields.TakeWhile(f => f.Id != passwordField.Id).LastOrDefault();
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId).LastOrDefault();
if(usernameField != null)
{
_usernameFields.Add(usernameField);
@@ -136,10 +138,14 @@ namespace Bit.Android.Autofill
_passwordFields = _usernameFields = null;
Ids.Add(field.Id);
if(field.Id > -1)
{
Ids.Add(field.Id);
IdToFieldMap.Add(field.Id, field);
}
Fields.Add(field);
AutofillIds.Add(field.AutofillId);
IdToFieldMap.Add(field.Id, field);
if(field.Hints != null)
{
@@ -180,7 +186,7 @@ namespace Bit.Android.Autofill
}
};
var usernameField = Fields.TakeWhile(f => f.Id != passwordField.Id).LastOrDefault();
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId).LastOrDefault();
savedItem.Login.Username = GetFieldValue(usernameField);
return savedItem;

View File

@@ -1,14 +1,31 @@
using static Android.App.Assist.AssistStructure;
using Android.App.Assist;
using Bit.App;
using System.Collections.Generic;
namespace Bit.Android.Autofill
{
public class Parser
{
public static HashSet<string> TrustedBrowsers = new HashSet<string>
{
"org.mozilla.focus","org.mozilla.firefox","org.mozilla.firefox_beta","com.microsoft.emmx",
"com.android.chrome","com.chrome.beta","com.android.browser","com.brave.browser","com.opera.browser",
"com.opera.browser.beta","com.opera.mini.native","com.chrome.dev","com.chrome.canary",
"com.google.android.apps.chrome","com.google.android.apps.chrome_dev","com.yandex.browser",
"com.sec.android.app.sbrowser","com.sec.android.app.sbrowser.beta","org.codeaurora.swe.browser",
"com.amazon.cloud9","org.mozilla.klar", "com.duckduckgo.mobile.android"
};
public static HashSet<string> ExcludedPackageIds = new HashSet<string>
{
"android"
};
private readonly AssistStructure _structure;
private string _uri;
private string _packageName;
private string _webDomain;
public Parser(AssistStructure structure)
{
@@ -25,10 +42,14 @@ namespace Bit.Android.Autofill
return _uri;
}
if(string.IsNullOrWhiteSpace(PackageName))
if(string.IsNullOrWhiteSpace(WebDomain) && string.IsNullOrWhiteSpace(PackageName))
{
_uri = null;
}
else if(!string.IsNullOrWhiteSpace(WebDomain))
{
_uri = string.Concat("http://", WebDomain);
}
else
{
_uri = string.Concat(Constants.AndroidAppProtocol, PackageName);
@@ -50,6 +71,19 @@ namespace Bit.Android.Autofill
_packageName = value;
}
}
public string WebDomain
{
get => _webDomain;
set
{
if(string.IsNullOrWhiteSpace(value))
{
_webDomain = _uri = null;
}
_webDomain = value;
}
}
public void Parse()
{
@@ -58,18 +92,20 @@ namespace Bit.Android.Autofill
var node = _structure.GetWindowNodeAt(i);
ParseNode(node.RootViewNode);
}
if(!TrustedBrowsers.Contains(PackageName))
{
WebDomain = null;
}
}
private void ParseNode(ViewNode node)
{
SetPackageAndDomain(node);
var hints = node.GetAutofillHints();
var isEditText = node.ClassName == "android.widget.EditText";
var isEditText = node.ClassName == "android.widget.EditText" || node?.HtmlInfo?.Tag == "input";
if(isEditText || (hints?.Length ?? 0) > 0)
{
if(PackageName == null)
{
PackageName = node.IdPackage;
}
FieldCollection.Add(new Field(node));
}
else
@@ -82,5 +118,18 @@ namespace Bit.Android.Autofill
ParseNode(node.GetChildAt(i));
}
}
private void SetPackageAndDomain(ViewNode node)
{
if(string.IsNullOrWhiteSpace(PackageName) && !string.IsNullOrWhiteSpace(node.IdPackage) &&
!ExcludedPackageIds.Contains(node.IdPackage))
{
PackageName = node.IdPackage;
}
if(string.IsNullOrWhiteSpace(WebDomain) && !string.IsNullOrWhiteSpace(node.WebDomain))
{
WebDomain = node.WebDomain;
}
}
}
}

View File

@@ -19,6 +19,7 @@ namespace Bit.Android
{
private NotificationChannel _notificationChannel;
private const string BitwardenTag = "bw_access";
private const int AutoFillNotificationId = 34573;
private const string SystemUiPackage = "com.android.systemui";
private const string BitwardenPackage = "com.x8bit.bitwarden";
@@ -42,10 +43,11 @@ namespace Bit.Android
new Browser("com.sec.android.app.sbrowser", "location_bar_edit_text"),
new Browser("com.sec.android.app.sbrowser.beta", "location_bar_edit_text"),
new Browser("com.yandex.browser", "bro_omnibar_address_title_text",
(s) => s.Split(' ').FirstOrDefault()),
(s) => s.Split(new char[]{' ', '<27>'}).FirstOrDefault()), // 0 = Regular Space, 1 = No-break space (00A0)
new Browser("org.mozilla.firefox", "url_bar_title"),
new Browser("org.mozilla.firefox_beta", "url_bar_title"),
new Browser("org.mozilla.focus", "display_url"),
new Browser("org.mozilla.klar", "display_url"),
new Browser("com.ghostery.android.ghostery", "search_field"),
new Browser("org.adblockplus.browser", "url_bar_title"),
new Browser("com.htc.sense.browser", "title"),
@@ -59,12 +61,36 @@ namespace Bit.Android
new Browser("com.ksmobile.cb", "address_bar_edit_text"),
new Browser("acr.browser.lightning", "search"),
new Browser("acr.browser.barebones", "search"),
new Browser("com.microsoft.emmx", "url_bar")
new Browser("com.microsoft.emmx", "url_bar"),
new Browser("com.duckduckgo.mobile.android", "omnibarTextInput")
}.ToDictionary(n => n.PackageName);
// Known packages to skip
private static HashSet<string> FilteredPackageNames => new HashSet<string>
{
SystemUiPackage,
"com.google.android.googlequicksearchbox",
"com.google.android.apps.nexuslauncher",
"com.google.android.launcher",
"com.computer.desktop.ui.launcher",
"com.launcher.notelauncher",
"com.anddoes.launcher",
"com.actionlauncher.playstore",
"ch.deletescape.lawnchair.plah",
"com.microsoft.launcher",
"com.teslacoilsw.launcher",
"com.teslacoilsw.launcher.prime",
"is.shortcut",
"me.craftsapp.nlauncher",
"com.ss.squarehome2"
};
private readonly IAppSettingsService _appSettings;
private long _lastNotificationTime = 0;
private string _lastNotificationUri = null;
private HashSet<string> _launcherPackageNames = null;
private DateTime? _lastLauncherSetBuilt = null;
private TimeSpan _rebuildLauncherSpan = TimeSpan.FromHours(1);
public AutofillService()
{
@@ -85,10 +111,13 @@ namespace Bit.Android
try
{
if(SkipPackage(e?.PackageName))
{
return;
}
var root = RootInActiveWindow;
if(e == null || root == null || string.IsNullOrWhiteSpace(e.PackageName) ||
e.PackageName == SystemUiPackage || e.PackageName.Contains("launcher") ||
root.PackageName != e.PackageName)
if(root == null || root.PackageName != e.PackageName)
{
return;
}
@@ -103,7 +132,7 @@ namespace Bit.Android
switch(e.EventType)
{
case EventTypes.ViewFocused:
if(!e.Source.Password || !_appSettings.AutofillPasswordField)
if(e.Source == null || !e.Source.Password || !_appSettings.AutofillPasswordField)
{
break;
}
@@ -410,16 +439,17 @@ namespace Bit.Android
}
private NodeList GetWindowNodes(AccessibilityNodeInfo n, AccessibilityEvent e,
Func<AccessibilityNodeInfo, bool> condition, bool disposeIfUnused, NodeList nodes = null)
Func<AccessibilityNodeInfo, bool> condition, bool disposeIfUnused, NodeList nodes = null,
int recursionDepth = 0)
{
if(nodes == null)
{
nodes = new NodeList();
}
if(n != null)
var dispose = disposeIfUnused;
if(n != null && recursionDepth < 50)
{
var dispose = disposeIfUnused;
if(n.WindowId == e.WindowId && !(n.ViewIdResourceName?.StartsWith(SystemUiPackage) ?? false) && condition(n))
{
dispose = false;
@@ -428,18 +458,54 @@ namespace Bit.Android
for(var i = 0; i < n.ChildCount; i++)
{
GetWindowNodes(n.GetChild(i), e, condition, true, nodes);
}
if(dispose)
{
n.Dispose();
var childNode = n.GetChild(i);
if(i > 100)
{
global::Android.Util.Log.Info(BitwardenTag, "Too many child iterations.");
break;
}
else if(childNode.GetHashCode() == n.GetHashCode())
{
global::Android.Util.Log.Info(BitwardenTag,
"Child node is the same as parent for some reason.");
}
else
{
GetWindowNodes(childNode, e, condition, true, nodes, recursionDepth++);
}
}
}
if(dispose)
{
n?.Dispose();
}
return nodes;
}
private bool SkipPackage(string eventPackageName)
{
if(string.IsNullOrWhiteSpace(eventPackageName) || FilteredPackageNames.Contains(eventPackageName)
|| eventPackageName.Contains("launcher"))
{
return true;
}
if(_launcherPackageNames == null || _lastLauncherSetBuilt == null ||
(DateTime.Now - _lastLauncherSetBuilt.Value) > _rebuildLauncherSpan)
{
// refresh launcher list every now and then
_lastLauncherSetBuilt = DateTime.Now;
var intent = new Intent(Intent.ActionMain);
intent.AddCategory(Intent.CategoryHome);
var resolveInfo = PackageManager.QueryIntentActivities(intent, 0);
_launcherPackageNames = resolveInfo.Select(ri => ri.ActivityInfo.PackageName).ToHashSet();
}
return _launcherPackageNames.Contains(eventPackageName);
}
public class Browser
{
public Browser(string packageName, string uriViewId)

View File

@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
using Android.Content;
using Bit.Android.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
@@ -9,6 +10,10 @@ namespace Bit.Android.Controls
{
public class CustomButtonRenderer : ButtonRenderer
{
public CustomButtonRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);

View File

@@ -1,4 +1,5 @@
using Bit.Android.Controls;
using Android.Content;
using Bit.Android.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
@@ -7,6 +8,10 @@ namespace Bit.Android.Controls
{
public class CustomLabelRenderer : LabelRenderer
{
public CustomLabelRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);

View File

@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
using Android.Content;
using Bit.Android.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
@@ -9,6 +10,10 @@ namespace Bit.Android.Controls
{
public class CustomSearchBarRenderer : SearchBarRenderer
{
public CustomSearchBarRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);

View File

@@ -0,0 +1,27 @@
using System;
using Bit.Android.Controls;
using Xamarin.Forms;
using Android.Content;
using Xamarin.Forms.Platform.Android;
using Android.Support.V4.Content.Res;
[assembly: ExportRenderer(typeof(Slider), typeof(CustomSliderRenderer))]
namespace Bit.Android.Controls
{
public class CustomSliderRenderer : SliderRenderer
{
public CustomSliderRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
{
base.OnElementChanged(e);
if(Control != null)
{
var thumb = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.slider_thumb, null);
Control.SetThumb(thumb);
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
using Android.Content;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
@@ -10,6 +11,10 @@ namespace Bit.Android.Controls
{
public class ExtendedButtonRenderer : CustomButtonRenderer
{
public ExtendedButtonRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);

View File

@@ -6,12 +6,17 @@ using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Text.Method;
using Android.Views;
using Android.Content;
[assembly: ExportRenderer(typeof(ExtendedEditor), typeof(ExtendedEditorRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedEditorRenderer : EditorRenderer
{
public ExtendedEditorRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);

View File

@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
using Android.Content;
using Android.Graphics;
using Android.Text;
using Android.Text.Method;
@@ -8,6 +9,7 @@ using Android.Widget;
using Bit.Android.Controls;
using Bit.App.Controls;
using Bit.App.Enums;
using Plugin.CurrentActivity;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
@@ -16,6 +18,10 @@ namespace Bit.Android.Controls
{
public class ExtendedEntryRenderer : EntryRenderer
{
public ExtendedEntryRenderer(Context context)
: base(context)
{ }
private bool _isPassword;
private bool _toggledPassword;
private bool _isDisposed;
@@ -66,6 +72,11 @@ namespace Bit.Android.Controls
{
Control.Typeface = Typeface.Monospace;
}
if(_view.HideCursor)
{
Control.SetCursorVisible(false);
}
}
private void ToggleIsPassword(object sender, EventArgs e)
@@ -91,7 +102,7 @@ namespace Bit.Android.Controls
}
// show keyboard
var imm = Forms.Context.GetSystemService(global::Android.Content.Context.InputMethodService) as InputMethodManager;
var imm = CrossCurrentActivity.Current.Activity.GetSystemService(Context.InputMethodService) as InputMethodManager;
imm.ShowSoftInput(Control, ShowFlags.Forced);
imm.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);

View File

@@ -0,0 +1,33 @@
using System;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Content;
using Android.Views;
[assembly: ExportRenderer(typeof(ExtendedListView), typeof(ExtendedListViewRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedListViewRenderer : ListViewRenderer
{
public ExtendedListViewRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if(e.NewElement is ExtendedListView listView)
{
if(listView.BottomPadding > 0)
{
Control.SetPadding(0, 0, 0, listView.BottomPadding);
Control.SetClipToPadding(false);
Control.ScrollBarStyle = ScrollbarStyles.OutsideOverlay;
}
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
using Android.Content;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
@@ -10,6 +11,10 @@ namespace Bit.Android.Controls
{
public class ExtendedPickerRenderer : PickerRenderer
{
public ExtendedPickerRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);

View File

@@ -2,89 +2,434 @@
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Com.Ittianyu.Bottomnavigationviewex;
using Xamarin.Forms.Platform.Android;
using Android.Support.Design.Widget;
using Xamarin.Forms.Platform.Android.AppCompat;
using System.Reflection;
using RelativeLayout = Android.Widget.RelativeLayout;
using Platform = Xamarin.Forms.Platform.Android.Platform;
using Android.Content;
using Android.Views;
using Android.Widget;
using Android.Support.Design.Internal;
using System.IO;
using System.Linq;
using System.ComponentModel;
using Android.Support.Design.Widget;
[assembly: ExportRenderer(typeof(ExtendedTabbedPage), typeof(ExtendedTabbedPageRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedTabbedPageRenderer : TabbedPageRenderer, TabLayout.IOnTabSelectedListener
public class ExtendedTabbedPageRenderer : VisualElementRenderer<ExtendedTabbedPage>,
BottomNavigationView.IOnNavigationItemSelectedListener
{
private TabLayout _tabLayout;
public static bool ShouldUpdateSelectedIcon;
public static Action<IMenuItem, FileImageSource, bool> MenuItemIconSetter;
public static float? BottomBarHeight = 50;
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
private RelativeLayout _rootLayout;
private FrameLayout _pageContainer;
private BottomNavigationViewEx _bottomNav;
private readonly int _barId;
public static global::Android.Graphics.Color? BackgroundColor;
public ExtendedTabbedPageRenderer(Context context)
: base(context)
{
AutoPackage = false;
_barId = GenerateViewId();
}
IPageController TabbedController => Element as IPageController;
public int LastSelectedIndex { get; internal set; }
public bool OnNavigationItemSelected(IMenuItem item)
{
this.SwitchPage(item);
return true;
}
internal void SetupTabItems()
{
this.SetupTabItems(_bottomNav);
}
internal void SetupBottomBar()
{
_bottomNav = this.SetupBottomBar(_rootLayout, _bottomNav, _barId);
}
public static readonly Action<IMenuItem, FileImageSource, bool> DefaultMenuItemIconSetter = (menuItem, icon, selected) =>
{
var tabIconId = ResourceUtils.IdFromTitle(icon, ResourceManager.DrawableClass);
menuItem.SetIcon(tabIconId);
};
protected override void OnElementChanged(ElementChangedEventArgs<ExtendedTabbedPage> e)
{
base.OnElementChanged(e);
var view = (ExtendedTabbedPage)Element;
var field = typeof(ExtendedTabbedPageRenderer).BaseType.GetField("_tabLayout",
BindingFlags.Instance | BindingFlags.NonPublic);
_tabLayout = field?.GetValue(this) as TabLayout;
if(_tabLayout != null)
if(e.OldElement != null)
{
var tab = _tabLayout.GetTabAt(0);
SetSelectedTabIcon(tab, Element.Children[0].Icon, true);
e.OldElement.ChildAdded -= PagesChanged;
e.OldElement.ChildRemoved -= PagesChanged;
e.OldElement.ChildrenReordered -= PagesChanged;
}
}
void TabLayout.IOnTabSelectedListener.OnTabSelected(TabLayout.Tab tab)
{
if(Element == null)
if(e.NewElement == null)
{
return;
}
var selectedIndex = tab.Position;
var child = Element.Children[selectedIndex];
if(Element.Children.Count > selectedIndex && selectedIndex >= 0)
UpdateIgnoreContainerAreas();
if(_rootLayout == null)
{
Element.CurrentPage = Element.Children[selectedIndex];
SetupNativeView();
}
SetSelectedTabIcon(tab, child.Icon, true);
this.HandlePagesChanged();
SwitchContent(Element.CurrentPage);
Element.ChildAdded += PagesChanged;
Element.ChildRemoved += PagesChanged;
Element.ChildrenReordered += PagesChanged;
}
void TabLayout.IOnTabSelectedListener.OnTabUnselected(TabLayout.Tab tab)
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var child = Element.Children[tab.Position];
SetSelectedTabIcon(tab, child.Icon, false);
base.OnElementPropertyChanged(sender, e);
if(e.PropertyName == nameof(TabbedPage.CurrentPage))
{
SwitchContent(Element.CurrentPage);
}
}
private void SetSelectedTabIcon(TabLayout.Tab tab, string icon, bool selected)
void PagesChanged(object sender, EventArgs e)
{
if(string.IsNullOrEmpty(icon))
this.HandlePagesChanged();
}
protected override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
TabbedController?.SendAppearing();
}
protected override void OnDetachedFromWindow()
{
base.OnDetachedFromWindow();
TabbedController?.SendDisappearing();
}
protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
{
var width = right - left;
var height = bottom - top;
base.OnLayout(changed, left, top, right, bottom);
if(width <= 0 || height <= 0)
{
return;
}
if(selected)
this.Layout(width, height);
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
var selectedIcon = string.Format("{0}_selected", icon.Replace(".png", string.Empty));
var selectedResource = IdFromTitle(selectedIcon, ResourceManager.DrawableClass);
if(selectedResource != 0)
Element.ChildAdded -= PagesChanged;
Element.ChildRemoved -= PagesChanged;
Element.ChildrenReordered -= PagesChanged;
if(_rootLayout != null)
{
tab.SetIcon(selectedResource);
return;
RemoveAllViews();
foreach(Page pageToRemove in Element.Children)
{
var pageRenderer = Platform.GetRenderer(pageToRemove);
if(pageRenderer != null)
{
pageRenderer.View.RemoveFromParent();
pageRenderer.Dispose();
}
}
if(_bottomNav != null)
{
_bottomNav.SetOnNavigationItemSelectedListener(null);
_bottomNav.Dispose();
_bottomNav = null;
}
_rootLayout.Dispose();
_rootLayout = null;
}
}
var resource = IdFromTitle(icon, ResourceManager.DrawableClass);
tab.SetIcon(resource);
base.Dispose(disposing);
}
private int IdFromTitle(string title, Type type)
internal void SetupNativeView()
{
var name = System.IO.Path.GetFileNameWithoutExtension(title);
return GetId(type, name);
_rootLayout = this.CreateRoot(_barId, GenerateViewId(), out _pageContainer);
AddView(_rootLayout);
}
private int GetId(Type type, string propertyName)
void SwitchContent(Page page)
{
this.ChangePage(_pageContainer, page);
}
void UpdateIgnoreContainerAreas()
{
foreach(var child in Element.Children)
{
child.IgnoresContainerArea = false;
}
}
}
internal static class TabExtensions
{
public static Rectangle CreateRect(this Context context, int width, int height)
{
return new Rectangle(0, 0, context.FromPixels(width), context.FromPixels(height));
}
public static void HandlePagesChanged(this ExtendedTabbedPageRenderer renderer)
{
renderer.SetupBottomBar();
renderer.SetupTabItems();
if(renderer.Element.Children.Count == 0)
{
return;
}
EnsureTabIndex(renderer);
}
static void EnsureTabIndex(ExtendedTabbedPageRenderer renderer)
{
var rootLayout = (RelativeLayout)renderer.GetChildAt(0);
var bottomNav = (BottomNavigationViewEx)rootLayout.GetChildAt(1);
var menu = (BottomNavigationMenu)bottomNav.Menu;
var itemIndex = menu.FindItemIndex(bottomNav.SelectedItemId);
var pageIndex = renderer.Element.Children.IndexOf(renderer.Element.CurrentPage);
if(pageIndex >= 0 && pageIndex != itemIndex && pageIndex < bottomNav.ItemCount)
{
var menuItem = menu.GetItem(pageIndex);
bottomNav.SelectedItemId = menuItem.ItemId;
if(ExtendedTabbedPageRenderer.ShouldUpdateSelectedIcon && ExtendedTabbedPageRenderer.MenuItemIconSetter != null)
{
ExtendedTabbedPageRenderer.MenuItemIconSetter?.Invoke(menuItem, renderer.Element.CurrentPage.Icon, true);
if(renderer.LastSelectedIndex != pageIndex)
{
var lastSelectedPage = renderer.Element.Children[renderer.LastSelectedIndex];
var lastSelectedMenuItem = menu.GetItem(renderer.LastSelectedIndex);
ExtendedTabbedPageRenderer.MenuItemIconSetter?.Invoke(lastSelectedMenuItem, lastSelectedPage.Icon, false);
renderer.LastSelectedIndex = pageIndex;
}
}
}
}
public static void SwitchPage(this ExtendedTabbedPageRenderer renderer, IMenuItem item)
{
var rootLayout = (RelativeLayout)renderer.GetChildAt(0);
var bottomNav = (BottomNavigationViewEx)rootLayout.GetChildAt(1);
var menu = (BottomNavigationMenu)bottomNav.Menu;
var index = menu.FindItemIndex(item.ItemId);
var pageIndex = index % renderer.Element.Children.Count;
var currentPageIndex = renderer.Element.Children.IndexOf(renderer.Element.CurrentPage);
if(currentPageIndex != pageIndex)
{
renderer.Element.CurrentPage = renderer.Element.Children[pageIndex];
}
}
public static void Layout(this ExtendedTabbedPageRenderer renderer, int width, int height)
{
var rootLayout = (RelativeLayout)renderer.GetChildAt(0);
var bottomNav = (BottomNavigationViewEx)rootLayout.GetChildAt(1);
var Context = renderer.Context;
rootLayout.Measure(MakeMeasureSpec(width, MeasureSpecMode.Exactly),
MakeMeasureSpec(height, MeasureSpecMode.AtMost));
((IPageController)renderer.Element).ContainerArea =
Context.CreateRect(rootLayout.MeasuredWidth, rootLayout.GetChildAt(0).MeasuredHeight);
rootLayout.Measure(MakeMeasureSpec(width, MeasureSpecMode.Exactly),
MakeMeasureSpec(height, MeasureSpecMode.Exactly));
rootLayout.Layout(0, 0, rootLayout.MeasuredWidth, rootLayout.MeasuredHeight);
if(renderer.Element.Children.Count == 0)
{
return;
}
int tabsHeight = bottomNav.MeasuredHeight;
var item = (ViewGroup)bottomNav.GetChildAt(0);
item.Measure(MakeMeasureSpec(width, MeasureSpecMode.Exactly),
MakeMeasureSpec(tabsHeight, MeasureSpecMode.Exactly));
item.Layout(0, 0, width, tabsHeight);
int item_w = width / item.ChildCount;
for(int i = 0; i < item.ChildCount; i++)
{
var frame = (FrameLayout)item.GetChildAt(i);
frame.Measure(MakeMeasureSpec(item_w, MeasureSpecMode.Exactly),
MakeMeasureSpec(tabsHeight, MeasureSpecMode.Exactly));
frame.Layout(i * item_w, 0, i * item_w + item_w, tabsHeight);
}
}
public static void SetupTabItems(this ExtendedTabbedPageRenderer renderer, BottomNavigationViewEx bottomNav)
{
var element = renderer.Element;
var menu = (BottomNavigationMenu)bottomNav.Menu;
menu.ClearAll();
var tabsCount = Math.Min(element.Children.Count, bottomNav.MaxItemCount);
for(int i = 0; i < tabsCount; i++)
{
var page = element.Children[i];
var menuItem = menu.Add(0, i, 0, page.Title);
var setter = ExtendedTabbedPageRenderer.MenuItemIconSetter ?? ExtendedTabbedPageRenderer.DefaultMenuItemIconSetter;
setter.Invoke(menuItem, page.Icon, renderer.LastSelectedIndex == i);
}
if(element.Children.Count > 0)
{
bottomNav.EnableShiftingMode(false);
bottomNav.EnableItemShiftingMode(false);
bottomNav.EnableAnimation(false);
bottomNav.SetTextVisibility(false);
bottomNav.SetBackgroundResource(Resource.Drawable.bottom_nav_bg);
bottomNav.SetIconSize(24, 24);
bottomNav.SetIconsMarginTop(32);
if(element.Children.Count > 3)
{
bottomNav.SetIconSizeAt(3, 29, 29);
bottomNav.SetIconMarginTop(3, 28);
}
var stateList = new global::Android.Content.Res.ColorStateList(
new int[][] {
new int[] { global::Android.Resource.Attribute.StateChecked },
new int[] { global::Android.Resource.Attribute.StateEnabled}
},
new int[] {
element.TintColor.ToAndroid(), // Selected
Color.FromHex("A1A1A1").ToAndroid() // Normal
});
bottomNav.ItemIconTintList = stateList;
}
}
public static BottomNavigationViewEx SetupBottomBar(this ExtendedTabbedPageRenderer renderer,
global::Android.Widget.RelativeLayout rootLayout, BottomNavigationViewEx bottomNav, int barId)
{
if(bottomNav != null)
{
rootLayout.RemoveView(bottomNav);
bottomNav.SetOnNavigationItemSelectedListener(null);
}
var barParams = new global::Android.Widget.RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MatchParent,
ExtendedTabbedPageRenderer.BottomBarHeight.HasValue ?
(int)rootLayout.Context.ToPixels(ExtendedTabbedPageRenderer.BottomBarHeight.Value) :
ViewGroup.LayoutParams.WrapContent);
barParams.AddRule(LayoutRules.AlignParentBottom);
bottomNav = new BottomNavigationViewEx(rootLayout.Context)
{
LayoutParameters = barParams,
Id = barId
};
if(ExtendedTabbedPageRenderer.BackgroundColor.HasValue)
{
bottomNav.SetBackgroundColor(ExtendedTabbedPageRenderer.BackgroundColor.Value);
}
bottomNav.SetOnNavigationItemSelectedListener(renderer);
rootLayout.AddView(bottomNav, 1, barParams);
return bottomNav;
}
public static void ChangePage(this ExtendedTabbedPageRenderer renderer, FrameLayout pageContainer, Page page)
{
renderer.Context.HideKeyboard(renderer);
if(page == null)
{
return;
}
if(Platform.GetRenderer(page) == null)
{
Platform.SetRenderer(page, Platform.CreateRendererWithContext(page, renderer.Context));
}
var pageContent = Platform.GetRenderer(page).View;
pageContainer.AddView(pageContent);
if(pageContainer.ChildCount > 1)
{
pageContainer.RemoveViewAt(0);
}
EnsureTabIndex(renderer);
}
public static RelativeLayout CreateRoot(this ExtendedTabbedPageRenderer renderer, int barId, int pageContainerId, out FrameLayout pageContainer)
{
var rootLayout = new RelativeLayout(renderer.Context)
{
LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent),
};
var pageParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
pageParams.AddRule(LayoutRules.Above, barId);
pageContainer = new FrameLayout(renderer.Context)
{
LayoutParameters = pageParams,
Id = pageContainerId
};
rootLayout.AddView(pageContainer, 0, pageParams);
return rootLayout;
}
private static int MakeMeasureSpec(int size, MeasureSpecMode mode)
{
return size + (int)mode;
}
}
public static class ResourceUtils
{
public static int IdFromTitle(string title, Type type)
{
var name = Path.GetFileNameWithoutExtension(title);
var id = GetId(type, name);
return id;
}
public static int GetId(Type type, string propertyName)
{
var props = type.GetFields();
var prop = props.FirstOrDefault(p => p.Name == propertyName);
var prop = props.Select(p => p).FirstOrDefault(p => p.Name == propertyName);
if(prop != null)
{
return (int)prop.GetValue(type);

View File

@@ -14,11 +14,25 @@ namespace Bit.Android.Controls
{
public class ExtendedTableViewRenderer : TableViewRenderer
{
public ExtendedTableViewRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
{
base.OnElementChanged(e);
Control.Divider = null;
Control.DividerHeight = 0;
if(e.NewElement is ExtendedTableView tableView)
{
if(tableView.BottomPadding > 0)
{
Control.SetPadding(0, 0, 0, tableView.BottomPadding);
Control.SetClipToPadding(false);
Control.ScrollBarStyle = ScrollbarStyles.OutsideOverlay;
}
}
}
protected override TableViewModelRenderer GetModelRenderer(AListView listView, TableView view)

View File

@@ -6,6 +6,8 @@ using Xamarin.Forms.Platform.Android;
using Android.Webkit;
using AWebkit = Android.Webkit;
using Java.Interop;
using Android.Content;
using Plugin.CurrentActivity;
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace Bit.Android.Controls
@@ -14,13 +16,17 @@ namespace Bit.Android.Controls
{
private const string JSFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
public HybridWebViewRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if(Control == null)
{
var webView = new AWebkit.WebView(Forms.Context);
var webView = new AWebkit.WebView(CrossCurrentActivity.Current.Activity);
webView.Settings.JavaScriptEnabled = true;
SetNativeControl(webView);
}

View File

@@ -0,0 +1,25 @@
#if !FDROID
using System;
using Android.App;
using Android.Content;
using Bit.App;
using Bit.App.Abstractions;
using Firebase.Iid;
using Plugin.Settings.Abstractions;
using XLabs.Ioc;
namespace Bit.Android
{
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class FirebaseInstanceIdService : Firebase.Iid.FirebaseInstanceIdService
{
public override void OnTokenRefresh()
{
var settings = Resolver.Resolve<ISettings>();
settings.AddOrUpdateValue(Constants.PushRegisteredToken, FirebaseInstanceId.Instance.Token);
Resolver.Resolve<IPushNotificationService>()?.Register();
}
}
}
#endif

View File

@@ -0,0 +1,44 @@
#if !FDROID
using System;
using Android.App;
using Android.Content;
using Bit.App.Abstractions;
using Firebase.Messaging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Xamarin.Forms;
using XLabs.Ioc;
namespace Bit.Android
{
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FirebaseMessagingService : Firebase.Messaging.FirebaseMessagingService
{
public override void OnMessageReceived(RemoteMessage message)
{
if(message?.Data == null)
{
return;
}
var data = message.Data.ContainsKey("data") ? message.Data["data"] : null;
if(data == null)
{
return;
}
try
{
var obj = JObject.Parse(data);
var listener = Resolver.Resolve<IPushNotificationListener>();
listener.OnMessage(obj, Device.Android);
}
catch(JsonReaderException ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
}
}
#endif

View File

@@ -1,3 +1,4 @@
#if !FDROID
using HockeyApp.Android;
using Bit.App.Abstractions;
using Newtonsoft.Json;
@@ -51,4 +52,5 @@ namespace Bit.Android
return true;
}
}
}
}
#endif

View File

@@ -7,7 +7,6 @@ using Bit.App.Abstractions;
using XLabs.Ioc;
using Plugin.Settings.Abstractions;
using Plugin.Connectivity.Abstractions;
using Acr.UserDialogs;
using Android.Content;
using System.Reflection;
using Xamarin.Forms.Platform.Android;
@@ -62,8 +61,10 @@ namespace Bit.Android
var appIdService = Resolver.Resolve<IAppIdService>();
var authService = Resolver.Resolve<IAuthService>();
#if !FDROID
HockeyApp.Android.CrashManager.Register(this, HockeyAppId,
new HockeyAppCrashManagerListener(appIdService, authService));
#endif
Forms.Init(this, bundle);
@@ -77,12 +78,10 @@ namespace Bit.Android
_appOptions,
Resolver.Resolve<IAuthService>(),
Resolver.Resolve<IConnectivity>(),
Resolver.Resolve<IUserDialogs>(),
Resolver.Resolve<IDatabaseService>(),
Resolver.Resolve<ISyncService>(),
_settings,
Resolver.Resolve<ILockService>(),
Resolver.Resolve<IGoogleAnalyticsService>(),
Resolver.Resolve<ILocalizeService>(),
Resolver.Resolve<IAppInfoService>(),
Resolver.Resolve<IAppSettingsService>(),
@@ -140,7 +139,14 @@ namespace Bit.Android
if(Utilities.NfcEnabled())
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, "ResumeYubiKey");
try
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, "ResumeYubiKey");
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine(e);
}
}
}
@@ -250,7 +256,7 @@ namespace Bit.Android
var options = new AppOptions
{
Uri = Intent.GetStringExtra("uri") ?? Intent.GetStringExtra("autofillFrameworkUri"),
MyVault = Intent.GetBooleanExtra("myVaultTile", false),
MyVaultTile = Intent.GetBooleanExtra("myVaultTile", false),
FromAutofillFramework = Intent.GetBooleanExtra("autofillFramework", false)
};

View File

@@ -1,5 +1,4 @@
using System;
using Acr.UserDialogs;
using Android.App;
using Android.Content;
using Android.OS;
@@ -14,7 +13,6 @@ using Plugin.Fingerprint;
using Plugin.Settings;
using XLabs.Ioc;
using System.Threading.Tasks;
using Plugin.Settings.Abstractions;
using FFImageLoading.Forms.Droid;
using XLabs.Ioc.SimpleInjectorContainer;
using SimpleInjector;
@@ -61,55 +59,6 @@ namespace Bit.Android
RegisterActivityLifecycleCallbacks(this);
AppContext = ApplicationContext;
StartPushService();
HandlePushReregistration();
}
private void HandlePushReregistration()
{
var pushNotification = Resolver.Resolve<IPushNotificationService>();
var settings = Resolver.Resolve<ISettings>();
// Reregister for push token based on certain conditions
// ref https://github.com/rdelrosario/xamarin-plugins/issues/65
var reregister = false;
// 1. First time starting the app after a new install
if(settings.GetValueOrDefault(FirstLaunchKey, true))
{
settings.AddOrUpdateValue(FirstLaunchKey, false);
reregister = true;
}
// 2. App version changed (installed update)
var versionCode = Context.ApplicationContext.PackageManager.GetPackageInfo(Context.PackageName, 0).VersionCode;
if(settings.GetValueOrDefault(LastVersionCodeKey, -1) != versionCode)
{
settings.AddOrUpdateValue(LastVersionCodeKey, versionCode);
reregister = true;
}
// 3. In debug mode
if(App.Utilities.Helpers.InDebugMode())
{
reregister = true;
}
// 4. Doesn't have a push token currently
if(string.IsNullOrWhiteSpace(pushNotification.Token))
{
reregister = true;
}
if(reregister)
{
pushNotification.Unregister();
if(Resolver.Resolve<IAuthService>().IsAuthenticated)
{
pushNotification.Register();
}
}
}
public override void OnTerminate()
@@ -149,34 +98,10 @@ namespace Bit.Android
{
}
public static void StartPushService()
{
AppContext.StartService(new Intent(AppContext, typeof(AndroidPushService)));
if(Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
{
PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext,
typeof(AndroidPushService)), 0);
AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(AlarmService);
alarm.Cancel(pintent);
}
}
public static void StopPushService()
{
AppContext.StopService(new Intent(AppContext, typeof(AndroidPushService)));
if(Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
{
PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext,
typeof(AndroidPushService)), 0);
AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(AlarmService);
alarm.Cancel(pintent);
}
}
public static void SetIoc(Application application)
{
UserDialogs.Init(application);
CachedImageRenderer.Init();
Refractored.FabControl.Droid.FloatingActionButtonViewRenderer.Init();
CachedImageRenderer.Init(true);
ZXing.Net.Mobile.Forms.Android.Platform.Init();
CrossFingerprint.SetCurrentActivityResolver(() => CrossCurrentActivity.Current.Activity);
@@ -201,17 +126,19 @@ namespace Bit.Android
container.RegisterSingleton<IDeviceActionService, DeviceActionService>();
container.RegisterSingleton<IAppIdService, AppIdService>();
container.RegisterSingleton<IPasswordGenerationService, PasswordGenerationService>();
container.RegisterSingleton<IReflectionService, ReflectionService>();
container.RegisterSingleton<ILockService, LockService>();
container.RegisterSingleton<IAppInfoService, AppInfoService>();
#if FDROID
container.RegisterSingleton<IGoogleAnalyticsService, NoopGoogleAnalyticsService>();
#else
container.RegisterSingleton<IGoogleAnalyticsService, GoogleAnalyticsService>();
#endif
container.RegisterSingleton<IDeviceInfoService, DeviceInfoService>();
container.RegisterSingleton<ILocalizeService, LocalizeService>();
container.RegisterSingleton<ILogService, LogService>();
container.RegisterSingleton<IHttpService, HttpService>();
container.RegisterSingleton<ITokenService, TokenService>();
container.RegisterSingleton<ISettingsService, SettingsService>();
container.RegisterSingleton<IMemoryService, MemoryService>();
container.RegisterSingleton<IAppSettingsService, AppSettingsService>();
// Repositories
@@ -233,14 +160,16 @@ namespace Bit.Android
// Other
container.RegisterSingleton(CrossSettings.Current);
container.RegisterSingleton(CrossConnectivity.Current);
container.RegisterSingleton(UserDialogs.Instance);
container.RegisterSingleton(CrossFingerprint.Current);
// Push
var pushListener = new PushNotificationListener();
container.RegisterSingleton<IPushNotificationListener>(pushListener);
CrossPushNotification.Initialize(pushListener, "962181367620");
container.RegisterSingleton(CrossPushNotification.Current);
#if FDROID
container.RegisterSingleton<IPushNotificationListener, NoopPushNotificationListener>();
container.RegisterSingleton<IPushNotificationService, NoopPushNotificationService>();
#else
container.RegisterSingleton<IPushNotificationListener, PushNotificationListener>();
container.RegisterSingleton<IPushNotificationService, AndroidPushNotificationService>();
#endif
container.Verify();
Resolver.SetResolver(new SimpleInjectorResolver(container));

Binary file not shown.

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.x8bit.bitwarden" android:versionName="1.13.0" android:installLocation="auto" android:versionCode="502" xmlns:tools="http://schemas.android.com/tools">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="26" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.x8bit.bitwarden" android:versionName="1.14.4" android:installLocation="auto" android:versionCode="502" xmlns:tools="http://schemas.android.com/tools">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
@@ -8,11 +8,6 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.x8bit.bitwarden.permission.C2D_MESSAGE" />
<permission android:name="com.x8bit.bitwarden.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
@@ -28,6 +23,17 @@
android:resource="@xml/filepaths" />
</provider>
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
android:exported="false" />
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<activity android:name="net.hockeyapp.android.UpdateActivity" android:exported="false" android:icon="@drawable/icon" />
</application>
</manifest>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 585 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#D2D6DF" />
</shape>
</item>
<item android:top="1dp">
<shape android:shape="rectangle">
<solid android:color="#F5F5F7" />
</shape>
</item>
</layer-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 741 B

After

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1017 B

After

Width:  |  Height:  |  Size: 593 B

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="@color/white"/>
<stroke android:width="1dp" android:color="#B5B5B5"/>
<size android:width="28dp" android:height="28dp"/>
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

View File

@@ -7,9 +7,5 @@
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabIndicatorColor="@android:color/white"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
app:tabTextColor="@color/tabtext"
app:tabSelectedTextColor="@android:color/white"
app:tabMode="fixed" />

View File

@@ -1,11 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways" />
android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

View File

@@ -4,11 +4,11 @@
Assist with filling username and password fields in other apps and on the web.
</string>
<string name="AutoFillServiceDescription">
It can be difficult for users (especially those with disabilities) to switch between apps and copy/paste
username and password information from their bitwarden vault.\n\nUsing this accessibility service allows bitwarden
to detect and read input fields on your device\'s screen. Whenever bitwarden detects a password field on the screen
a notification will appear that allows you to quickly access your bitwarden vault and automatically fill (auto-fill)
the correct login information into the necessary fields.
It can be difficult and insecure for users to switch between apps to copy/paste username and password information
from their bitwarden vault.\n\nUsing this accessibility service allows bitwarden to detect and read input fields on
your device\'s screen. Whenever bitwarden detects a password field on the screen a notification will appear that allows
you to quickly access your bitwarden vault and automatically fill (auto-fill) the correct login information into the
necessary fields.
</string>
<string name="MyVault">
My Vault

View File

@@ -89,7 +89,7 @@ namespace Bit.Android.Services
{
return App.Utilities.Crypto.AesCbcDecrypt(new App.Models.CipherString(cs), aesKey);
}
catch(Exception e)
catch
{
Console.WriteLine("Failed to decrypt from secure storage.");
_settings.Remove(formattedKey);
@@ -120,7 +120,7 @@ namespace Bit.Android.Services
var cipherString = App.Utilities.Crypto.AesCbcEncrypt(dataBytes, aesKey);
_settings.AddOrUpdateValue(formattedKey, cipherString.EncryptedString);
}
catch(Exception e)
catch
{
Console.WriteLine("Failed to encrypt to secure storage.");
//Utilities.SendCrashEmail(e);
@@ -224,7 +224,7 @@ namespace Bit.Android.Services
return new App.Models.SymmetricCryptoKey(key);
}
}
catch(Exception e)
catch
{
Console.WriteLine("Cannot get AesKey.");
_keyStore.DeleteEntry(KeyAlias);

View File

@@ -1,560 +1,44 @@
using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using Android.OS;
#if !FDROID
using System;
using Bit.App;
using Bit.App.Abstractions;
using Bit.App.Utilities;
using System.Threading;
using Plugin.Settings.Abstractions;
using Xamarin.Forms;
using Android.Gms.Gcm.Iid;
using Android.Gms.Gcm;
using Java.IO;
using Newtonsoft.Json.Linq;
using Android.Support.V4.App;
using Android.Media;
using Newtonsoft.Json;
namespace Bit.Android.Services
{
public class AndroidPushNotificationService : IPushNotificationService
{
private const string GcmPreferencesKey = "GCMPreferences";
private const string Tag = "PushNotification";
private readonly IPushNotificationListener _pushNotificationListener;
private readonly ISettings _settings;
internal static IPushNotificationListener Listener { get; set; }
public string Token => GetRegistrationId();
public AndroidPushNotificationService(
IPushNotificationListener pushNotificationListener,
ISettings settings)
{
_pushNotificationListener = pushNotificationListener;
_settings = settings;
}
public string Token => _settings.GetValueOrDefault(Constants.PushCurrentToken, null);
public void Register()
{
System.Diagnostics.Debug.WriteLine(
$"{PushNotificationContants.DomainName} - Register - Registering push notifications");
if(string.IsNullOrEmpty(CrossPushNotification.SenderId))
var registeredToken = _settings.GetValueOrDefault(Constants.PushRegisteredToken, null);
if(!string.IsNullOrWhiteSpace(registeredToken) && registeredToken != Token)
{
System.Diagnostics.Debug.WriteLine(
$"{PushNotificationContants.DomainName} - Register - SenderId is missing.");
CrossPushNotification.PushNotificationListener.OnError(
$"{PushNotificationContants.DomainName} - Register - Sender Id is missing.", Device.Android);
_pushNotificationListener.OnRegistered(registeredToken, Device.Android);
}
else
{
System.Diagnostics.Debug.WriteLine(
$"{PushNotificationContants.DomainName} - Register - Registering for Push Notifications");
ThreadPool.QueueUserWorkItem(state =>
{
try
{
Intent intent = new Intent(global::Android.App.Application.Context,
typeof(PushNotificationRegistrationIntentService));
global::Android.App.Application.Context.StartService(intent);
}
catch(Exception ex)
{
System.Diagnostics.Debug.WriteLine($"{Tag} - Error : {ex.Message}");
CrossPushNotification.PushNotificationListener.OnError($"{Tag} - Register - {ex.Message}",
Device.Android);
}
});
_settings.AddOrUpdateValue(Constants.PushLastRegistrationDate, DateTime.UtcNow);
}
}
public void Unregister()
{
ThreadPool.QueueUserWorkItem(state =>
{
System.Diagnostics.Debug.WriteLine(
$"{PushNotificationContants.DomainName} - Unregister - Unregistering push notifications");
try
{
var instanceID = InstanceID.GetInstance(global::Android.App.Application.Context);
instanceID.DeleteToken(CrossPushNotification.SenderId, GoogleCloudMessaging.InstanceIdScope);
CrossPushNotification.PushNotificationListener.OnUnregistered(Device.Android);
StoreRegistrationId(global::Android.App.Application.Context, string.Empty);
}
catch(IOException ex)
{
System.Diagnostics.Debug.WriteLine($"{Tag} - Error : {ex.Message}");
CrossPushNotification.PushNotificationListener.OnError(
$"{Tag} - Unregister - {ex.Message}", Device.Android);
}
});
}
private string GetRegistrationId()
{
var context = global::Android.App.Application.Context;
var prefs = GetGCMPreferences(context);
var registrationId = prefs.GetString(PushNotificationContants.Token, string.Empty);
if(string.IsNullOrEmpty(registrationId))
{
System.Diagnostics.Debug.WriteLine($"{PushNotificationContants.DomainName} - Registration not found.");
return string.Empty;
}
// Check if app was updated; if so, it must clear the registration ID
// since the existing registration ID is not guaranteed to work with
// the new app version.
var registeredVersion = prefs.GetInt(PushNotificationContants.AppVersion, Java.Lang.Integer.MinValue);
var currentVersion = GetAppVersion(context);
if(registeredVersion != currentVersion)
{
System.Diagnostics.Debug.WriteLine($"{PushNotificationContants.DomainName} - App version changed.");
return string.Empty;
}
return registrationId;
}
internal static ISharedPreferences GetGCMPreferences(Context context)
{
return context.GetSharedPreferences(GcmPreferencesKey, FileCreationMode.Private);
}
internal static int GetAppVersion(Context context)
{
try
{
var packageInfo = context.PackageManager.GetPackageInfo(context.PackageName, 0);
return packageInfo.VersionCode;
}
catch(global::Android.Content.PM.PackageManager.NameNotFoundException e)
{
// should never happen
throw new Java.Lang.RuntimeException("Could not get package name: " + e);
}
}
internal static void StoreRegistrationId(Context context, string regId)
{
var prefs = GetGCMPreferences(context);
var appVersion = GetAppVersion(context);
System.Diagnostics.Debug.WriteLine(
$"{PushNotificationContants.DomainName} - Saving token on app version {appVersion}");
var editor = prefs.Edit();
editor.PutString(PushNotificationContants.Token, regId);
editor.PutInt(PushNotificationContants.AppVersion, appVersion);
editor.Commit();
}
}
[Service(Exported = false)]
public class PushNotificationRegistrationIntentService : IntentService
{
private const string Tag = "PushNotificationRegistationIntentService";
private string[] _topics = new string[] { "global" };
private readonly object _syncLock = new object();
protected override void OnHandleIntent(Intent intent)
{
try
{
var extras = intent.Extras;
lock(_syncLock)
{
var instanceID = InstanceID.GetInstance(global::Android.App.Application.Context);
var token = instanceID.GetToken(CrossPushNotification.SenderId,
GoogleCloudMessaging.InstanceIdScope, null);
CrossPushNotification.PushNotificationListener.OnRegistered(token, Device.Android);
AndroidPushNotificationService.StoreRegistrationId(global::Android.App.Application.Context, token);
SubscribeTopics(token);
System.Diagnostics.Debug.WriteLine($"{token} - Device registered, registration ID={Tag}");
}
}
catch(Exception ex)
{
System.Diagnostics.Debug.WriteLine($"{ex.Message} - Error : {Tag}");
CrossPushNotification.PushNotificationListener.OnError(
$"{ex.ToString()} - Register - {Tag}", Device.Android);
}
}
private void SubscribeTopics(string token)
{
var pubSub = GcmPubSub.GetInstance(this);
foreach(var topic in _topics)
{
pubSub.Subscribe(token, "/topics/" + topic, null);
}
}
}
[Service(Exported = false)]
[IntentFilter(new string[] { "com.google.android.gms.iid.InstanceID" })]
public class PushNotificationInstanceIDListenerService : InstanceIDListenerService
{
private const string Tag = "PushNotificationInstanceIDLS";
public override void OnTokenRefresh()
{
base.OnTokenRefresh();
ThreadPool.QueueUserWorkItem(state =>
{
try
{
var intent = new Intent(global::Android.App.Application.Context,
typeof(PushNotificationRegistrationIntentService));
global::Android.App.Application.Context.StartService(intent);
}
catch(Exception ex)
{
System.Diagnostics.Debug.WriteLine($"{ex.Message} - Error : {Tag}");
CrossPushNotification.PushNotificationListener.OnError(
$"{ex.ToString()} - Register - {Tag}", Device.Android);
}
});
}
}
[Service(Exported = false, Name = "pushnotification.plugin.PushNotificationGcmListener")]
[IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" },
Categories = new string[] { "com.x8bit.bitwarden" })]
public class PushNotificationGcmListener : GcmListenerService
{
public override void OnMessageReceived(string from, Bundle extras)
{
if(extras != null && !extras.IsEmpty)
{
System.Diagnostics.Debug.WriteLine(
$"{PushNotificationContants.DomainName} - GCM Listener - Push Received");
var parameters = new Dictionary<string, object>();
var values = new JObject();
foreach(var key in extras.KeySet())
{
var value = extras.Get(key).ToString();
if(ValidateJSON(value))
{
values.Add(key, JObject.Parse(value));
}
else
{
values.Add(key, value);
}
parameters.Add(key, extras.Get(key));
System.Diagnostics.Debug.WriteLine(
$"{PushNotificationContants.DomainName} - GCM Listener - Push Params {key} : {extras.Get(key)}");
}
var context = global::Android.App.Application.Context;
CrossPushNotification.PushNotificationListener.OnMessage(values, Device.Android);
try
{
var notifyId = 0;
var title = context.ApplicationInfo.LoadLabel(context.PackageManager);
var message = string.Empty;
var tag = string.Empty;
if(!string.IsNullOrEmpty(CrossPushNotification.NotificationContentTextKey) &&
parameters.ContainsKey(CrossPushNotification.NotificationContentTextKey))
{
message = parameters[CrossPushNotification.NotificationContentTextKey].ToString();
}
else if(parameters.ContainsKey(PushNotificationContants.Alert))
{
message = parameters[PushNotificationContants.Alert].ToString();
}
else if(parameters.ContainsKey(PushNotificationContants.Message))
{
message = parameters[PushNotificationContants.Message].ToString();
}
else if(parameters.ContainsKey(PushNotificationContants.Subtitle))
{
message = parameters[PushNotificationContants.Subtitle].ToString();
}
else if(parameters.ContainsKey(PushNotificationContants.Text))
{
message = parameters[PushNotificationContants.Text].ToString();
}
if(!string.IsNullOrEmpty(CrossPushNotification.NotificationContentTitleKey) &&
parameters.ContainsKey(CrossPushNotification.NotificationContentTitleKey))
{
title = parameters[CrossPushNotification.NotificationContentTitleKey].ToString();
}
else if(parameters.ContainsKey(PushNotificationContants.Title))
{
if(!string.IsNullOrEmpty(message))
{
title = parameters[PushNotificationContants.Title].ToString();
}
else
{
message = parameters[PushNotificationContants.Title].ToString();
}
}
if(string.IsNullOrEmpty(message))
{
var data = (
!string.IsNullOrEmpty(CrossPushNotification.NotificationContentDataKey) &&
values[CrossPushNotification.NotificationContentDataKey] != null) ?
values[CrossPushNotification.NotificationContentDataKey] :
values[PushNotificationContants.Data];
if(data != null)
{
if(!string.IsNullOrEmpty(CrossPushNotification.NotificationContentTextKey) &&
data[CrossPushNotification.NotificationContentTextKey] != null)
{
message = data[CrossPushNotification.NotificationContentTextKey].ToString();
}
else if(data[PushNotificationContants.Alert] != null)
{
message = data[PushNotificationContants.Alert].ToString();
}
else if(data[PushNotificationContants.Message] != null)
{
message = data[PushNotificationContants.Message].ToString();
}
else if(data[PushNotificationContants.Subtitle] != null)
{
message = data[PushNotificationContants.Subtitle].ToString();
}
else if(data[PushNotificationContants.Text] != null)
{
message = data[PushNotificationContants.Text].ToString();
}
if(!string.IsNullOrEmpty(CrossPushNotification.NotificationContentTitleKey) &&
data[CrossPushNotification.NotificationContentTitleKey] != null)
{
title = data[CrossPushNotification.NotificationContentTitleKey].ToString();
}
else if(data[PushNotificationContants.Title] != null)
{
if(!string.IsNullOrEmpty(message))
{
title = data[PushNotificationContants.Title].ToString();
}
else
{
message = data[PushNotificationContants.Title].ToString();
}
}
}
}
if(parameters.ContainsKey(PushNotificationContants.Id))
{
var str = parameters[PushNotificationContants.Id].ToString();
try
{
notifyId = Convert.ToInt32(str);
}
catch(Exception)
{
// Keep the default value of zero for the notify_id, but log the conversion problem.
System.Diagnostics.Debug.WriteLine("Failed to convert {0} to an integer", str);
}
}
if(parameters.ContainsKey(PushNotificationContants.Tag))
{
tag = parameters[PushNotificationContants.Tag].ToString();
}
if(!parameters.ContainsKey(PushNotificationContants.Silent) ||
!System.Boolean.Parse(parameters[PushNotificationContants.Silent].ToString()))
{
if(CrossPushNotification.PushNotificationListener.ShouldShowNotification())
{
CreateNotification(title, message, notifyId, tag, extras);
}
}
}
catch(Java.Lang.Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
catch(Exception ex1)
{
System.Diagnostics.Debug.WriteLine(ex1.ToString());
}
}
}
private void CreateNotification(string title, string message, int notifyId, string tag, Bundle extras)
{
System.Diagnostics.Debug.WriteLine(
$"{PushNotificationContants.DomainName} - PushNotification - Message {title} : {message}");
NotificationCompat.Builder builder = null;
var context = global::Android.App.Application.Context;
if(CrossPushNotification.SoundUri == null)
{
CrossPushNotification.SoundUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
}
try
{
if(CrossPushNotification.IconResource == 0)
{
CrossPushNotification.IconResource = context.ApplicationInfo.Icon;
}
else
{
var name = context.Resources.GetResourceName(CrossPushNotification.IconResource);
if(name == null)
{
CrossPushNotification.IconResource = context.ApplicationInfo.Icon;
}
}
}
catch(global::Android.Content.Res.Resources.NotFoundException ex)
{
CrossPushNotification.IconResource = context.ApplicationInfo.Icon;
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
var resultIntent = context.PackageManager.GetLaunchIntentForPackage(context.PackageName);
if(extras != null)
{
resultIntent.PutExtras(extras);
}
// Create a PendingIntent; we're only using one PendingIntent (ID = 0):
const int pendingIntentId = 0;
var resultPendingIntent = PendingIntent.GetActivity(context, pendingIntentId,
resultIntent, PendingIntentFlags.OneShot);
// Build the notification
builder = new NotificationCompat.Builder(context)
.SetAutoCancel(true) // dismiss the notification from the notification area when the user clicks on it
.SetContentIntent(resultPendingIntent) // start up this activity when the user clicks the intent.
.SetContentTitle(title) // Set the title
.SetSound(CrossPushNotification.SoundUri)
.SetSmallIcon(CrossPushNotification.IconResource) // This is the icon to display
.SetContentText(message); // the message to display.
if(Build.VERSION.SdkInt >= BuildVersionCodes.JellyBean)
{
// Using BigText notification style to support long message
var style = new NotificationCompat.BigTextStyle();
style.BigText(message);
builder.SetStyle(style);
}
var notificationManager = (NotificationManager)context.GetSystemService(NotificationService);
notificationManager.Notify(tag, notifyId, builder.Build());
}
private static bool ValidateJSON(string s)
{
try
{
JObject.Parse(s);
return true;
}
catch(JsonReaderException ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
return false;
}
}
}
[BroadcastReceiver(Exported = true, Permission = "com.google.android.c2dm.permission.SEND")]
[IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" },
Categories = new string[] { "com.x8bit.bitwarden" })]
public class PushNotificationsReceiver : GcmReceiver
{ }
[Service]
public class AndroidPushService : Service
{
public override void OnCreate()
{
base.OnCreate();
System.Diagnostics.Debug.WriteLine("Push Notification Service - Created");
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
System.Diagnostics.Debug.WriteLine("Push Notification Service - Started");
return StartCommandResult.Sticky;
}
public override IBinder OnBind(Intent intent)
{
System.Diagnostics.Debug.WriteLine("Push Notification Service - Binded");
return null;
}
public override void OnDestroy()
{
System.Diagnostics.Debug.WriteLine("Push Notification Service - Destroyed");
base.OnDestroy();
}
}
internal class CrossPushNotification
{
private static Lazy<IPushNotificationService> Implementation = new Lazy<IPushNotificationService>(
() => new AndroidPushNotificationService(),
LazyThreadSafetyMode.PublicationOnly);
public static bool IsInitialized => PushNotificationListener != null;
public static IPushNotificationListener PushNotificationListener { get; private set; }
public static string SenderId { get; set; }
public static string NotificationContentTitleKey { get; set; }
public static string NotificationContentTextKey { get; set; }
public static string NotificationContentDataKey { get; set; }
public static int IconResource { get; set; }
public static global::Android.Net.Uri SoundUri { get; set; }
public static void Initialize<T>(T listener, string senderId) where T : IPushNotificationListener
{
SenderId = senderId;
if(PushNotificationListener == null)
{
PushNotificationListener = listener;
System.Diagnostics.Debug.WriteLine("PushNotification plugin initialized.");
}
else
{
System.Diagnostics.Debug.WriteLine("PushNotification plugin already initialized.");
}
}
public static void Initialize<T>(string senderId) where T : IPushNotificationListener, new()
{
Initialize(new T(), senderId);
}
public static IPushNotificationService Current
{
get
{
if(!IsInitialized)
{
throw new Exception("Not initialized.");
}
var ret = Implementation.Value;
if(ret == null)
{
throw new Exception("Not in PCL");
}
return ret;
}
// Do we ever need to unregister?
}
}
}
#endif

View File

@@ -1,6 +1,7 @@
using Android.App;
using Android.Views.Autofill;
using Bit.App.Abstractions;
using Plugin.CurrentActivity;
using System.Linq;
using AndroidApp = Android.App.Application;
@@ -19,7 +20,7 @@ namespace Bit.Android.Services
private bool AutofillAccessibilityRunning()
{
var manager = ((ActivityManager)Xamarin.Forms.Forms.Context.GetSystemService("activity"));
var manager = ((ActivityManager)CrossCurrentActivity.Current.Activity.GetSystemService("activity"));
var services = manager.GetRunningServices(int.MaxValue);
return services.Any(s => s.Process.ToLowerInvariant().Contains("bitwarden") &&
s.Service.ClassName.ToLowerInvariant().Contains("autofill"));
@@ -32,9 +33,9 @@ namespace Bit.Android.Services
return false;
}
var activity = (MainActivity)Xamarin.Forms.Forms.Context;
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
var afm = (AutofillManager)activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager)));
return afm.IsEnabled;
return afm.IsEnabled && afm.HasEnabledAutofillServices;
}
}
}

View File

@@ -23,7 +23,6 @@ using Android.App.Assist;
using Bit.Android.Autofill;
using System.Linq;
using Plugin.Settings.Abstractions;
using Acr.UserDialogs;
using Android.Views.InputMethods;
namespace Bit.Android.Services
@@ -31,21 +30,36 @@ namespace Bit.Android.Services
public class DeviceActionService : IDeviceActionService
{
private readonly IAppSettingsService _appSettingsService;
private readonly IUserDialogs _userDialogs;
private bool _cameraPermissionsDenied;
private DateTime? _lastAction;
private ProgressDialog _progressDialog;
private global::Android.Widget.Toast _toast;
public DeviceActionService(
IAppSettingsService appSettingsService,
IUserDialogs userDialogs)
IAppSettingsService appSettingsService)
{
_appSettingsService = appSettingsService;
_userDialogs = userDialogs;
}
private Context CurrentContext => CrossCurrentActivity.Current.Activity;
public void Toast(string text, bool longDuration = false)
{
if(_toast != null)
{
_toast.Cancel();
_toast.Dispose();
_toast = null;
}
_toast = global::Android.Widget.Toast.MakeText(CurrentContext, text,
longDuration ? global::Android.Widget.ToastLength.Long : global::Android.Widget.ToastLength.Short);
_toast.Show();
}
public void CopyToClipboard(string text)
{
var clipboardManager = (ClipboardManager)Forms.Context.GetSystemService(Context.ClipboardService);
var clipboardManager = (ClipboardManager)CurrentContext.GetSystemService(Context.ClipboardService);
clipboardManager.Text = text;
}
@@ -131,7 +145,7 @@ namespace Bit.Android.Services
var hasStorageWritePermission = !_cameraPermissionsDenied && HasPermission(Manifest.Permission.WriteExternalStorage);
var additionalIntents = new List<IParcelable>();
if(Forms.Context.PackageManager.HasSystemFeature(PackageManager.FeatureCamera))
if(CurrentContext.PackageManager.HasSystemFeature(PackageManager.FeatureCamera))
{
var hasCameraPermission = !_cameraPermissionsDenied && HasPermission(Manifest.Permission.Camera);
@@ -181,7 +195,7 @@ namespace Bit.Android.Services
public void Autofill(VaultListPageModel.Cipher cipher)
{
var activity = (MainActivity)Forms.Context;
var activity = (MainActivity)CurrentContext;
if(activity.Intent.GetBooleanExtra("autofillFramework", false))
{
if(cipher == null)
@@ -259,7 +273,7 @@ namespace Bit.Android.Services
public void Background()
{
var activity = (MainActivity)Forms.Context;
var activity = (MainActivity)CurrentContext;
if(activity.Intent.GetBooleanExtra("autofillFramework", false))
{
activity.SetResult(Result.Canceled);
@@ -273,7 +287,7 @@ namespace Bit.Android.Services
public void RateApp()
{
var activity = (MainActivity)Forms.Context;
var activity = (MainActivity)CurrentContext;
try
{
var rateIntent = RateIntentForUrl("market://details", activity);
@@ -288,9 +302,9 @@ namespace Bit.Android.Services
public void DismissKeyboard()
{
var activity = (MainActivity)Forms.Context;
try
{
var activity = (MainActivity)CurrentContext;
var imm = (InputMethodManager)activity.GetSystemService(Context.InputMethodService);
imm.HideSoftInputFromWindow(activity.CurrentFocus.WindowToken, 0);
}
@@ -299,14 +313,14 @@ namespace Bit.Android.Services
public void OpenAccessibilitySettings()
{
var activity = (MainActivity)Forms.Context;
var activity = (MainActivity)CurrentContext;
var intent = new Intent(Settings.ActionAccessibilitySettings);
activity.StartActivity(intent);
}
public void LaunchApp(string appName)
public async Task LaunchAppAsync(string appName, Page page)
{
var activity = (MainActivity)Forms.Context;
var activity = (MainActivity)CurrentContext;
if(_lastAction.LastActionWasRecent())
{
return;
@@ -317,7 +331,7 @@ namespace Bit.Android.Services
var launchIntent = activity.PackageManager.GetLaunchIntentForPackage(appName);
if(launchIntent == null)
{
_userDialogs.Alert(string.Format(AppResources.CannotOpenApp, appName));
await page.DisplayAlert(null, string.Format(AppResources.CannotOpenApp, appName), AppResources.Ok);
}
else
{
@@ -410,10 +424,36 @@ namespace Bit.Android.Services
public void OpenAutofillSettings()
{
var activity = (MainActivity)Forms.Context;
var activity = (MainActivity)CurrentContext;
var intent = new Intent(Settings.ActionRequestSetAutofillService);
intent.SetData(global::Android.Net.Uri.Parse("package:com.x8bit.bitwarden"));
activity.StartActivity(intent);
}
public void ShowLoading(string text)
{
if(_progressDialog != null)
{
HideLoading();
}
var activity = (MainActivity)CurrentContext;
_progressDialog = new ProgressDialog(activity);
_progressDialog.SetMessage(text);
_progressDialog.SetCancelable(true);
_progressDialog.Show();
}
public void HideLoading()
{
if(_progressDialog == null)
{
return;
}
_progressDialog.Dismiss();
_progressDialog.Dispose();
_progressDialog = null;
}
}
}

View File

@@ -3,11 +3,13 @@ using Android.Content.PM;
using Android.OS;
using Android.Views.Autofill;
using Bit.App.Abstractions;
using Plugin.CurrentActivity;
namespace Bit.Android.Services
{
public class DeviceInfoService : IDeviceInfoService
{
public string Type => Xamarin.Forms.Device.Android;
public string Model => Build.Model;
public int Version => (int)Build.VERSION.SdkInt;
public float Scale
@@ -44,7 +46,8 @@ namespace Bit.Android.Services
}
}
public bool NfcEnabled => Utilities.NfcEnabled();
public bool HasCamera => Xamarin.Forms.Forms.Context.PackageManager.HasSystemFeature(PackageManager.FeatureCamera);
public bool HasCamera => CrossCurrentActivity.Current.Activity.PackageManager.HasSystemFeature(
PackageManager.FeatureCamera);
public bool AutofillServiceSupported => AutofillSupported();
public bool HasFaceIdSupport => false;
private bool AutofillSupported()
@@ -53,9 +56,9 @@ namespace Bit.Android.Services
{
return false;
}
var activity = (MainActivity)Xamarin.Forms.Forms.Context;
var afm = (AutofillManager)activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager)));
var afm = (AutofillManager)CrossCurrentActivity.Current.Activity.GetSystemService(
Java.Lang.Class.FromType(typeof(AutofillManager)));
return afm.IsAutofillSupported;
}
}

View File

@@ -1,4 +1,5 @@
using System;
#if !FDROID
using System;
using Bit.App;
using Bit.App.Abstractions;
using Plugin.Settings.Abstractions;
@@ -80,3 +81,4 @@ namespace Bit.Android.Services
}
}
}
#endif

View File

@@ -54,7 +54,7 @@ namespace Bit.Android.Services
if(androidLanguage.StartsWith("zh"))
{
if(androidLanguage.Contains("Hant"))
if(androidLanguage.Contains("Hant") || androidLanguage.Contains("TW"))
{
netLanguage = "zh-Hant";
}
@@ -63,11 +63,6 @@ namespace Bit.Android.Services
netLanguage = "zh-Hans";
}
}
else if(androidLanguage.StartsWith("pt"))
{
// only Portuguese Europe for now
netLanguage = "pt-PT";
}
else
{
// certain languages need to be converted to CultureInfo equivalent

View File

@@ -1,44 +0,0 @@
using System;
using Android.Content;
using Bit.App.Abstractions;
using Xamarin.Forms;
namespace Bit.Android.Services
{
public class MemoryService : IMemoryService
{
public MemoryInfo GetInfo()
{
return MemoryHelper.GetMemoryInfo(Forms.Context);
}
public void Check()
{
MemoryHelper.MemoryCheck(Forms.Context);
}
public static class MemoryHelper
{
public static void MemoryCheck(Context context)
{
Console.WriteLine("MemoryHelper.MemoryCheck.{0} - {1}", "Start", context.ToString());
var maxMemory = Java.Lang.Runtime.GetRuntime().MaxMemory();
var freeMemory = Java.Lang.Runtime.GetRuntime().FreeMemory();
var percentUsed = (maxMemory - freeMemory) / (double)maxMemory;
Console.WriteLine("Free memory: {0:N}", freeMemory);
Console.WriteLine("Max memory: {0:N}", maxMemory);
Console.WriteLine("% used: {0:P}", percentUsed);
Console.WriteLine("MemoryHelper.MemoryCheck.{0} {3:P} {1} out of {2}", "End", freeMemory, maxMemory, percentUsed);
}
public static MemoryInfo GetMemoryInfo(Context context)
{
var retVal = new MemoryInfo();
retVal.MaxMemory = Java.Lang.Runtime.GetRuntime().MaxMemory();
retVal.FreeMemory = Java.Lang.Runtime.GetRuntime().FreeMemory();
retVal.TotalMemory = Java.Lang.Runtime.GetRuntime().TotalMemory();
return retVal;
}
}
}
}

View File

@@ -1,34 +0,0 @@
using System;
using System.Reflection;
using Bit.App.Abstractions;
using Bit.App.Controls;
using Xamarin.Forms;
namespace Bit.Android.Services
{
public class ReflectionService : IReflectionService
{
public Func<double, double, SizeRequest> GetVisualElementOnSizeRequest(ExtendedTableView tableView)
{
var handle = typeof(VisualElement).GetMethod(
"OnSizeRequest",
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new Type[] { typeof(double), typeof(double) },
null)?.MethodHandle;
if(!handle.HasValue)
{
throw new ArgumentNullException("handle could not be found.");
}
var pointer = handle.Value.GetFunctionPointer();
if(pointer == null)
{
throw new ArgumentNullException("pointer could not be found.");
}
return (Func<double, double, SizeRequest>)Activator.CreateInstance(typeof(Func<double, double, SizeRequest>), tableView, pointer);
}
}
}

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Validation" publicKeyToken="2fc06f0d701809a7" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.3.0.0" newVersion="2.3.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="SimpleInjector" publicKeyToken="984cb50dea722e99" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.8.0" newVersion="4.0.8.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="PInvoke.BCrypt" publicKeyToken="9e300f9f87f04a7a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.5.0.0" newVersion="0.5.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,90 @@
$rootPath = $env:APPVEYOR_BUILD_FOLDER;
$androidPath = $($rootPath + "\src\Android\Android.csproj");
$appPath = $($rootPath + "\src\App\App.csproj");
echo "##### Increment Version"
$androidManifest = $($rootPath + "\src\Android\Properties\AndroidManifest.xml");
$xml=New-Object XML;
$xml.Load($androidManifest);
$node=$xml.SelectNodes("/manifest");
$node.SetAttribute("android:versionCode", $env:APPVEYOR_BUILD_NUMBER);
$xml.Save($androidManifest);
echo "##### Decrypt Keystore"
$encKeystorePath = $($rootPath + "\src\Android\8bit.keystore.enc");
$secureFilePath = $($rootPath + "\secure-file\tools\secure-file.exe");
Invoke-Expression "& `"$secureFilePath`" -decrypt $($encKeystorePath) -secret $($env:keystore_dec_secret)"
echo "##### Sign Release Configuration"
msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" "/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:keystore_password)" "/p:AndroidSigningKeyStore=8bit.keystore" "/p:AndroidSigningStorePass=$($env:keystore_password)" "/v:quiet"
echo "##### Copy Release apk to project root"
$signedApkPath = $($rootPath + "\src\Android\bin\Release\com.x8bit.bitwarden-Signed.apk");
$signedApkDestPath = $($rootPath + "\com.x8bit.bitwarden-" + $env:APPVEYOR_BUILD_NUMBER + ".apk");
Copy-Item $signedApkPath $signedApkDestPath
echo "##### Clean Android and App"
msbuild "$($androidPath)" "/t:Clean" "/p:Configuration=FDroid"
msbuild "$($appPath)" "/t:Clean" "/p:Configuration=FDroid"
echo "##### Backup project files"
Copy-Item $androidPath $($androidPath + ".original");
Copy-Item $appPath $($appPath + ".original");
echo "##### Uninstall from Android.csproj"
$xml=New-Object XML;
$xml.Load($androidPath);
$ns=New-Object System.Xml.XmlNamespaceManager($xml.NameTable);
$ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI);
$firebaseNode=$xml.SelectSingleNode("/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.Firebase.Messaging']", $ns);
$firebaseNode.ParentNode.RemoveChild($firebaseNode);
$playServiceNode=$xml.SelectSingleNode("/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.GooglePlayServices.Analytics']", $ns);
$playServiceNode.ParentNode.RemoveChild($playServiceNode);
$xml.Save($androidPath);
echo "##### Uninstall from App.csproj"
$xml=New-Object XML;
$xml.Load($appPath);
$hockeyNode=$xml.SelectSingleNode("/Project/ItemGroup/PackageReference[@Include='HockeySDK.Xamarin']");
$hockeyNode.ParentNode.RemoveChild($hockeyNode);
$xml.Save($appPath);
echo "##### Restore NuGet"
$nugetPath = $($rootPath + "\nuget.exe");
Invoke-Expression "& `"$nugetPath`" restore"
echo "##### Build and Sign FDroid Configuration"
msbuild "$($androidPath)" "/logger:C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" "/p:Configuration=FDroid"
msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=FDroid" "/p:AndroidKeyStore=true" "/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:keystore_password)" "/p:AndroidSigningKeyStore=8bit.keystore" "/p:AndroidSigningStorePass=$($env:keystore_password)" "/v:quiet"
echo "##### Copy FDroid apk to project root"
$signedApkPath = $($rootPath + "\src\Android\bin\FDroid\com.x8bit.bitwarden-Signed.apk");
$signedApkDestPath = $($rootPath + "\com.x8bit.bitwarden-fdroid-" + $env:APPVEYOR_BUILD_NUMBER + ".apk");
Copy-Item $signedApkPath $signedApkDestPath
echo "##### Done"

View File

@@ -0,0 +1,42 @@
{
"project_info": {
"project_number": "1093287226212",
"firebase_url": "https://bitwarden-dev.firebaseio.com",
"project_id": "bitwarden-dev",
"storage_bucket": "bitwarden-dev.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:1093287226212:android:f8d67b786db1b844",
"android_client_info": {
"package_name": "com.x8bit.bitwarden"
}
},
"oauth_client": [
{
"client_id": "1093287226212-m4mv8ho387tdgosc9lsltnmruul7ouo0.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyA4Xkn0do7Ky_OLff2L_7MXeNK6s-JVgXg"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}

Binary file not shown.

View File

@@ -1,8 +0,0 @@
$rootPath = $args[0];
$newVersionCode = $args[1];
$xml=New-Object XML;
$xml.Load($rootPath + "\src\Android\Properties\AndroidManifest.xml");
$node=$xml.SelectNodes("/manifest");
$node.SetAttribute("android:versionCode", $newVersionCode);
$xml.Save($rootPath + "\src\Android\Properties\AndroidManifest.xml");

View File

@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Acr.Support" version="2.1.0" targetFramework="monoandroid60" />
<package id="Acr.UserDialogs" version="6.3.10" targetFramework="monoandroid71" />
<package id="AndHUD" version="1.2.0" targetFramework="monoandroid60" />
<package id="BouncyCastle" version="1.8.1" targetFramework="monoandroid60" />
<package id="CommonServiceLocator" version="1.3" targetFramework="monoandroid60" />
<package id="HockeySDK.Xamarin" version="4.1.5" targetFramework="monoandroid71" />
<package id="Microsoft.NETCore.Platforms" version="1.0.1" targetFramework="monoandroid71" />
<package id="Microsoft.Win32.Primitives" version="4.0.1" targetFramework="monoandroid71" />
<package id="NETStandard.Library" version="1.6.0" targetFramework="monoandroid71" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="monoandroid60" />
<package id="PCLCrypto" version="2.0.147" targetFramework="monoandroid60" />
<package id="PInvoke.BCrypt" version="0.5.97" targetFramework="monoandroid71" />
<package id="PInvoke.Kernel32" version="0.5.97" targetFramework="monoandroid71" />
<package id="PInvoke.NCrypt" version="0.5.97" targetFramework="monoandroid71" />
<package id="PInvoke.Windows.Core" version="0.5.97" targetFramework="monoandroid71" />
<package id="Plugin.CurrentActivity" version="1.0.1" targetFramework="monoandroid60" />
<package id="Plugin.Fingerprint" version="1.4.6-beta4" targetFramework="monoandroid80" />
<package id="SimpleInjector" version="4.0.8" targetFramework="monoandroid71" />
<package id="Splat" version="1.6.2" targetFramework="monoandroid60" />
<package id="sqlite-net-pcl" version="1.5.166-beta" targetFramework="monoandroid71" />
<package id="SQLitePCLRaw.bundle_green" version="1.1.8" targetFramework="monoandroid71" />
<package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="monoandroid71" />
<package id="SQLitePCLRaw.lib.e_sqlite3.android" version="1.1.8" targetFramework="monoandroid71" />
<package id="SQLitePCLRaw.provider.e_sqlite3.android" version="1.1.8" targetFramework="monoandroid71" />
<package id="System.AppContext" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Collections" version="4.0.11" targetFramework="monoandroid71" />
<package id="System.Collections.Concurrent" version="4.0.12" targetFramework="monoandroid71" />
<package id="System.ComponentModel" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.Console" version="4.0.0" targetFramework="monoandroid71" />
<package id="System.Diagnostics.Debug" version="4.0.11" targetFramework="monoandroid71" />
<package id="System.Diagnostics.Tools" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.Diagnostics.Tracing" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Globalization" version="4.0.11" targetFramework="monoandroid71" />
<package id="System.Globalization.Calendars" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.IO" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.IO.Compression" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.IO.Compression.ZipFile" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.IO.FileSystem" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.IO.FileSystem.Primitives" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.Linq" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Linq.Expressions" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Net.Http" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Net.Primitives" version="4.0.11" targetFramework="monoandroid71" />
<package id="System.Net.Sockets" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.ObjectModel" version="4.0.12" targetFramework="monoandroid71" />
<package id="System.Reflection" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Reflection.Extensions" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.Reflection.Primitives" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.Runtime" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Runtime.Extensions" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Runtime.Handles" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.0.0" targetFramework="monoandroid71" />
<package id="System.Runtime.Numerics" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.Security.Cryptography.Algorithms" version="4.2.0" targetFramework="monoandroid71" />
<package id="System.Security.Cryptography.Encoding" version="4.0.0" targetFramework="monoandroid71" />
<package id="System.Security.Cryptography.Primitives" version="4.0.0" targetFramework="monoandroid71" />
<package id="System.Security.Cryptography.X509Certificates" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Text.Encoding" version="4.0.11" targetFramework="monoandroid71" />
<package id="System.Text.Encoding.Extensions" version="4.0.11" targetFramework="monoandroid71" />
<package id="System.Text.RegularExpressions" version="4.1.0" targetFramework="monoandroid71" />
<package id="System.Threading" version="4.0.11" targetFramework="monoandroid71" />
<package id="System.Threading.Tasks" version="4.0.11" targetFramework="monoandroid71" />
<package id="System.Threading.Timer" version="4.0.1" targetFramework="monoandroid71" />
<package id="System.Xml.ReaderWriter" version="4.0.11" targetFramework="monoandroid71" />
<package id="System.Xml.XDocument" version="4.0.11" targetFramework="monoandroid71" />
<package id="Validation" version="2.3.7" targetFramework="monoandroid60" />
<package id="Xam.Plugin.Connectivity" version="3.0.2" targetFramework="monoandroid71" />
<package id="Xam.Plugins.Settings" version="3.0.1" targetFramework="monoandroid71" />
<package id="Xamarin.Android.Support.Animated.Vector.Drawable" version="23.3.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.Design" version="23.3.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.v4" version="23.3.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.v7.AppCompat" version="23.3.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.v7.CardView" version="23.3.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.v7.MediaRouter" version="23.3.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.v7.RecyclerView" version="23.3.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.Vector.Drawable" version="23.3.0" targetFramework="monoandroid60" />
<package id="Xamarin.FFImageLoading" version="2.2.9" targetFramework="monoandroid71" />
<package id="Xamarin.FFImageLoading.Forms" version="2.2.9" targetFramework="monoandroid71" />
<package id="Xamarin.Forms" version="2.3.4.267" targetFramework="monoandroid71" />
<package id="Xamarin.GooglePlayServices.Analytics" version="29.0.0.2" targetFramework="monoandroid60" />
<package id="Xamarin.GooglePlayServices.Base" version="29.0.0.2" targetFramework="monoandroid60" />
<package id="Xamarin.GooglePlayServices.Basement" version="29.0.0.2" targetFramework="monoandroid60" />
<package id="Xamarin.GooglePlayServices.Gcm" version="29.0.0.2" targetFramework="monoandroid60" />
<package id="Xamarin.GooglePlayServices.Measurement" version="29.0.0.2" targetFramework="monoandroid60" />
<package id="XLabs.IoC" version="2.0.5782" targetFramework="monoandroid60" />
<package id="XLabs.IoC.SimpleInjector" version="2.0.5782" targetFramework="monoandroid71" />
<package id="ZXing.Net.Mobile" version="2.1.47" targetFramework="monoandroid71" />
<package id="ZXing.Net.Mobile.Forms" version="2.1.47" targetFramework="monoandroid71" />
</packages>

View File

@@ -4,8 +4,8 @@ namespace Bit.App.Abstractions
{
public interface IAppSettingsService
{
bool DefaultPageVault { get; set; }
bool Locked { get; set; }
int FailedPinAttempts { get; set; }
DateTime LastActivity { get; set; }
DateTime LastCacheClear { get; set; }
bool AutofillPersistNotification { get; set; }

View File

@@ -1,10 +1,14 @@
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Bit.App.Abstractions
{
public interface IDeviceActionService
{
void ShowLoading(string text);
void HideLoading();
void Toast(string text, bool longDuration = false);
void CopyToClipboard(string text);
bool OpenFile(byte[] fileData, string id, string fileName);
bool CanOpenFile(string fileName);
@@ -17,6 +21,6 @@ namespace Bit.App.Abstractions
void DismissKeyboard();
void OpenAccessibilitySettings();
void OpenAutofillSettings();
void LaunchApp(string appName);
Task LaunchAppAsync(string appName, Page page);
}
}

View File

@@ -2,6 +2,7 @@
{
public interface IDeviceInfoService
{
string Type { get; }
string Model { get; }
int Version { get; }
float Scale { get; }

View File

@@ -6,7 +6,7 @@ namespace Bit.App.Abstractions
{
public interface ILockService
{
void UpdateLastActivity(DateTime? activityDate = null);
void UpdateLastActivity();
Task<LockType> GetLockTypeAsync(bool forceLock);
Task CheckLockAsync(bool forceLock);
bool TopPageIsLock();

View File

@@ -1,26 +0,0 @@
namespace Bit.App.Abstractions
{
public interface IMemoryService
{
MemoryInfo GetInfo();
void Check();
}
public class MemoryInfo
{
public long FreeMemory { get; set; }
public long MaxMemory { get; set; }
public long TotalMemory { get; set; }
public long UsedMemory => TotalMemory - FreeMemory;
public double HeapUsage()
{
return UsedMemory / (double)TotalMemory;
}
public double Usage()
{
return UsedMemory / (double)MaxMemory;
}
}
}

View File

@@ -1,11 +0,0 @@
using System;
using Bit.App.Controls;
using Xamarin.Forms;
namespace Bit.App.Abstractions
{
public interface IReflectionService
{
Func<double, double, SizeRequest> GetVisualElementOnSizeRequest(ExtendedTableView tableView);
}
}

View File

@@ -9,8 +9,6 @@ using Plugin.Settings.Abstractions;
using Bit.App.Controls;
using Plugin.Connectivity.Abstractions;
using System.Net;
using Acr.UserDialogs;
using XLabs.Ioc;
using System.Reflection;
using Bit.App.Resources;
using Bit.App.Utilities;
@@ -21,14 +19,12 @@ namespace Bit.App
public class App : Application
{
private AppOptions _options;
private readonly IAuthService _authService;
private readonly IDatabaseService _databaseService;
private readonly IConnectivity _connectivity;
private readonly IUserDialogs _userDialogs;
private readonly ISyncService _syncService;
private readonly IAuthService _authService;
private readonly ISettings _settings;
private readonly ILockService _lockService;
private readonly IGoogleAnalyticsService _googleAnalyticsService;
private readonly ILocalizeService _localizeService;
private readonly IAppInfoService _appInfoService;
private readonly IAppSettingsService _appSettingsService;
@@ -38,26 +34,22 @@ namespace Bit.App
AppOptions options,
IAuthService authService,
IConnectivity connectivity,
IUserDialogs userDialogs,
IDatabaseService databaseService,
ISyncService syncService,
ISettings settings,
ILockService lockService,
IGoogleAnalyticsService googleAnalyticsService,
ILocalizeService localizeService,
IAppInfoService appInfoService,
IAppSettingsService appSettingsService,
IDeviceActionService deviceActionService)
{
_options = options ?? new AppOptions();
_authService = authService;
_databaseService = databaseService;
_connectivity = connectivity;
_userDialogs = userDialogs;
_syncService = syncService;
_authService = authService;
_settings = settings;
_lockService = lockService;
_googleAnalyticsService = googleAnalyticsService;
_localizeService = localizeService;
_appInfoService = appInfoService;
_appSettingsService = appSettingsService;
@@ -78,7 +70,7 @@ namespace Bit.App
}
else
{
MainPage = new MainPage(myVault: _options.MyVault);
MainPage = new MainPage();
}
}
else
@@ -88,9 +80,9 @@ namespace Bit.App
if(Device.RuntimePlatform == Device.iOS)
{
MessagingCenter.Subscribe<Application, bool>(Current, "Resumed", async (sender, args) =>
MessagingCenter.Subscribe<Application, bool>(Current, "Resumed", async (sender, forceLock) =>
{
Device.BeginInvokeOnMainThread(async () => await _lockService.CheckLockAsync(args));
Device.BeginInvokeOnMainThread(async () => await _lockService.CheckLockAsync(forceLock));
await Task.Run(() => FullSyncAsync()).ConfigureAwait(false);
});
}
@@ -291,7 +283,7 @@ namespace Bit.App
// List View
Resources.Add(new Style(typeof(ListView))
Resources.Add(new Style(typeof(ExtendedListView))
{
Setters = {
new Setter { Property = ListView.SeparatorColorProperty, Value = grayLighter }

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