Compare commits

...

673 Commits

Author SHA1 Message Date
akwizgran
89f50bbdaf Bump version numbers for beta release. 2018-03-29 16:38:03 +01:00
akwizgran
3eed7df1a4 Merge branch '1171-wifi-access-point' into 'maintenance-0.16'
Backport: Enable LAN plugin when providing a wifi access point

See merge request akwizgran/briar!755
2018-03-29 15:36:11 +00:00
akwizgran
f7af0dc3b0 Delay handling of AP enabled event. 2018-03-29 16:19:03 +01:00
akwizgran
fbaf446570 AP state change event races with address appearing. 2018-03-29 16:19:03 +01:00
akwizgran
fb6d962131 Enable LAN plugin to use wifi AP interface. 2018-03-29 16:19:03 +01:00
akwizgran
d007de48ac Serialise concurrent calls to updateConnectionStatus(). 2018-03-29 16:19:03 +01:00
akwizgran
95a08eed5c Serialise concurrent calls to bind(). 2018-03-29 16:19:02 +01:00
akwizgran
040894b205 Merge branch '1190-shutdown-from-background' into 'maintenance-0.16'
Backport: Shut down cleanly when phone is shutting down or memory is low

See merge request akwizgran/briar!754
2018-03-29 15:04:21 +00:00
akwizgran
41d3bd4f19 Show notification for low memory shutdown. 2018-03-29 15:50:25 +01:00
akwizgran
347868684c Shut down cleanly when device shuts down. 2018-03-29 15:50:23 +01:00
akwizgran
1038a3532b Shut down cleanly when memory is low. 2018-03-29 15:48:29 +01:00
Torsten Grote
4e6d514a0d Backport translation update, add Romanian 2018-03-29 11:07:31 -03:00
akwizgran
f178ce807f Merge branch '965-empty-state-messages' into 'maintenance-0.16'
Backport: Shorten and clean up various strings, remove empty forum warning bubble

See merge request akwizgran/briar!751
2018-03-29 11:47:53 +00:00
akwizgran
a2c827ef24 Merge branch 'hide-ui-during-shutdown' into 'maintenance-0.16'
Backport: Hide UI during shutdown

See merge request akwizgran/briar!750
2018-03-29 11:39:02 +00:00
akwizgran
9496148182 Merge branch '346-full-screen-qr-code' into 'maintenance-0.16'
Backport: Add fullscreen button to QR code view

See merge request akwizgran/briar!749
2018-03-29 11:29:55 +00:00
akwizgran
bb27ca186a Merge branch '845-wifi-without-internet' into 'maintenance-0.16'
Backport: Use WifiManager to get wifi network information

See merge request akwizgran/briar!748
2018-03-29 11:21:15 +00:00
akwizgran
be38431e03 Merge branch '1184-rejected-execution-exception' into 'maintenance-0.16'
Backport: Discard tasks submitted to ScheduledExecutorService during shutdown

See merge request akwizgran/briar!747
2018-03-29 11:12:23 +00:00
akwizgran
e314b39661 Merge branch '965-forum-empty-state' into 'maintenance-0.16'
Backport: Remove mention of pen icon from forum empty state message

See merge request akwizgran/briar!746
2018-03-29 11:03:28 +00:00
akwizgran
4aa8d0b6c0 Remove empty forum warning bubble. 2018-03-29 12:03:17 +01:00
akwizgran
6220a8c00e Consistent text for blogs and forums. 2018-03-29 12:03:17 +01:00
akwizgran
dcd9b0a637 Shorter empty state messages. 2018-03-29 12:03:16 +01:00
akwizgran
94b17caf0f Consistent explanation of account deletion options. 2018-03-29 12:03:16 +01:00
akwizgran
fce8d9fa9f Finish if back button is pressed in SignOutFragment. 2018-03-29 12:00:41 +01:00
akwizgran
f4c798a2da Use database icon for SignOutFragment. 2018-03-29 12:00:41 +01:00
akwizgran
accef2e51b Close NavDrawerActivity immediately when signing out. 2018-03-29 12:00:41 +01:00
akwizgran
34b4c35f44 Use selectable item background to get touch effect. 2018-03-29 11:55:47 +01:00
akwizgran
9b253fc965 Adjust layout weights when resizing QR code view. 2018-03-29 11:55:46 +01:00
akwizgran
4d97cad842 Add fullscreen button to QR code view. 2018-03-29 11:55:46 +01:00
akwizgran
ba99f58559 Use wifi network's socket factory on API 21+. 2018-03-29 11:53:03 +01:00
akwizgran
edbb0a3c13 Use WifiManager to get wifi network information.
This ensures we bind to the wifi interface even if it doesn't have internet access and there's another interface with internet access (e.g. mobile data).
2018-03-29 11:53:03 +01:00
akwizgran
fdbcc0736c Discard tasks submitted during shutdown. 2018-03-29 11:50:21 +01:00
akwizgran
f4722b2a67 Remove mention of pen icon from forum empty state message. 2018-03-29 11:48:29 +01:00
akwizgran
d316e126a9 Merge branch '1159-android-8-notification-settings' into 'maintenance-0.16'
Backport: Overhaul notifications for Android 8

See merge request akwizgran/briar!744
2018-03-29 10:24:09 +00:00
Torsten Grote
20bd72844c Use a different notification preference summary for Android 8 2018-03-26 13:38:55 -03:00
Torsten Grote
02c88eb907 Show different notification settings for Android O
This also makes the defaults consistent with Android versions below O.
2018-03-26 13:38:54 -03:00
akwizgran
1afc0d4fda Merge branch '545-remove-clientid-from-validator-db-methods' into 'maintenance-0.16'
Backport: Remove client ID from validator's DB methods

See merge request akwizgran/briar!738
2018-03-20 17:33:30 +00:00
akwizgran
5a7f39df4d Backport some inconsequential changes from master.
Should make it easier to backport test changes in future.
2018-03-20 17:24:36 +00:00
akwizgran
e30b190209 Remove client ID from validator's DB methods. 2018-03-20 17:23:26 +00:00
akwizgran
31d35a7dd8 Merge branch '1177-blank-viewfinder' into 'maintenance-0.16'
Backport: Show viewfinder again after connection fails

See merge request akwizgran/briar!736
2018-03-20 16:05:57 +00:00
akwizgran
53f85d4b71 When resetting, restart camera if we've stopped it. 2018-03-20 15:51:06 +00:00
akwizgran
54b0bb6084 Don't create a stack of QR code fragments. 2018-03-20 15:38:34 +00:00
akwizgran
f2cfca1460 Remove performance logging. 2018-03-20 15:38:31 +00:00
akwizgran
0cbdc47649 Merge branch '545-denormalise-statuses' into 'maintenance-0.16'
Backport: Add denormalised columns to statuses table

See merge request akwizgran/briar!730
2018-03-09 15:41:37 +00:00
Torsten Grote
536853343e Merge branch '1169-settings-npe' into 'maintenance-0.16'
Backport: Disable settings until they have been loaded

See merge request akwizgran/briar!731
2018-03-08 15:58:33 +00:00
akwizgran
93de06ed0c Merge branch '1181-blurry-error-icon' into 'maintenance-0.16'
Unblur error icon

See merge request akwizgran/briar!729
2018-03-08 15:57:20 +00:00
Torsten Grote
d7f5da305a Disable settings until they have been loaded
In practise, this is not noticeable in the UI.
Only when the database is congested, it should become visible and
prevent a crash when the sound setting is clicked.
2018-03-08 12:45:46 -03:00
Torsten Grote
7c48bc5a00 Unblur error icon 2018-03-08 11:54:12 -03:00
akwizgran
9493e242cc Add migration to schema version 32. 2018-03-08 14:49:22 +00:00
akwizgran
3e28323ab1 Test that visibility change affects expected contacts. 2018-03-08 12:36:30 +00:00
akwizgran
c7e496230b Add denormalised columns to statuses table. 2018-03-08 12:35:46 +00:00
akwizgran
7f8e96a654 Bump version numbers for beta release. 2018-03-07 17:10:28 +00:00
akwizgran
84e040605b Don't reuse the same ConnectionChooser every time.
This is a fix for a backporting mistake.
2018-03-07 16:47:08 +00:00
akwizgran
b0aa1517e5 Merge branch '283-key-exchange-connections' into 'maintenance-0.16'
Backport: Refactor key agreement connection choosing

See merge request akwizgran/briar!725
2018-03-07 14:06:09 +00:00
akwizgran
2ac9f567dc Merge branch '1164-store-bluetooth-properties' into 'maintenance-0.16'
Backport: Store Bluetooth address and UUID at first startup

See merge request akwizgran/briar!724
2018-03-07 14:05:08 +00:00
akwizgran
792cfd7d6f Merge branch '790-ask-before-turning-on-bluetooth' into 'maintenance-0.16'
Backport: Ask before turning on Bluetooth to add a contact

See merge request akwizgran/briar!723
2018-03-07 14:04:09 +00:00
Torsten Grote
2112d4fa7d Backport: Update translations 2018-03-07 09:57:42 -03:00
akwizgran
31ca04e070 Merge branch '1001-bluetooth-connects-to-contacts' into 'maintenance-0.16'
Backport: Don't make Bluetooth connections when configured not to

See merge request akwizgran/briar!722
2018-03-07 12:36:17 +00:00
akwizgran
9693a5cb93 Refactor key agreement connection choosing. 2018-03-07 12:27:05 +00:00
akwizgran
82266345ae Merge branch 'bluetooth-refactoring' into 'maintenance-0.16'
Backport: Factor shared Bluetooth code into superclass

See merge request akwizgran/briar!721
2018-03-07 12:24:38 +00:00
akwizgran
0942fe6053 Merge branch 'transport-indicators-no-buttons' into 'maintenance-0.16'
Backport: Prevent transport indicators from looking like buttons

See merge request akwizgran/briar!720
2018-03-07 12:16:16 +00:00
akwizgran
4a1f58705d Address review comments. 2018-03-07 12:10:31 +00:00
akwizgran
cfe0d9a656 Don't set running = true until properties have been loaded. 2018-03-07 12:10:31 +00:00
akwizgran
3cf61e7b3d Store Bluetooth address and UUID at first startup. 2018-03-07 12:10:31 +00:00
akwizgran
7bb7f8ad5b Fix import of wrong Immutable annotation. 2018-03-07 12:09:37 +00:00
akwizgran
fc50bb1c6c Ask before turning on Bluetooth to add a contact. 2018-03-07 12:09:37 +00:00
akwizgran
19be4d6edf Remove unnecessary executor calls. 2018-03-07 12:08:56 +00:00
akwizgran
b2e4de91a4 Don't make Bluetooth connections when configured not to. 2018-03-07 12:08:56 +00:00
akwizgran
9b184fe1d9 Merge branch '1174-link-click-crash' into 'maintenance-0.16'
Backport: Get unwrapped context when clicking links to prevent crash on Android 4

See merge request akwizgran/briar!719
2018-03-07 12:00:27 +00:00
akwizgran
f4ddc01641 Factor shared Bluetooth code into superclass. 2018-03-07 11:56:52 +00:00
akwizgran
08b63201d9 Merge branch 'fix-intro-fragment' into 'maintenance-0.16'
Backport: Fix uncentered intro fragment

See merge request akwizgran/briar!718
2018-03-07 11:52:22 +00:00
Torsten Grote
1c41181f1c Prevent transport indicators from looking like buttons 2018-03-07 11:50:18 +00:00
Torsten Grote
246b330b36 Passing in reference to FragmentManager when clicking links to prevent crash on Android 4 2018-03-07 11:39:24 +00:00
akwizgran
fd3e74cefc Merge branch '1168-startup-status-screen' into 'maintenance-0.16'
Backport: Show status message while opening and migrating DB

See merge request akwizgran/briar!717
2018-03-07 11:31:24 +00:00
goapunk
ef12191ec8 fix uncentered intro fragment
Signed-off-by: goapunk <noobie@goapunks.net>
2018-03-07 11:25:18 +00:00
akwizgran
a9fc310762 Merge branch '1176-startup-failure-crash' into 'maintenance-0.16'
Backport: Inject StartupFailureActivity to prevent NPE

See merge request akwizgran/briar!716
2018-03-07 11:14:49 +00:00
akwizgran
0a70c2d44d Add more lifecycle states, merge lifecycle events. 2018-03-07 11:07:28 +00:00
Torsten Grote
af1fc6f095 Start NavDrawerActivity only after database was opened and services started 2018-03-07 11:07:27 +00:00
Torsten Grote
21956f2627 Show a status screen when opening the database or applying migrations 2018-03-07 11:07:24 +00:00
akwizgran
55db6e524a Merge branch '346-qr-code-optimisations' into 'maintenance-0.16'
Backport: Improve QR code scanning on phones with high res cameras and slow CPUs

See merge request akwizgran/briar!715
2018-03-07 11:06:56 +00:00
Torsten Grote
dac3de24e7 Do not show splash screen when signed in 2018-03-07 11:05:17 +00:00
akwizgran
f93f41893e Inject StartupFailureActivity to prevent NPE. 2018-03-07 11:00:31 +00:00
akwizgran
7dacb43e01 Don't stop camera view when QR code is scanned. 2018-03-07 10:54:27 +00:00
akwizgran
6a962bad24 Use ConstraintLayout for intro fragment. 2018-03-07 10:47:37 +00:00
akwizgran
489c0154e9 Add javadoc links. 2018-03-07 10:47:37 +00:00
akwizgran
85dc99da72 Crop camera preview before looking for QR code. 2018-03-07 10:47:35 +00:00
akwizgran
ec808fd9f7 Add landscape layout for QR code fragment. 2018-03-07 10:45:49 +00:00
Torsten Grote
4c661cd4bb Merge branch '1154-fix-notification-light' into 'maintenance-0.16'
Backport: Fix notification light

See merge request akwizgran/briar!713
2018-03-06 18:17:46 +00:00
Torsten Grote
6324fb72a5 Fix notification light 2018-03-06 15:04:50 -03:00
akwizgran
d3aebc4aba Merge branch '1136-startup-failure-ux' into 'maintenance-0.16'
Backport: Improve UX for startup failures

See merge request akwizgran/briar!707
2018-02-28 10:26:48 +00:00
Torsten Grote
65c0e110c5 Improve UX for startup failures
Show a proper error message when database is too new or too old.
2018-02-26 14:49:01 -03:00
Torsten Grote
67aeb40d34 Backport ErrorFragment 2018-02-26 14:49:00 -03:00
akwizgran
8280b2e3b8 Inject StartupFailureActivity to prevent NPE. 2018-02-26 14:49:00 -03:00
akwizgran
4e0b9145c1 Merge branch '542-retransmission' into 'maintenance-0.16'
Backport: Don't poll for retransmission

See merge request akwizgran/briar!703
2018-02-22 12:45:48 +00:00
akwizgran
0ad4f2f39b Don't poll for retransmission. 2018-02-22 12:36:33 +00:00
akwizgran
812522a900 Bump version numbers for beta release. 2018-02-19 16:40:47 +00:00
akwizgran
98db9da4bc Merge branch '509-tap-viewfinder-to-auto-focus' into 'maintenance-0.16'
Backport: Tap viewfinder to restart auto focus

See merge request akwizgran/briar!701
2018-02-19 16:20:16 +00:00
akwizgran
eda3c964aa Merge branch '1137-stop-polling-disabled-plugins' into 'maintenance-0.16'
Backport: Don't poll disabled transport plugins

See merge request akwizgran/briar!700
2018-02-19 16:03:15 +00:00
akwizgran
68df606146 Tap viewfinder to restart auto focus. 2018-02-19 15:58:20 +00:00
akwizgran
52bd699d2d Don't poll disabled transport plugins. 2018-02-19 15:53:43 +00:00
Torsten Grote
abb8db10db Merge branch 'migration-30-31' into 'maintenance-0.16'
Beta: Migrate DB schema from version 30 to 31

See merge request akwizgran/briar!690
2018-02-18 17:58:48 +00:00
akwizgran
30edb90426 Add migration from schema 30 to 31. 2018-02-02 17:01:49 +00:00
akwizgran
ffc94b2812 Merge branch '545-remove-unnecessary-indexes' into 'maintenance-0.16'
Backport: Remove unnecessary DB indexes

See merge request akwizgran/briar!692
2018-02-02 17:00:00 +00:00
akwizgran
35a7bb4576 Merge branch '594-db-migrations' into 'maintenance-0.16'
Backport: Migrate schema when opening database

See merge request akwizgran/briar!689
2018-02-02 15:46:39 +00:00
akwizgran
2d87e34aa2 Throw meaningful exceptions for schema errors. 2018-02-02 15:34:49 +00:00
akwizgran
088564f22f Add comment. 2018-02-02 15:34:25 +00:00
akwizgran
8c8c1158f4 Apply more than one migration if suitable. 2018-02-02 15:34:09 +00:00
akwizgran
8faa456eb2 Add unit tests for migration logic. 2018-02-02 15:32:20 +00:00
akwizgran
4c61158326 Migrate database schema if a migration is available. 2018-02-02 15:31:58 +00:00
akwizgran
6792abc00a Remove unnecessary DB indexes. 2018-02-01 17:44:22 +00:00
Torsten Grote
63442aea1d Merge branch '1162-redundant-db-tasks' into 'maintenance-0.16'
Backport: Avoid queueing redundant DB tasks during sync

See merge request akwizgran/briar!685
2018-02-01 16:17:11 +00:00
akwizgran
a58443eaa8 Merge branch '1148-wrong-network-interface' into 'maintenance-0.16'
Backport: Prefer LAN addresses with longer prefixes

See merge request akwizgran/briar!684
2018-02-01 15:48:53 +00:00
akwizgran
14a9614c35 Avoid queueing redundant DB tasks during sync. 2018-02-01 15:48:15 +00:00
akwizgran
f1011b97b3 Merge branch '1143-screen-overlay-dialog' into 'maintenance-0.16'
Backport: Don't show screen overlay dialog if all overlay apps have been allowed

See merge request akwizgran/briar!683
2018-02-01 15:41:55 +00:00
akwizgran
1935b1e09a Add tests for link-local addresses. 2018-02-01 15:40:23 +00:00
akwizgran
ac9df9d5d8 Prefer LAN addresses with longer prefixes. 2018-02-01 15:40:23 +00:00
akwizgran
30a800a4d0 Remove unused argument. 2018-02-01 15:34:16 +00:00
akwizgran
69537b67a2 Simplify dialog handling, work around Android bug. 2018-02-01 15:34:16 +00:00
akwizgran
92982f98a8 Update screen overlay warning text. 2018-02-01 15:34:16 +00:00
akwizgran
ea5fa72224 Re-show dialog when activity resumes or is recreated. 2018-02-01 15:34:16 +00:00
akwizgran
5a1651d483 Set layout weight so checkbox is visible. 2018-02-01 15:34:16 +00:00
akwizgran
fcbf6dfb7f Cache the list of overlay apps. 2018-02-01 15:34:15 +00:00
akwizgran
7aebf92a6f Allow filtered taps if all overlay apps are whitelisted. 2018-02-01 15:34:10 +00:00
akwizgran
1b9f8d4f0b Merge branch '1116-samsung-back-crash' into 'maintenance-0.16'
Backport: Workaround for Samsung crash in Android 4.4

See merge request akwizgran/briar!682
2018-02-01 11:00:28 +00:00
Torsten Grote
93db4eb986 Workaround for Samsung crash in Android 4.4
Closes #1116
2018-02-01 10:41:48 +00:00
akwizgran
347c2f22c1 Bump version numbers for beta release. 2018-01-29 16:48:21 +00:00
Torsten Grote
a8ea191ffb Merge branch '1007-samsung-transition-npe-fix' into 'maintenance-0.16'
Backport: Another attempt at fixing an infamous Samsung activity transition NPE

See merge request akwizgran/briar!678
2018-01-29 14:53:46 +00:00
Torsten Grote
2a4c22757b Another attempt at fixing an infamous Samsung activity transition NPE 2018-01-29 12:36:21 -02:00
Torsten Grote
28ebbbc7d1 Backport translation updates
New translations: br, nl, he, sv, cs, ja
2018-01-29 10:45:12 -02:00
akwizgran
5e7d08f05d Merge branch 'change-password-activity' into 'maintenance-0.16'
Backport: ChangePasswordActivity should extend BriarActivity

See merge request akwizgran/briar!673
2018-01-23 17:36:18 +00:00
akwizgran
ea005748dc Merge branch 'tor-plugin-detect-connectivity-loss' into 'maintenance-0.16'
Backport: Tor plugin should detect connectivity loss

See merge request akwizgran/briar!672
2018-01-23 17:29:28 +00:00
akwizgran
b021bfab5e ChangePasswordActivity should extend BriarActivity. 2018-01-23 17:22:43 +00:00
akwizgran
29cd105a1d Use scheduler service to schedule connectivity checks. 2018-01-23 17:16:59 +00:00
akwizgran
be2e68e96c Listen for a wider range of connectivity-related events. 2018-01-23 17:15:53 +00:00
akwizgran
9dd3f81bb7 Use Tor's OR connection events to detect lost connectivity. 2018-01-23 17:15:53 +00:00
akwizgran
5d918591d4 Merge branch '1145-avoid-unnecessary-db-queries' into 'maintenance-0.16'
Backport: Avoid unnecessary DB queries when starting clients

See merge request akwizgran/briar!669
2018-01-16 15:33:14 +00:00
akwizgran
f1c027fa4d Avoid unnecessary DB queries when starting clients. 2018-01-16 15:23:31 +00:00
akwizgran
d2d3ccf68d Merge branch 'prefer-project-modules' into 'maintenance-0.16'
Backport: Prefer project modules over prebuilt dependencies

See merge request akwizgran/briar!668
2018-01-12 17:55:05 +00:00
akwizgran
f4efed54d5 Prefer project modules over prebuilt dependencies. 2018-01-12 17:35:59 +00:00
akwizgran
459538e40c Bump version numbers for beta release. 2017-12-22 14:43:03 +00:00
akwizgran
183f501761 Merge branch '1132-upgrade-tor-0.2.9.14' into 'maintenance-0.16'
Beta: Upgrade Tor to 0.2.9.14, GeoIP to 2017-11-06

See merge request akwizgran/briar!657
2017-12-22 14:10:52 +00:00
akwizgran
65ee5f539b Upgrade Tor to 0.2.9.14, GeoIP to 2017-11-06. 2017-12-22 13:52:45 +00:00
akwizgran
604339326c Merge branch '1129-send-on-ctrl-enter' into 'maintenance-0.16'
Beta: Send message on ctrl + enter

See merge request akwizgran/briar!656
2017-12-22 11:49:55 +00:00
sbkaf
0acec1343f send message on ctrl + enter 2017-12-22 11:32:15 +00:00
akwizgran
0434756bbd Merge branch '1133-extend-expiry-period' into 'maintenance-0.16'
Extend expiry date, show extension notification

See merge request akwizgran/briar!655
2017-12-22 11:23:40 +00:00
akwizgran
e233433140 Extend expiry date, show extension notification. 2017-12-22 10:58:11 +00:00
akwizgran
c63f285f53 Bumped version numbers for beta release. 2017-12-07 14:13:11 +00:00
akwizgran
0800188718 Merge branch '1112-screen-filter-crash' into 'maintenance-0.16'
Beta: Don't show screen filter dialog after onSaveInstanceState().

See merge request !650
2017-12-07 13:29:27 +00:00
akwizgran
6188e48beb Don't show screen filter dialog after onSaveInstanceState(). 2017-12-07 13:07:07 +00:00
akwizgran
5726e29b56 Merge branch '1088-huawei-whitelisting' into 'maintenance-0.16'
Beta: Add button for Huawei's power manager to setup wizard

See merge request !648
2017-12-07 13:05:34 +00:00
Torsten Grote
5d70399de0 Add button for Huawei's power manager to setup wizard 2017-12-05 15:26:14 -02:00
akwizgran
73202dde5e Merge branch '1127-notification-channels' into 'maintenance-0.16'
Beta: Use channels for all notifications

See merge request !647
2017-12-05 17:03:37 +00:00
akwizgran
a98ac8233c Sort order of channel IDs affects UI of Settings app. 2017-12-05 16:49:31 +00:00
akwizgran
bee3e244fc Use channels for all notifications. 2017-12-05 16:49:31 +00:00
akwizgran
da25999a15 Merge branch '1120-crash-removing-shutdown-hook' into 'maintenance-0.16'
Beta: Don't remove shutdown hook when closing DB

See merge request !645
2017-12-05 14:58:56 +00:00
akwizgran
62049df342 Don't remove shutdown hook when closing DB. 2017-12-05 14:46:07 +00:00
akwizgran
024e5aa90f Bumped version numbers for beta release. 2017-12-04 14:43:27 +00:00
akwizgran
6d791481d5 Merge branch '1007-samsung-transition-npe-beta' into 'maintenance-0.16'
Beta: Don't set scene transition for Samsung devices running Android 7.0

See merge request !641
2017-12-04 14:35:39 +00:00
Torsten Grote
0a807d0893 Don't set scene transition for Samsung devices running Android 7.0 2017-12-04 10:58:20 -02:00
akwizgran
23596bbdd4 Merge branch origin/maintenance-0.16 into maintenance-0.16 2017-12-01 17:19:42 +00:00
Torsten Grote
fe79954138 Merge branch 'briar-beta-app-name' into 'maintenance-0.16'
Change app name for beta debug builds

See merge request !636
2017-12-01 16:43:45 +00:00
akwizgran
9902c023ca Bump version number for beta release. 2017-12-01 16:30:18 +00:00
akwizgran
e8baee6734 Specify 7 characters for Git revision.
(cherry picked from commit f0d8532)
2017-12-01 16:29:45 +00:00
akwizgran
a8dc029e56 Change app name for beta debug builds. 2017-12-01 16:21:20 +00:00
akwizgran
74e3fee7aa Merge branch '1124-notification-channel-crash-beta' into 'maintenance-0.16'
Beta: Use NotificationChannel for foreground service to avoid crash on Android 8.1

See merge request !635
2017-12-01 16:00:53 +00:00
Torsten Grote
05aac696b7 Use NotificationChannel for foreground service to avoid crash on Android 8.1
This also seems to address #1075 at least on an emulator
2017-12-01 13:47:02 -02:00
akwizgran
48918f4727 Bumped version numbers for beta release. 2017-11-30 13:35:43 +00:00
akwizgran
303b5bd395 Merge branch 'target-sdk-26' into 'master'
Target API version 26, upgrade support library

See merge request !626
2017-11-29 17:38:12 +00:00
akwizgran
97733a52c8 Updated translations. 2017-11-23 17:03:15 +00:00
akwizgran
89dcbec599 Upgrade Gradle plugin to 3.0.1. 2017-11-23 17:01:16 +00:00
akwizgran
6497809fe1 Merge branch '1103-dont-ask-again-doze' into 'master'
Show Doze Mode Warning with Don't Ask Again Option

Closes #1103

See merge request !625
2017-11-23 16:23:39 +00:00
akwizgran
9f3a63d8c4 Don't unregister receiver unless it was registered. 2017-11-22 11:37:58 +00:00
akwizgran
748fa77d94 Move doze receiver out of BriarService. 2017-11-22 11:07:28 +00:00
Torsten Grote
4ca86ee4eb Address review comments 2017-11-21 16:01:07 -02:00
Torsten Grote
ec2f372933 Remember that app entered doze mode and inform user when returning 2017-11-21 15:55:00 -02:00
Torsten Grote
4267800db2 Allow Account Creation without Doze White-listing 2017-11-21 15:55:00 -02:00
Torsten Grote
bb8cb9bcbb Show Doze Dialog only after startup and provide "don't ask again" option 2017-11-21 15:54:59 -02:00
akwizgran
d5b9e15ee1 Bump compileSdkVersion to match support library. 2017-11-21 17:33:40 +00:00
akwizgran
43ee3246f6 Remove redundant casts from findViewById. 2017-11-21 17:29:21 +00:00
akwizgran
b56724dee5 Set target SDK version to 26, upgrade support library. 2017-11-21 17:29:21 +00:00
akwizgran
92748ac872 Accept build tools license for CI. 2017-11-21 17:28:11 +00:00
akwizgran
b89686c287 Merge branch 'upgrade-gradle-witness' into 'master'
Upgrade Gradle Witness

See merge request !623
2017-11-21 17:11:06 +00:00
akwizgran
a34692630b Use testImplementation for Mockito. 2017-11-21 17:03:38 +00:00
akwizgran
735208562a Use java-library plugin for Java modules. 2017-11-21 16:35:08 +00:00
akwizgran
49826fdc56 Use new Gradle configurations for Android modules. 2017-11-21 16:35:08 +00:00
akwizgran
e8c54a609c Upgrade Gradle Witness. 2017-11-21 16:35:03 +00:00
akwizgran
ece2c51358 A few more Java 8 changes in merged code. 2017-11-21 16:21:15 +00:00
akwizgran
3ec8af4661 Merge branch 'use-java-8-language-features' into 'master'
Use java 8 language features

See merge request !621
2017-11-21 15:22:52 +00:00
Torsten Grote
77a08596fe Merge branch '764-bdf-list-dictionary-not-thread-safe' into 'master'
BdfList and BdfDictionary don't need to be thread-safe

Closes #764

See merge request !614
2017-11-21 13:00:23 +00:00
akwizgran
879f699b2b A few more lambdas. 2017-11-21 10:51:37 -02:00
akwizgran
d7383a3361 Effectively final. 2017-11-21 10:51:35 -02:00
akwizgran
a5b321a93b Multi-catch. 2017-11-21 10:49:10 -02:00
akwizgran
5fa6b0ca1c Lambdas. 2017-11-21 10:49:08 -02:00
akwizgran
27328afe3c Diamond operators. 2017-11-21 10:45:47 -02:00
Torsten Grote
2d26af1ae2 Merge branch 'java-8-language-features' into 'master'
Support Java 8 language features

See merge request !620
2017-11-21 12:09:27 +00:00
Torsten Grote
6db8f33e8f Merge branch 'log-network-usage' into 'master'
Log network usage at shutdown

See merge request !616
2017-11-21 11:45:42 +00:00
akwizgran
d6a7e6d52c Resolve merge conflicts.
# Conflicts:
#   briar-android/build.gradle
#   briar-android/src/test/java/org/briarproject/briar/android/login/SetupActivityTest.java
2017-11-21 10:27:31 +00:00
akwizgran
df99b3b666 Merge branch '1085-startup-wizard' into 'master'
Setup Wizard that asks for Doze Mode exception

Closes #1085 and #1018

See merge request !603
2017-11-21 09:40:10 +00:00
akwizgran
0f1c9f4fe2 Refactored tests for account setup and changing password. 2017-11-20 14:11:31 -02:00
Torsten Grote
5dcd5f79dc Test PasswordFragment account creation individually 2017-11-20 11:52:06 -02:00
Torsten Grote
8a81171739 Setup Wizard that asks for Doze Mode exception
Keep checking if we are whitelisted and request it if not
2017-11-20 11:52:05 -02:00
akwizgran
1c4f20f76f Merge branch 'simply-build-gradle' into 'master'
Simply bramble-androids's build.gradle

See merge request !622
2017-11-17 16:11:00 +00:00
goapunk
f84fa588f6 simply bramble-androids's build.gradle
Signed-off-by: goapunk <noobie@goapunks.net>
2017-11-17 16:43:07 +01:00
akwizgran
e30e34f342 Include java.lang.invoke classes in bootstrap classpath. 2017-11-16 15:26:05 +00:00
akwizgran
fc93ced067 Download the Android support repository for CI. 2017-11-16 12:54:57 +00:00
akwizgran
bb7df72d31 Compile against OpenJDK 6 standard library for CI. 2017-11-16 12:54:50 +00:00
akwizgran
f8425658e4 Support Java 8 language features in Java modules. 2017-11-16 11:46:35 +00:00
akwizgran
53c8cf09b6 Support Java 8 language features in Android modules. 2017-11-16 11:46:34 +00:00
akwizgran
9f29bf4949 Upgrade Gradle and Android Gradle plugin 2017-11-16 11:46:32 +00:00
akwizgran
98e2adf794 Fix Dagger setup, remove android-apt plugin. 2017-11-16 11:46:02 +00:00
Torsten Grote
2a43e0b0ed Merge branch '545-simple-db-indexes' into 'master'
Add some simple indexes to the DB

See merge request !618
2017-11-09 12:10:07 +00:00
akwizgran
773ae73820 Updated translations. 2017-11-09 12:05:21 +00:00
akwizgran
009db57bc5 Merge branch '482-delete-old-transport-property-updates' into 'master'
Delete old transport property updates

Closes #482

See merge request !617
2017-11-09 11:59:00 +00:00
akwizgran
5e98126e77 Completely remove old local updates from the database. 2017-11-09 10:58:51 +00:00
akwizgran
bd7ebfd83a Unit tests for TransportPropertyManagerImpl. 2017-11-08 16:44:26 +00:00
akwizgran
10f41ef157 Log network usage at shutdown. 2017-11-08 14:46:56 +00:00
akwizgran
1dd4960109 Transactions that delete old updates must be read-write. 2017-11-08 14:23:30 +00:00
akwizgran
75413b6c86 Delete old transport property updates.
Some of this code is only needed for backward compatibility - it can be removed when we break compatibility for 1.0.
2017-11-08 09:47:59 +00:00
akwizgran
b2180582a7 BdfList and BdfDictionary don't need to be thread-safe.
Same goes for Metadata.
2017-11-06 15:20:21 +00:00
akwizgran
8211ce7ae3 Add some simple indexes to the DB. 2017-11-03 15:06:34 +00:00
akwizgran
e6b1597fa7 Upgraded Gradle to 3.5. 2017-10-26 18:07:20 +01:00
akwizgran
8937d3cd9c Updated translations. 2017-10-24 17:01:11 +01:00
akwizgran
51f320d147 Merge branch '992-wake-lock-tag' into 'master'
Change wake lock tag

Closes #992 and #1087

See merge request !612
2017-10-24 13:36:26 +00:00
goapunk
e402a894bb Change wake lock tag
Signed-off-by: goapunk <noobie@goapunks.net>
2017-10-24 13:45:27 +02:00
Torsten Grote
9b577f1219 Merge branch 'remove-location-permission' into 'master'
Remove unused location permission

See merge request !611
2017-10-18 16:31:56 +00:00
akwizgran
220f678403 Removed unused location permission. 2017-10-18 14:05:11 +01:00
akwizgran
4173fc4daa Merge branch '1045-preference-divider' into 'master'
Don't use a custom widget to separate preference categories

Closes #1045

See merge request !609
2017-10-17 17:03:13 +00:00
Torsten Grote
c6756d2145 Merge branch 'gradle-plugin-2.3.3' into 'master'
Upgrade Gradle plugin and build tools

See merge request !610
2017-10-17 16:14:53 +00:00
akwizgran
6731f6eeb5 Added checksum for Gradle download. 2017-10-17 17:01:46 +01:00
akwizgran
6f7f8b40e3 Upgraded Gradle plugin and build tools. 2017-10-17 15:31:28 +01:00
akwizgran
1a83b2c99b Bumped version number for beta release. 2017-10-17 09:41:11 +01:00
akwizgran
f641fae1c7 Added new translations. 2017-10-16 17:10:53 +01:00
akwizgran
deb43d9872 Updated translations. 2017-10-16 17:08:07 +01:00
akwizgran
cee4e1305e Merge branch 'extend-expiry' into 'master'
Extend expiry and show a green snackbar about it once

See merge request !606
2017-10-12 17:03:26 +00:00
akwizgran
a1f989c43c Use black text for the expiry extension notice. 2017-10-12 17:51:57 +01:00
akwizgran
b67abadbac Use a setting to record whether update notice has been shown 2017-10-12 17:51:57 +01:00
Torsten Grote
8c29c85696 Extend expiry and show a green snackbar about it once 2017-10-12 17:51:57 +01:00
akwizgran
4fe4c298d7 Don't use a custom widget to separate preference categories. 2017-10-11 17:35:05 +01:00
akwizgran
13d35229d5 Merge branch '1091-reduce-polling-queries' into 'master'
Reduce number of DB queries used when polling for connections

Closes #1091

See merge request !604
2017-10-11 13:45:14 +00:00
Torsten Grote
f0137b41b6 Merge branch 'accept-sdk-license-agreement-for-ci' into 'master'
Accept build tools license agreement for CI runner

See merge request !607
2017-10-11 13:24:25 +00:00
akwizgran
b221d21903 Accept all SDK license agreements for CI runner. 2017-10-11 14:18:02 +01:00
Torsten Grote
8bac202626 Add Hindi, Finnish and Basque translations 2017-10-10 10:04:22 -03:00
Torsten Grote
973151c949 Merge branch 'report-bluetooth-and-wifi-support' into 'master'
Report Bluetooth LE and Wi-Fi Direct support in crash reports and feedback

See merge request !605
2017-10-10 12:16:29 +00:00
akwizgran
ed26ab78a5 Merge branch '158-permission-requests' into 'master'
Add permission requests for Android 6+

Closes #158

See merge request !601
2017-10-10 10:40:14 +00:00
akwizgran
8454b2d235 Code cleanup, shortened button text to help with layout. 2017-10-10 11:33:07 +01:00
akwizgran
91d0f89f60 Removed unused import. 2017-10-10 11:08:40 +01:00
akwizgran
e074672e86 Reduce DB queries for looking up transport properties. 2017-10-10 10:59:39 +01:00
akwizgran
6c1901fe5b Reduced DB queries when polling for LAN connections. 2017-10-09 15:20:03 +01:00
goapunk
49052be627 Add permission requests for Android 6+
* Add request for the camera

Signed-off-by: goapunk <noobie@goapunks.net>
2017-10-04 13:17:51 +02:00
Torsten Grote
5b5b540630 Merge branch '299-disable-bluetooth-at-shutdown' into 'master'
Disable Bluetooth at shutdown if we enabled it

See merge request !602
2017-10-03 15:38:22 +00:00
akwizgran
9993bac3a1 Disable Bluetooth at shutdown if we enabled it. 2017-10-03 15:59:07 +01:00
akwizgran
3c95988693 Merge branch '539-clear-notifications' into 'master'
Don't show dismissed notifications again when items are removed

Closes #539

See merge request !600
2017-10-02 14:46:54 +00:00
akwizgran
fc5c3b470e Merge branch 'patch-1' into 'master'
Contacts, on your side

See merge request !594
2017-10-02 13:14:00 +00:00
akwizgran
53f05a72ba Removed logging. 2017-09-29 15:31:25 +01:00
akwizgran
2c10ae7d06 Clear notifications when dismissed.
Also fixed an issue with notifications alerting again when items
were removed.
2017-09-29 15:23:27 +01:00
akwizgran
6b9010c557 Merge branch '703-create-test-data' into 'master'
Add an option to debug builds to create fake test data

Closes #703

See merge request !595
2017-09-28 10:37:03 +00:00
Torsten Grote
1bf0fdfa81 Add an option to debug builds to create fake test data 2017-09-27 13:55:29 -03:00
Torsten Grote
237759aac0 Add Simplified Chinese translation 2017-09-27 13:32:07 -03:00
akwizgran
2a141e0a97 Merge branch 'disableAaptCruncher' into 'master'
Disable PNG crunching for reproducibility

See merge request !596
2017-09-27 16:04:23 +00:00
akwizgran
d6900be68e Merge branch '1051-fix-pink' into 'master'
Fix pink navigation drawer items with current support library

Closes #1051

See merge request !598
2017-09-27 16:02:22 +00:00
Torsten Grote
a35d7c7204 Fix pink navigation drawer items with current support library 2017-09-27 12:09:06 -03:00
Torsten Grote
86287f9241 Merge branch 'spongy-castle-158' into 'master'
Upgrade Spongy Castle to 1.58

See merge request !597
2017-09-27 15:01:15 +00:00
akwizgran
0b2e3dd96f Upgrade Spongy Castle to 1.58. 2017-09-27 15:54:37 +01:00
Torsten Grote
90aa1d1ce7 Disable PNG crunching for reproducibility
This can help to prevent non-determinism introduced by the crunching
process.

More information:
e48f9f0773

With enabled and disabled crunching,
the size of the signed release APK was 17809681 bytes.

Related to #164
2017-09-27 11:35:25 -03:00
Michael Rogers
ef2286ab53 Bumped version number for beta release. 2017-09-20 14:51:10 +01:00
akwizgran
47b25f3221 Merge branch '1064-rss-date-npe' into 'master'
Fix NPE when some RSS items don't have dates and add test

Closes #1064

See merge request !591
2017-09-20 12:21:06 +00:00
Torsten Grote
c30bfa12ce Fix NPE when some RSS items don't have dates and add test 2017-09-20 09:11:06 -03:00
akwizgran
d0fc04251d Merge branch 'three-new-langs' into 'master'
Add Norwegian Bokmål, Occitan (post 1500) and Serbian

See merge request !593
2017-09-20 11:15:44 +00:00
akwizgran
dcbb41eb7a Merge branch '1069-forum-sharing-exception' into 'master'
Fix crash when sharing a forum while it was just shared with us

Closes #1069

See merge request !592
2017-09-20 11:14:20 +00:00
Allan Nordhøy
5c51259269 "Connection aborted!" no und 2017-09-19 19:39:57 +00:00
Allan Nordhøy
7eefa07052 Contact connections → contacts
by us → on your side
2017-09-19 18:56:22 +00:00
Torsten Grote
999bdf8866 Add Norwegian Bokmål, Occitan (post 1500) and Serbian 2017-09-19 14:47:39 -03:00
Torsten Grote
911c0c0fd9 Fix crash when sharing a forum while it was just shared with us 2017-09-19 14:30:57 -03:00
akwizgran
99d8cc64a6 Merge branch '1024-message-tree-npe' into 'master'
Don't add threaded messages to the UI before their parents

Closes #1024

See merge request !585
2017-09-19 15:37:58 +00:00
akwizgran
ba727d7568 Don't add threaded messages to the UI before their parents. 2017-09-19 16:31:27 +01:00
Torsten Grote
ed01048f9f Merge branch 'remove-old-bluetooth-code' into 'master'
Remove old Bluetooth code and location permission

See merge request !584
2017-09-19 14:16:13 +00:00
Torsten Grote
043ee3c58e Merge branch '1044-crash-when-setting-ringtone' into 'master'
Don't crash if the chosen ringtone can't be loaded

Closes #1044

See merge request !586
2017-09-19 13:11:44 +00:00
Torsten Grote
6e0af7deda Merge branch '1060-upgrade-tor' into 'master'
Upgrade Tor to 0.2.9.12

Closes #1060

See merge request !590
2017-09-19 12:14:55 +00:00
akwizgran
9591db2097 Upgrade Tor to 0.2.9.12.
Libevent 2.0.22-stable, OpenSSL 1.0.2l and GeoIP 2017-09-06.
2017-09-19 12:49:22 +01:00
akwizgran
329a4c64f6 Merge branch '1028-lost-reply-id' into 'master'
Keep the reply ID up to date in ThreadListActivity

Closes #1028

See merge request !587
2017-09-18 15:10:38 +00:00
Torsten Grote
79015bc5ae Merge branch '1042-catch-npe-when-getting-socket-streams' into 'master'
Catch NPE when getting socket input/output streams

Closes #1042

See merge request !589
2017-09-18 14:55:08 +00:00
akwizgran
27422ab9f9 Catch NPE when getting socket input/output streams.
Works around a bug in Android 7, fixed in 7.1.
2017-09-18 15:47:12 +01:00
Torsten Grote
abcb682498 Merge branch '1040-rss-feed-illegal-argument-exception' into 'master'
Catch IllegalArgumentException when parsing RSS feed

Closes #1040

See merge request !588
2017-09-18 14:38:22 +00:00
akwizgran
5044127c46 Catch IllegalArgumentException when parsing RSS feed. 2017-09-18 15:26:12 +01:00
akwizgran
0e4b8ca62e Keep the activity's reply ID up to date. 2017-09-18 15:13:16 +01:00
akwizgran
822017c69c Don't crash if the chosen ringtone can't be loaded. 2017-09-18 13:37:10 +01:00
akwizgran
eb6561b93d Updated translations for German, French and Russian. 2017-09-15 10:40:05 +01:00
akwizgran
eb9d0c00a8 Report Bluetooth LE and Wi-Fi Direct support. 2017-08-16 12:21:13 +01:00
Michael Rogers
d24b1884a2 Removed old Bluetooth code and the location permission it requires. 2017-08-11 12:42:47 +01:00
Michael Rogers
078534889e Bumped version number for beta release. 2017-08-04 15:16:51 +01:00
Torsten Grote
e92713006a Fix string in Spanish translation 2017-08-04 10:57:43 -03:00
akwizgran
18f43f3bc1 Merge branch '871-rss-feeds-lost' into 'master'
Fix bug where RSS feeds got lost when a fetching error occured

Closes #871

See merge request !583
2017-08-04 13:52:26 +00:00
akwizgran
a4118b40e1 Merge branch 'debug-build-alongside-beta' into 'master'
Make debug builds installable alongside official beta build

See merge request !582
2017-08-02 16:54:25 +00:00
Torsten Grote
de29fbc324 Fix bug where RSS feeds got lost when a fetching error occured 2017-08-01 15:32:51 -03:00
Torsten Grote
3197dcf9b5 Merge branch 'checked-camera-exceptions' into 'master'
Throw checked exceptions for camera errors

See merge request !580
2017-08-01 16:54:45 +00:00
akwizgran
35aad409fd Merge branch '994-notification-sound-delay' into 'master'
Always play a notification sound, if at least 2sec after last one

Closes #994

See merge request !581
2017-08-01 16:20:35 +00:00
Torsten Grote
08ce6a7331 Change app name for debug builds 2017-08-01 13:08:12 -03:00
Torsten Grote
33a0099065 Make debug builds installable alongside official beta build 2017-08-01 12:57:11 -03:00
Torsten Grote
34d20fafda Always play a notification sound, if at least 2sec after last one
This is the same behavior as Signal.
We might want to adjust the delay later on.

This is also introduces a new BriarNotificationBuilder as a first step
to clean up the Notification Manager code.
2017-08-01 12:47:11 -03:00
Michael Rogers
aafddcd0f0 Bumped version number for beta release (for real this time). 2017-08-01 16:43:47 +01:00
akwizgran
0d6983b4ef Throw checked exceptions for camera errors. 2017-08-01 15:56:20 +01:00
akwizgran
69bfb72171 Merge branch '1002-cam-get-params-npe' into 'master'
Catch RuntimeException when getting camera parameters

See merge request !579
2017-08-01 13:56:45 +00:00
Torsten Grote
1aa33ec9b2 Catch RuntimeException when getting camera parameters 2017-08-01 10:49:04 -03:00
akwizgran
6702df1e22 Merge branch '1008-qr-decoding-crash' into 'master'
Catch IllegalArgumentException when decoding QrCode

Closes #1008

See merge request !578
2017-08-01 13:36:09 +00:00
akwizgran
c1748c9a86 Bumped version number for beta release. 2017-08-01 14:32:05 +01:00
akwizgran
9df624c62a Merge branch '1009-camera-npe' into 'master'
Prevent NPE in CameraView

Closes #1009 and #997

See merge request !577
2017-08-01 13:29:33 +00:00
Torsten Grote
0ee6197d7f Catch IllegalArgumentException when decoding QrCode 2017-08-01 10:21:02 -03:00
Torsten Grote
b03a7dce3e Catch runtime exception when setting best camera parameters
Closes #997
2017-08-01 10:09:21 -03:00
Torsten Grote
6c59d7dd5f Prevent NPE in CameraView
This prevents crashes, but still might cause the camera to not show up
thus preventing the user from adding contacts.
2017-08-01 09:41:42 -03:00
Michael Rogers
050191f0ef Bumped version number for beta release. 2017-08-01 12:31:47 +01:00
akwizgran
4b5a19ce5d Merge branch 'update-translations' into 'master'
Update translations, add Turkish and Russian

See merge request !575
2017-08-01 09:28:17 +00:00
akwizgran
7c4dd991b9 Merge branch '1016-reblog-runtime-error' into 'master'
Runtime error fix due to window requests

Closes #1016 and #1007

See merge request !576
2017-08-01 09:25:39 +00:00
Ernir Erlingsson
8455569e88 moved window requests above onCreate 2017-07-30 22:42:03 +02:00
Torsten Grote
d25676559c Update translations, add Turkish and Russian 2017-07-29 11:03:51 -03:00
Michael Rogers
a9437f7985 Bumped version number for beta release. 2017-07-28 18:01:19 +01:00
akwizgran
8141a97fc9 Merge branch '1015-recent-emoji-crash' into 'master'
Prevent a crash caused by empty emoji

Closes #1015

See merge request !571
2017-07-28 16:59:02 +00:00
Torsten Grote
db842bd7e4 Prevent a crash caused by empty emoji
The crash happens because the serialization of recently used emoji uses
';' to separate the emojis.
One of the ASCII emojis however has a ';' in the beginning.
When this one is used by the user,
it causes an empty string to be returned when deserializing.

This commit prevents the crash by changing the separator to a tab.
It uses a different settings string to store the emoji,
so users will lose the list of recently used emoji when they update to
this version.

PS. That wasn't my idea ;)
2017-07-28 13:49:51 -03:00
Torsten Grote
6dbec3a864 Merge branch 'enable-logging-for-beta-builds' into 'master'
Enable logging for beta builds

See merge request !573
2017-07-28 15:58:01 +00:00
akwizgran
29f658cf4d Merge branch '1006-blog-crash' into 'master'
Prevent crash in blog by ensuring a listener always exists

Closes #1006

See merge request !574
2017-07-28 15:53:43 +00:00
akwizgran
ca83744a84 Merge branch 'close-feed-stream' into 'master'
Close InputStream from RSS feed and prevent NPE

See merge request !572
2017-07-28 15:48:01 +00:00
Torsten Grote
d91a9e2be4 Prevent crash in blog by ensuring a listener always exists 2017-07-28 12:42:56 -03:00
akwizgran
8408c3f467 Enable logging for beta builds.
Some devices were logging and others not, due to the log level being set in the SplashScreenActivity constructor.
2017-07-28 16:41:24 +01:00
Torsten Grote
544c83a64c Close InputStream from RSS feed and prevent NPE 2017-07-28 10:38:01 -03:00
Michael Rogers
3800cd5e4f Bumped version number for beta release. 2017-07-28 11:17:09 +01:00
akwizgran
259f2cd419 Merge branch '993-fix-full-text-blog-posts' into 'master'
Show blog posts with full text when clicked

Closes #993

See merge request !570
2017-07-26 11:01:38 +00:00
Torsten Grote
20eb022c36 Show blog posts with full text when clicked
This fixes a regression that was introduced in !551.
2017-07-25 15:50:04 -03:00
akwizgran
531e555b52 Bumped version number for beta release. 2017-07-25 18:43:19 +01:00
akwizgran
a9024aa34b Merge branch '955-shared-with-update' into 'master'
Fix "shared with" counter not being updated

Closes #955

See merge request !569
2017-07-25 17:40:40 +00:00
akwizgran
d4e3b7842c Merge branch 'blog-sharing-tests' into 'master'
Add unit tests for BlogSharingManager

See merge request !567
2017-07-25 17:40:29 +00:00
Torsten Grote
167fddfbcc Add unit tests for BlogSharingManager 2017-07-25 12:45:36 -03:00
Torsten Grote
a48d642648 Fix UI bug in CreateForumActivity and adapt group creation 2017-07-25 12:32:53 -03:00
Torsten Grote
9a70f054c7 Use proper GroupId when reacting to accepted invitations
Fixes #955
2017-07-25 10:03:13 -03:00
Torsten Grote
ca43d13bd6 Merge branch 'inject-properties-module-eager-singletons' into 'master'
Inject properties module's eager singletons

See merge request !568
2017-07-25 12:55:59 +00:00
akwizgran
5b71004179 Inject properties module's eager singletons. 2017-07-25 13:49:15 +01:00
akwizgran
63befccdbf Bumped expiry time and version number for beta release. 2017-07-21 11:52:09 +01:00
akwizgran
4ecf7c02d0 Merge branch '979-duplicate-blog-session' into 'master'
Fix Blog Sharing Sessions

Closes #979

See merge request !566
2017-07-21 10:27:21 +00:00
Torsten Grote
f25badc18c Move responsibility for pre-sharing blogs to sharing manager
to have all the code related to that in one place,
so it is easier to maintain and to spot bugs.

This also checks that only blogs without an existing sharing session
are shared and initialized again.
It extends an existing test to catch the missing check.

This removes some debugging information from the previous commit
to not leak private information via the sharing sessions.

Fixes #979
2017-07-17 14:07:47 -03:00
akwizgran
6e931e9ba5 Bump version number and expiry date for beta release. 2017-07-17 10:32:46 +01:00
akwizgran
7e749124bf Merge branch '617-protocol-versioning' into 'master'
Protocol versioning for BTP

See merge request !557
2017-07-17 09:24:35 +00:00
akwizgran
5822eb7808 Remove 'this'. 2017-07-17 10:16:50 +01:00
Torsten Grote
7a7e086541 Merge branch '982-name-not-found-exception' into 'master'
Use fully-qualified class names in manifest

Closes #982

See merge request !565
2017-07-14 12:19:50 +00:00
akwizgran
abab3167c2 Use fully-qualified class names in manifest.
This prevents a crash on Android 4 when the package name in build.gradle differs from the name in the manifest.
2017-07-14 12:01:55 +01:00
Torsten Grote
8d08570568 Merge branch '977-crash-when-opening-rss-blog' into 'master'
Create correct shareable for RSS blogs

Closes #977

See merge request !564
2017-07-07 17:42:54 +00:00
akwizgran
2007078f13 Added test for sharing an RSS blog. 2017-07-07 18:02:15 +01:00
akwizgran
dfb71a7978 Merge branch '942-block-blog-notifications' into 'master'
Block blog notifications when viewing combined feed

See merge request !563
2017-07-07 16:32:07 +00:00
akwizgran
480b0e3a03 Create correct shareable for RSS blogs.
Also removed "personal blog" wording that doesn't apply to RSS blogs.
2017-07-07 17:30:44 +01:00
akwizgran
8f8751f4ac Block blog notifications when viewing combined feed. 2017-07-07 15:34:00 +01:00
akwizgran
de2ea112ee Merge branch '933-beta-warning' into 'master'
Show Beta Expiry Warning

Closes #933

See merge request !559
2017-07-07 12:19:04 +00:00
Torsten Grote
6f99a53fd9 Show beta expiry warning in main activity 2017-07-07 09:12:07 -03:00
akwizgran
a8a9b9032d Merge branch 'warn_on_extra_translation' into 'master'
Show a warning instead of throwing an error for unused translations

See merge request !561
2017-07-07 12:01:23 +00:00
goapunk
6b15fb89de Show a warning instead of throwing an error for unused translations
Signed-off-by: goapunk <noobie@goapunks.net>
2017-07-07 12:19:44 +02:00
Torsten Grote
a711d6b8a1 Merge branch '106-fix-package-name' into 'master'
Set applicationId to match app_package

See merge request !560
2017-07-05 13:46:30 +00:00
akwizgran
5678f8aaa4 Update Robolectric tests so they can find resources. 2017-07-05 14:40:03 +01:00
akwizgran
2fe37f6c26 Set applicationId to match app_package. 2017-07-05 14:17:35 +01:00
Torsten Grote
a879747968 Translation Update 2017-07-05 09:50:14 -03:00
akwizgran
95e8fd7ee0 Merge branch 'notify_more_agressively' into 'master'
Notify more aggressively

See merge request !555
2017-07-05 11:36:37 +00:00
goapunk
4416aaaa4c Notify more aggressively
* Add setting to show notification on the lockscreen
* Don't block notifications in the contact-/-group/-forum/-bloglist

Signed-off-by: goapunk <noobie@goapunks.net>
2017-07-05 13:05:21 +02:00
Torsten Grote
500d5f0efe Merge branch '822-group-creation-workflow' into 'master'
Revisit private group creation workflow

Closes #822

See merge request !553
2017-07-04 17:19:11 +00:00
akwizgran
fc8978fd90 Create forum when button is clicked. 2017-07-04 16:17:59 +01:00
akwizgran
73df126bd4 Create and share private groups separately, as with forums. 2017-07-04 16:17:58 +01:00
akwizgran
9146488c7d Use same layout and behaviour for creating groups and forums. 2017-07-04 16:17:58 +01:00
akwizgran
613a7fe376 Merge branch '962-removing-contacts' into 'master'
Add test where two contacts remove each other

Closes #962

See merge request !558
2017-07-04 15:14:27 +00:00
akwizgran
ecb62f00d4 Code cleanup. 2017-07-04 16:09:32 +01:00
akwizgran
c4540a03cd Protocol versioning for BTP. 2017-07-04 16:09:32 +01:00
akwizgran
3e31da99b5 Merge branch '106-beta-namespace' into 'master'
Change app name and package name for beta release

Closes #106

See merge request !545
2017-07-04 14:40:47 +00:00
Torsten Grote
098c1d0b1e Add test where two contacts remove each other 2017-07-04 11:30:17 -03:00
akwizgran
178e908c86 Use a different package name and app name for beta builds. 2017-07-03 18:20:05 +01:00
akwizgran
ecf7cf14ae Merge branch '957-rss-url-case-sensitivity' into 'master'
Handle RSS URLs case-insensitively

Closes #957

See merge request !544
2017-07-03 16:22:52 +00:00
akwizgran
09e2a15a73 Merge branch '951-remove-visibility-indicators' into 'master'
Remove visibility indicators from private group join messages

Closes #951

See merge request !546
2017-07-03 16:22:31 +00:00
akwizgran
ab387860a6 Removed visibility indicators from private group member list. 2017-07-03 16:37:29 +01:00
akwizgran
f63fc94f2b Removed visibility indicators from private group join messages. 2017-07-03 16:37:29 +01:00
Michael Rogers
41e5928cca Validate and normalise RSS URLs. 2017-07-03 16:36:50 +01:00
Torsten Grote
8303175494 Merge branch 'use-f-droid-base-docker-image' into 'master'
Use F-Droid's base Docker image

See merge request !556
2017-07-03 15:35:28 +00:00
akwizgran
151eb6935b Use F-Droid's base Docker image. 2017-07-03 16:17:03 +01:00
akwizgran
6a419c0c7b Merge branch '968-downgrade-h2' into 'master'
Downgrade H2 to 1.4.192

Closes #968

See merge request !550
2017-07-03 11:51:35 +00:00
akwizgran
1795b32121 Downgrade H2 to 1.4.192. 2017-07-03 12:36:45 +01:00
akwizgran
01971768ce Merge branch '970_settings_use_summaries' into 'master'
Split notification settings into title and summary.

Closes #970

See merge request !554
2017-07-03 11:19:15 +00:00
akwizgran
ef7483ab01 Merge branch '787-tapping-blog-author-opens-same-blog' into 'master'
Don't reopen the same blog when the author is tapped

Closes #787

See merge request !551
2017-07-03 10:43:15 +00:00
akwizgran
527d11473d Merge branch '805-introduction-message-layout' into 'master'
Use smaller layout for introduction message screen

Closes #805

See merge request !552
2017-07-03 10:40:10 +00:00
akwizgran
775dadc9a0 Merge branch '904-notify-tor-controller' into 'master'
Notify Tor controller if Tor has crashed

Closes #904

See merge request !543
2017-07-03 09:29:04 +00:00
akwizgran
800b10a988 Merge branch '956-tap-protection-ux' into 'master'
Don't show tap protection dialog until it's needed

Closes #956

See merge request !548
2017-07-03 09:22:31 +00:00
akwizgran
c977bf047d Removed overrides of showScreenFilterWarning. 2017-07-03 10:08:36 +01:00
goapunk
660a25f21d Split notification settings into title and summary.
Signed-off-by: goapunk <noobie@goapunks.net>
2017-07-03 09:27:07 +02:00
Torsten Grote
e7fd6d23af Merge branch '962-check-blog-subscription-when-removing-contact' into 'master'
Check personal blog subscription when removing contact

See merge request !549
2017-06-30 20:57:52 +00:00
Torsten Grote
46982897f0 Merge branch '963-load-thread-list-messages-on-start' into 'master'
Load messages each time activity starts

See merge request !547
2017-06-30 20:53:13 +00:00
Torsten Grote
d24de68d64 Merge branch '574-upgrade-tor' into 'master'
Upgrade Tor to 0.2.9

Closes #574

See merge request !542
2017-06-30 20:36:22 +00:00
akwizgran
7514c46a3f Use smaller layout for introduction message screen. 2017-06-30 16:23:16 +01:00
akwizgran
6632c0f8e3 Don't reopen the same blog when the author is tapped. 2017-06-30 14:24:32 +01:00
akwizgran
79aafcda69 Fixed a test, added a regression test. 2017-06-30 12:58:44 +01:00
akwizgran
05af21e8dc Check personal blog subscription when removing contact. 2017-06-30 12:04:34 +01:00
akwizgran
0dc62cbbdc Fixed a test. 2017-06-30 10:01:35 +01:00
akwizgran
f3a084cfd2 Removed option to remember shown overlay apps. 2017-06-29 18:47:36 +01:00
akwizgran
8b32f82566 Don't show tap protection dialog until it's needed. 2017-06-29 18:18:39 +01:00
akwizgran
d598b6ed44 Load messages each time activity starts. 2017-06-26 16:21:25 +01:00
akwizgran
f5dc6f24b9 Bumped expiry date to 1 September 2017. 2017-06-26 14:50:58 +01:00
akwizgran
37454392da Update Tor binaries to 0.2.9.11. 2017-06-23 22:06:00 +01:00
akwizgran
de7f9111d3 Update Tor patch to 0.2.9.11. 2017-06-23 15:23:26 +01:00
akwizgran
96d2889a6c Notify Tor controller if Tor has crashed. 2017-06-23 14:57:00 +01:00
Torsten Grote
f6412d1e9a Merge branch 'spongy-castle-1-56' into 'master'
Upgrade Spongy Castle and some other dependencies

See merge request !541
2017-06-15 17:37:22 +00:00
akwizgran
b377cd6b1c Upgrade Spongy Castle and some other dependencies. 2017-06-12 17:44:08 +01:00
Ernir Erlingsson
f6cdbda5bb Merge branch 'master' of https://code.briarproject.org/akwizgran/briar 2017-05-29 11:06:16 +02:00
Ernir Erlingsson
855c600a3e hotfix list restore NPE for user testing 2017-05-29 11:05:46 +02:00
akwizgran
ea6e8303b0 Merge branch '954_dont_show_on_startup_failure' into 'master'
Don't show screenfilter warning in StartupFailureActivity

See merge request !539
2017-05-29 09:05:18 +00:00
goapunk
d4934040d9 Don't show screenfilter warning in StartupFailureActivity
Signed-off-by: goapunk <noobie@goapunks.net>
2017-05-22 12:40:33 +02:00
akwizgran
3449677b24 Bumped version number and expiry date. 2017-05-19 12:07:29 +01:00
akwizgran
1ad3a6646e Merge branch '941-store-correct-parent-id' into 'master'
Store correct original parent ID when rewrapping blog posts

See merge request !534
2017-05-12 09:53:27 +00:00
akwizgran
2d10f6b2bd Merge branch '884-emoji-text-view-layout-bug' into 'master'
Remove ellipsizing support from EmojiTextView

Closes #884

See merge request !533
2017-05-12 09:35:33 +00:00
akwizgran
5b05424d83 Merge branch 'master' into '941-store-correct-parent-id'
# Conflicts:
#   briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java
2017-05-12 09:34:24 +00:00
akwizgran
0826022d82 Merge branch 'bring_annotations_in_line' into 'master'
Bring nullable annotation imports in line

See merge request !536
2017-05-12 09:33:00 +00:00
akwizgran
a901bfb9cb Merge branch '948-vector-crash' into 'master'
Remove scientific notation from vector drawables to prevent crashes

Closes #948

See merge request !537
2017-05-12 09:28:59 +00:00
akwizgran
03cdce122a Merge branch '947-bluetooth-address-crash' into 'master'
Don't crash on empty bluetooth addresses

See merge request !538
2017-05-12 09:26:57 +00:00
goapunk
f2e0e16969 Bring nullable annotation imports in line
Signed-off-by: goapunk <noobie@goapunks.net>
2017-05-12 10:06:56 +02:00
Torsten Grote
0c441e2ff3 Don't crash on empty bluetooth addresses 2017-05-10 15:06:09 -03:00
Torsten Grote
21302304a5 Remove scientific notation from vector drawables to prevent crashes
Details: http://stackoverflow.com/a/40829348
2017-05-10 14:56:59 -03:00
Torsten Grote
6839d8b844 Merge branch 'wifi-manager-memory-leak' into 'master'
Use application context to get WifiManager

See merge request !535
2017-05-10 17:01:52 +00:00
Torsten Grote
aee65a716c Merge branch '798-remove-contact-blogs' into 'master'
Allow to remove pre-shared blogs of our contacts

Closes #798

See merge request !529
2017-05-10 16:58:38 +00:00
Torsten Grote
6a07d8f2c9 Allow to remove pre-shared blogs of our contacts 2017-05-10 13:50:07 -03:00
Ernir Erlingsson
3c1ea81cd0 Merge branch '853-disabled-menu-items' into 'master'
Remove theme default color override

Closes #853

See merge request !527
2017-05-06 20:26:15 +00:00
Ernir Erlingsson
025f417bc7 Merge branch '894-list-position-restore' into 'master'
save and restore list position for threaded lists

Closes #894 and #946

See merge request !528
2017-05-06 19:37:02 +00:00
Ernir Erlingsson
c9dcd906c9 final pre-merge fixes 2017-05-06 21:36:25 +02:00
Ernir Erlingsson
7024e04d15 fixed final akwizgran comments 2017-05-06 21:31:53 +02:00
akwizgran
0b8ac947db Use application context to get WifiManager. 2017-05-05 15:43:27 +01:00
Ernir Erlingsson
948410a064 fixed unread buttons for threaded lists and akwizgran's comments 2017-05-05 14:49:53 +02:00
akwizgran
2841339cac Merge branch '468-ci' into 'master'
Set up basic CI

Closes #468

See merge request !530
2017-05-05 09:11:06 +00:00
Torsten Grote
e8e82bd805 Update Translations 2017-05-04 10:26:49 -03:00
Ernir Erlingsson
6876f40a0e Merge branch 'fix_groupname_validation' into 'master'
Fix groupname validation

See merge request !531
2017-05-04 07:26:55 +00:00
Ernir Erlingsson
5f4e1ecdfd improvements after code review #1
fix
2017-05-02 11:42:55 +02:00
Ernir Erlingsson
044719432a list position save and restore now implemented for threaded lists 2017-05-02 11:42:55 +02:00
Ernir Erlingsson
d1a929da85 bumped expire date 2017-05-02 11:42:15 +02:00
goapunk
2a8978a60d fix group name validation
Signed-off-by: goapunk <noobie@goapunks.net>
2017-04-29 16:49:37 +02:00
Torsten Grote
c0afad7a26 Set up basic CI 2017-04-28 13:24:41 -03:00
akwizgran
37281c6c23 Remove ellipsizing support from EmojiTextView.
This is a workaround for a layout bug.
2017-04-28 15:39:24 +01:00
Ernir Erlingsson
6de539a62d Merge branch '791-permanent-input' into 'master'
Show text input permanently in threaded conversations

Closes #791

See merge request !526
2017-04-27 10:38:58 +00:00
Ernir Erlingsson
34704ec04d Merge branch '874-tree-indicator' into 'master'
Darken thread indicator

Closes #874

See merge request !525
2017-04-26 08:38:52 +00:00
akwizgran
9fd6d46583 Merge branch '871-increase-socket-timeout' into 'master'
Increase socket timeout for Tor sockets

See merge request !519
2017-04-19 16:53:59 +00:00
akwizgran
76a5e25656 Added tests for wrapping and rewrapping blog posts. 2017-04-19 12:16:18 +01:00
akwizgran
3575b74837 Store correct original parent ID when rewrapping blog posts. 2017-04-19 12:15:34 +01:00
Torsten Grote
f1c7996960 Remove theme default color override 2017-04-18 09:14:00 -03:00
Torsten Grote
920f3581fa Show text input permanently in threaded conversations 2017-04-17 16:22:24 -03:00
Torsten Grote
45e7af31fe Darken thread indicator 2017-04-17 16:14:26 -03:00
Torsten Grote
67d5d8cdf1 Merge branch '941-reblogged-rss-post-has-wrong-icon' into 'master'
Store RSS flag for wrapped blog posts

Closes #941

See merge request !524
2017-04-17 18:23:41 +00:00
Torsten Grote
9d8cadb7a9 Merge branch 'use-original-timestamp-for-rss-posts' into 'master'
Use original timestamp for RSS posts, if available

See merge request !523
2017-04-17 18:22:10 +00:00
Torsten Grote
6425c49d04 Merge branch 'remove-single-top-flag' into 'master'
Don't use single top and clear top flags together

See merge request !522
2017-04-17 18:20:46 +00:00
Torsten Grote
68d98b50f2 Merge branch '938-ignore-play-services-overlay-permission' into 'master'
When checking for overlay apps, ignore Play Services

Closes #938

See merge request !521
2017-04-17 18:19:46 +00:00
akwizgran
84986d393f Added a test for #941, fixed some broken tests. 2017-04-13 17:28:45 +01:00
akwizgran
115d488bc3 Clamp the imported timestamp within reasonable limits. 2017-04-13 16:21:00 +01:00
akwizgran
2eeb2213e3 Store RSS flag for wrapped blog posts. 2017-04-13 15:23:08 +01:00
akwizgran
1b48d661e8 Use original timestamp for RSS posts, if available. 2017-04-13 14:43:43 +01:00
akwizgran
49ba66dee9 Don't use single top and clear top flags together. 2017-04-13 13:56:20 +01:00
akwizgran
46920f3bce Merge branch '892-separate-rss-blog' into 'master'
Separate RSS posts from personal blog posts

Closes #892

See merge request !520
2017-04-13 10:15:00 +00:00
Torsten Grote
4b955809f7 Address review comments 2017-04-12 15:18:27 -03:00
akwizgran
57d4d6546a When checking for overlay apps, ignore Play Services. 2017-04-12 14:24:37 +01:00
Torsten Grote
9bfb58a764 Show blog posts from RSS feeds with a dedicated icon
This adds a field to the post headers and some more tests.
2017-04-12 08:43:24 -03:00
Torsten Grote
0256ec0b8c Show reblog icon only for reblogged posts 2017-04-12 08:43:23 -03:00
Torsten Grote
b0b4a85d15 Add integration test for FeedManager
Attention: This factors out a DnsModule to be able to make actual
non-Tor DNS lookups for testing.
2017-04-12 08:43:23 -03:00
Torsten Grote
d40a058ef5 Change blog descriptor format to include RSS feed flag
This now also handles the case where an RSS blog is deleted via the blog
deletion option and not the feed management.
2017-04-12 08:43:22 -03:00
Torsten Grote
58b9efb24c Open feed's blog when clicking it in 'manage activity' 2017-04-12 08:43:22 -03:00
Torsten Grote
17de785c12 Remove blog as well when removing RSS feed
This also adds a confirmation dialog to the removal process.
2017-04-12 08:43:21 -03:00
Torsten Grote
c7ff1ba974 Store RSS feeds in a separate dedicated blog
A fake LocalAuthor is created for this new blog and stored in the feed's metadata.
2017-04-12 08:43:21 -03:00
akwizgran
d17669f131 Increase socket timeout for Tor sockets. 2017-04-11 14:53:03 +01:00
akwizgran
9755cd9ab4 Merge branch '891-messages-not-acked' into 'master'
Fix MessageId calculation for deprecated MessageQueue

Closes #891

See merge request !514
2017-04-11 12:49:44 +00:00
akwizgran
6d2b18facc Merge branch '799-explain-content-visibility' into 'master'
Show explanation about visibility in member lists

Closes #799

See merge request !516
2017-04-07 14:54:41 +00:00
Torsten Grote
f8cf7034db Show explanation about visibility in member lists 2017-04-07 11:38:33 -03:00
akwizgran
a1e65c9fa7 Merge branch '893-double-introduction-accept' into 'master'
Prevent conversation actions from being executed twice

Closes #893

See merge request !512
2017-04-07 14:03:40 +00:00
Torsten Grote
499d2fe677 Prevent conversation actions from being executed twice 2017-04-07 10:00:55 -03:00
Torsten Grote
fe963edd9d Merge branch '829-new-launcher-icon' into 'master'
Use the new launcher icon

Closes #829

See merge request !515
2017-04-07 12:59:35 +00:00
akwizgran
96f006068f Use the new launcher icon. 2017-04-07 13:57:13 +01:00
akwizgran
74f1fa5690 Merge branch '932-panic-button-terminate-process' into 'master'
Terminate the process after handling a panic trigger

Closes #932

See merge request !513
2017-04-07 12:49:52 +00:00
Torsten Grote
85c17b4cb0 Fix MessageId calculation for deprecated MessageQueue
This was preventing introduction messages from getting ACKed.
The introduction tests were modified to check for this.
2017-04-07 09:45:35 -03:00
akwizgran
6b3a1fd6d4 Merge branch 'fix-test-configuration' into 'master'
Fix "all tests" configuration

See merge request !509
2017-04-07 10:19:01 +00:00
akwizgran
bcabcfce8c Merge branch '925_panic_app_market' into 'master'
Refine the panic app list tap behavior

Closes #925

See merge request !511
2017-04-07 10:17:48 +00:00
goapunk
db0a3bf380 Refine the panic app list behavior
* Only open if a market is installed

Signed-off-by: goapunk <noobie@goapunks.net>
2017-04-07 12:07:10 +02:00
akwizgran
d5d9436e28 Terminate the process after handling a panic trigger. 2017-04-07 10:54:51 +01:00
Torsten Grote
0827b067ec Harmonize position of boolean message variables 2017-04-06 15:42:12 -03:00
akwizgran
9d0dbe9210 Merge branch '885_store_only_four_lan_ip' into 'master'
Store only 4 ip addresses because 5 exceed the maximum length.

Closes #885

See merge request !510
2017-04-06 14:38:49 +00:00
akwizgran
1f7d1bf515 Merge branch '675-polite-executor' into 'master'
Use a polite executor for validation tasks

Closes #675

See merge request !507
2017-04-06 14:37:59 +00:00
akwizgran
fb85ecf07b Added note about number of available processors changing. 2017-04-06 15:34:39 +01:00
akwizgran
a931e6b316 Merge branch '906_tapjacking' into 'master'
Add tapjacking protection

Closes #906

See merge request !502
2017-04-06 14:31:10 +00:00
akwizgran
3aa4644339 If we have multiple cores, leave one free from crypto tasks. 2017-04-06 11:36:02 +01:00
goapunk
9a638c804a Store only 4 ip addresses because 5 exceed the maximum length.
Signed-off-by: goapunk <noobie@goapunks.net>
2017-04-06 12:35:44 +02:00
akwizgran
df3254c634 Fix "all tests" configuration.
The last (empty) stage of this configuration used to
complain about not finding any tests. I replace the last
stage with a copy of the briar-android configuration
and removed briar-android from the list of prerequisites,
so all stages now contain tests.
2017-04-06 10:18:42 +01:00
akwizgran
ba353b9f2b List of wifi configs can be null. 2017-04-06 10:11:59 +01:00
goapunk
04c4e70dd1 Add tapjacking protection
* Set filterTouchesWhenObscured for all views
* Warn the user if Apps using the SYSTEM_ALERT_WINDOW permission are installed
* Warn the user if an App using the permission is installed while Briar is running

Signed-off-by: goapunk <noobie@goapunks.net>
2017-04-05 23:25:57 +02:00
akwizgran
d381e25e86 Limit the number of validation tasks on the crypto executor. 2017-04-05 17:34:21 +01:00
akwizgran
0c085f139a Added "polite" delegating executor. 2017-04-05 17:34:20 +01:00
akwizgran
4123f4a5ce Log time spent queueing and executing crypto and DB tasks. 2017-04-05 17:34:15 +01:00
akwizgran
7bc269fda4 Merge branch '914-simpler-secure-random' into 'master'
Remove Fortuna generator, fix Android SecureRandom bug

Closes #914

See merge request !500
2017-04-05 10:55:25 +00:00
akwizgran
a22931bae6 Merge branch '928-move-html-sanitation-to-dbthread' into 'master'
Move HTML Sanitation to DbThread

Closes #928

See merge request !506
2017-04-04 16:54:21 +00:00
akwizgran
403f886110 Merge branch '910-fix-intent-hijacking' into 'master'
Fix possible intent hijacking for implicit pending intents

Closes #910

See merge request !499
2017-04-04 16:34:38 +00:00
Torsten Grote
b7866be38d Move HTML Sanitation to DbThread 2017-04-04 13:27:06 -03:00
akwizgran
a1b415330e Merge branch '926-class-cast-exception' into 'master'
Don't cast Context to BaseActivity

Closes #926

See merge request !505
2017-04-04 12:44:38 +00:00
Torsten Grote
58318bb79f Remove pending intents for clearning notification counters
These counters are already reset when the user clicks the notification
or vists the area of the app the notifications are for.

This also removes a potential intent hijacking vulnerability.
2017-04-04 09:02:38 -03:00
akwizgran
10bb30e190 Don't assume Context is a BaseActivity. 2017-04-03 12:22:52 +01:00
akwizgran
199a2ffc46 Merge branch '909-prevent-multiple-password-screens' into 'master'
Prevent multiple instances of PasswordActivity

Closes #909

See merge request !504
2017-03-31 13:42:04 +00:00
akwizgran
f6ad2992f2 Prevent multiple instances of PasswordActivity. 2017-03-31 12:55:38 +01:00
akwizgran
f039bd1239 Merge branch '909-restrict-access-to-panic-prefs' into 'master'
Don't allow other apps to open the panic prefs activity

See merge request !503
2017-03-31 08:25:21 +00:00
Torsten Grote
da22d91ef3 Update expiry date and translations 2017-03-30 15:35:02 -03:00
Torsten Grote
cd360ec877 Merge branch '909-restrict-access-to-settings-activity' into 'master'
Require a system permission to open the settings activity

See merge request !501
2017-03-30 12:58:07 +00:00
akwizgran
8e1ada4cdc Don't allow other apps to open the panic prefs activity. 2017-03-30 12:26:33 +01:00
akwizgran
ac063b4c79 Require a system permission to open the settings activity. 2017-03-30 12:00:35 +01:00
akwizgran
10e6163e94 Merge branch '915-fix-forumactivitytest' into 'master'
Fix ForumActivityTest

Closes #915

See merge request !496
2017-03-30 08:19:30 +00:00
Torsten Grote
ebc3402307 Merge branch '912-validate-stream-encrypter-args' into 'master'
Validate arguments to StreamEncrypter#writeFrame()

Closes #912

See merge request !497
2017-03-29 16:52:54 +00:00
akwizgran
d9c63bbcfe Remove Fortuna generator, fix Android SecureRandom bug. 2017-03-29 16:31:59 +01:00
akwizgran
9c89e83c20 Merge branch '913-simpler-password-strength-estimation' into 'master'
Simpler password strength estimation

Closes #913

See merge request !495
2017-03-29 15:01:44 +00:00
akwizgran
adc9bdeb68 Merge branch 'run-configurations' into 'master'
Run configurations for tests

See merge request !498
2017-03-29 08:18:05 +00:00
akwizgran
ff7f0bdc63 Added run configurations for tests to git. 2017-03-28 15:36:18 +01:00
Torsten Grote
c5f6980c69 Fix ForumActivityTest 2017-03-28 09:34:42 -03:00
akwizgran
2574354997 Merge branch '905_set_testing_constant_on_debug' into 'master'
Set TESTING from BuildConfig

Closes #905

See merge request !494
2017-03-28 12:30:00 +00:00
akwizgran
c4e42949cf Simpler password strength estimation. 2017-03-28 13:27:04 +01:00
goapunk
1c5897f1cc Set TESTING from BuildConfig
Signed-off-by: goapunk <noobie@goapunks.net>
2017-03-27 23:39:39 +02:00
akwizgran
510f99c7da Validate arguments to StreamEncrypter#writeFrame(). 2017-03-27 16:26:49 +01:00
akwizgran
1918346ae8 Merge branch '911-link-sanitation' into 'master'
Sanitize all HTML before displaying it

Closes #911

See merge request !493
2017-03-27 09:45:17 +00:00
akwizgran
2a59515c72 Merge branch '907-panic-signout' into 'master'
Require a panic app to be set before executing any panic actions

Closes #907

See merge request !492
2017-03-27 09:43:30 +00:00
akwizgran
7161152b41 Merge branch '903_replace_Runtime_with_ProcessBuilder' into 'master'
Use ProcessBuilder instead of Runtime to start tor

See merge request !487
2017-03-27 09:37:00 +00:00
akwizgran
b42660edab Merge branch 'emoji-soft-reference' into 'master'
Fix potential NPE when getting soft reference

See merge request !490
2017-03-27 09:28:30 +00:00
akwizgran
b405bbf98e Merge branch 'setting-to-disable-tor' into 'master'
Add a setting to disable Tor

See merge request !489
2017-03-27 09:27:56 +00:00
akwizgran
c167938b61 Use constants for Tor network setting values. 2017-03-27 10:26:10 +01:00
Torsten Grote
24b531e6b2 Sanitize all HTML before displaying it 2017-03-24 16:45:36 -03:00
Torsten Grote
9cffff715a Require a panic app to be set before executing any panic actions 2017-03-24 16:19:09 -03:00
Torsten Grote
804e912e19 Merge branch 'remove-placeholder-tests' into 'master'
Remove placeholder tests

See merge request !491
2017-03-24 18:12:13 +00:00
akwizgran
d67e3900e3 Removed placeholder tests.
Evidently this way of nagging myself to write tests doesn't work.
2017-03-24 15:18:37 +00:00
akwizgran
e682f31898 Added a setting to disable Tor.
Also fixed a bug with settings namespaces.
2017-03-24 14:56:30 +00:00
akwizgran
a9053808b4 Merge branch '908-rss-import-dns-leak' into 'master'
Don't make DNS lookups during RSS import

Closes #908

See merge request !488
2017-03-24 10:02:19 +00:00
akwizgran
d9a62a0431 Merge branch 'print_tor_errors' into 'master'
Make Tor boot more verbose

See merge request !486
2017-03-24 10:01:29 +00:00
akwizgran
15ba73276d Merge branch '900-remove-error-state' into 'master'
Remove error state and reset session on error instead

Closes #900

See merge request !484
2017-03-24 09:57:03 +00:00
Torsten Grote
720dda784e Remove error state and reset session on error instead 2017-03-23 14:14:23 -03:00
akwizgran
0ae55404f5 Merge branch '900-simplify-sharing-client-state-machine' into 'master'
Remove REMOTE_LEFT state from sharing client state machine

See merge request !483
2017-03-23 16:13:44 +00:00
akwizgran
9c41437870 Prevent OkHttp from making local DNS lookups. 2017-03-23 15:13:15 +00:00
akwizgran
da9cde083f Include description of SOCKS error in exception. 2017-03-23 15:13:15 +00:00
goapunk
ce3156c9fe Use ProcessBuilder instead of Runtime to start tor
* ProcessBuilder copies the ENV from the current proc
  and preserves ANDROID_ROOT and ANDROID_DATA

Signed-off-by: goapunk <noobie@goapunks.net>
2017-03-18 09:46:24 +01:00
goapunk
be3752bf2f Set Android env vars
Signed-off-by: goapunk <noobie@goapunks.net>

(cherry picked from commit e26f663)
2017-03-17 16:00:34 +00:00
noobie
ef74db65aa Make Tor boot more verbose
Signed-off-by: noobie <noobie@goapunks.net>
2017-03-13 12:19:14 +01:00
Torsten Grote
867a233b6f Update expiry 2017-03-06 18:46:15 +01:00
Torsten Grote
36f02b36d9 Update expiry and translations 2017-02-01 11:17:53 -02:00
Torsten Grote
59af25b2cd Remove REMOTE_LEFT state from sharing client state machine 2017-01-12 15:19:28 -02:00
akwizgran
2fb11fba2a Merge branch '877-save-invitation-outcome-to-invitation-message-and-make-available-to-ui' into 'master'
Store invitation outcome in metadata and make it available to the UI

This MR is based on !479 and should only be merged after that one has been merged as well.

It stores the invitation outcome in the message metadata  and includes it in the `canBeOpened()` calculation for private groups and sharables.

Closes #877

See merge request !480
2017-01-06 16:06:19 +00:00
akwizgran
1d11857e75 Merge branch '476-blog-sharing-protocol-modifies-state-external-to-session' into 'master'
Migrate blog sharing to new sharing client infrastructure

This MR contains a second small commit that fixes #816 and adds a test for it.

Closes #476, #701

See merge request !479
2017-01-06 16:04:17 +00:00
Torsten Grote
04508a7431 Store invitation outcome in metadata
and include in canBeOpened calculation for private groups and sharables.
2017-01-06 13:29:21 -02:00
Torsten Grote
5653c6d650 Address review comments 2017-01-06 13:25:13 -02:00
Torsten Grote
ab100ad19b Properly remove the blog when deleting a contact and inform all peers
Fixes #816
2017-01-06 13:01:37 -02:00
Torsten Grote
c13eafef14 Migrate blog sharing to new sharing client infrastructure 2017-01-06 13:01:34 -02:00
akwizgran
d5443e9651 Merge branch '889-select-navdrawer-item-when-coming-from-notification' into 'master'
Check the blog item in NavDrawer when opening a blog via notification

There are three scenarios where the selected item in the NavDrawer changes:
1. The user selects an item -> the item is checked automatically.
2. The user pressed back -> already handled in onBackPressed (needs to be extended with #606)
3. The user touched a notification -> handled by this commit.
   
Signed-off-by: goapunk <noobie@goapunks.net>

Closes #889

See merge request !481
2017-01-06 14:59:21 +00:00
akwizgran
d5f9a3280d Merge branch 'briar-recycler-view-log' into 'master'
Stop periodic list update only once

When testing the forum unread code, I noticed the recycler view is detaching twice. Once because the stop method is called and once because the view detaches from the window. Wouldn't it be safe to null the refresher when the updates are stopped?

See merge request !478
2017-01-06 14:15:48 +00:00
goapunk
09b2ecaecf Check the corresponding NavDrawer item when coming from a notification
Signed-off-by: goapunk <noobie@goapunks.net>
2017-01-06 15:12:40 +01:00
Torsten Grote
dc6a6f27ab Fix MessageTreeImplTest 2017-01-04 16:27:49 -02:00
Torsten Grote
8d9ddeeeee Stop periodic list update only once 2017-01-04 11:15:19 -02:00
Torsten Grote
baed2b8483 Merge branch '879-remove-thread-collapsing-unread-count' into 'master'
Remove code for collapsing threads and for reply count

Besides removing lots of code, this MR also improves the encapsulation between adapter and view holders.

Closes #478, #502, #526, #682,  #683,  #835,  #836

See merge request !477
2017-01-04 13:00:16 +00:00
Torsten Grote
b3d3230549 Remove code for collapsing threads and for reply count 2017-01-04 10:58:31 -02:00
akwizgran
deb8787668 Merge branch '879-threaded-unread-messages' into 'master'
Threaded Unread Handling

![unread](/uploads/457c3bc36c897d683ff8161b4f3a344c/unread.mp4)

This leaves in the collapsing code for now and just hides the UI element for collapsing. The code can be removed in a second pass to simplify the adapter.

Closes #879

See merge request !476
2017-01-04 11:12:24 +00:00
Torsten Grote
7034ea28f3 Merge branch '475-new-sharing-client' into 'master'
New Forum Sharing Client

This is very similar to how the private group invitations work and I am sure there's still some tiny bugs that I didn't catch.

All existing integration tests either pass or have been modified to pass.

Once this has been merged, the code should be usable for blog sharing as well.

Closes #475

See merge request !467
2017-01-03 19:30:48 +00:00
Torsten Grote
51b78cf9b1 Address review comments for new sharing client 2017-01-03 17:25:45 -02:00
Torsten Grote
b4c669243b Add UnreadMessageButton to threaded conversations 2017-01-03 13:25:31 -02:00
Torsten Grote
694e662028 New Forum Sharing Client 2017-01-03 11:23:02 -02:00
Torsten Grote
409e0fb5a5 ForumSharingValidator 2017-01-03 11:23:00 -02:00
Torsten Grote
279f4d668a Add new UnreadMessageButton class 2017-01-02 16:30:00 -02:00
akwizgran
d2608e28ac Merge branch '881-forumactivitytest-fails-due-to-custom-toolbar' into 'master'
Fix ForumActivityTest and get rid of redundant theme definition

Closes #881

See merge request !474
2017-01-02 14:22:27 +00:00
akwizgran
8cf02c5f0e Merge branch '851-refresher-memory-leak' into 'master'
Fix memory leaks caused by periodic view refreshing tasks

This branch implements @goapunk's suggested solution to #851. Credit goes to @ernir for finding the bug and the initial solution, and @goapunk for the improved solution - I just did a quick implementation so we can get this fixed as quickly as possible.

Closes #851

See merge request !473
2017-01-02 14:10:32 +00:00
Torsten Grote
c5df2100da Fix ForumActivityTest and get rid of redundant theme definition 2017-01-02 11:57:45 -02:00
akwizgran
a6999a8197 Merge branch '710-conversationactivity-uses-uninitialised-field-as-format-string-argument' into 'master'
Make sure contact name is initialized when needed

This uses a Listenable Future and unfortunately requires 4 basically identical methods to handle the incoming events. Any suggestions for improving that are welcome.

Closes #710

See merge request !472
2017-01-02 11:11:41 +00:00
akwizgran
da89f11419 Merge branch '882-feedmanagerimpl-logs-rss-feed-urls' into 'master'
Do not log information from RSS feeds

Closes #882

See merge request !475
2017-01-02 10:52:04 +00:00
Torsten Grote
a9663875f4 Update expiry date and translations 2016-12-30 12:13:43 -02:00
Torsten Grote
804966ede6 Do not log information from RSS feeds 2016-12-29 13:07:18 -02:00
Torsten Grote
f0f22b42e5 Make sure contact name is initialized when needed 2016-12-29 12:29:32 -02:00
akwizgran
59316ae3c4 Fix memory leaks caused by periodic view refreshing tasks. 2016-12-28 15:23:21 +00:00
akwizgran
79c78518fb Fix potential NPE when getting soft reference. 2016-12-28 13:47:33 +00:00
Torsten Grote
460b524e4b Merge branch 'record-reading-tests' into 'master'
Unit tests for record readers

I thought we should have some tests for the new logic that skips unrecognised record types.

See merge request !471
2016-12-21 17:14:16 +00:00
akwizgran
48e949c9f8 Merge branch '742-use-unique-request-ids-across-the-app' into 'master'
Use unique request codes across the app

Closes #742

See merge request !470
2016-12-21 15:33:03 +00:00
Torsten Grote
924398c829 Use unique request codes across the app 2016-12-21 12:52:11 -02:00
akwizgran
8619b044ce Merge branch '469-handle-background-errors' into 'master'
Add a handleDbException() method to BaseActivity

This adds a `handleDbException()` method to BaseActivity and a corresponding method for fragments that calls through to the activity.
For now, the method just finishes the activity
and NavDrawerActivity overrides it to do nothing,
and all the error places marked with TODO that finish the activity call the method instead.

That gives us zero functional improvement over the status quo,
but it allows us to change the default behaviour easily,
and then we can start thinking about which cases should have non-default behaviour.

First part of #469

See merge request !469
2016-12-21 14:46:53 +00:00
akwizgran
3c3731a562 Merge branch '876-group-invitation-not-marked-unavailable' into 'master'
Mark invitation unavailable to answer when creator dissolved the group after the invitation.

Closes #876

See merge request !468
2016-12-21 14:43:38 +00:00
akwizgran
b54984b542 Unit tests for RecordReaderImpl. 2016-12-21 14:39:56 +00:00
akwizgran
2390f767f5 Unit tests for KeyAgreementTransport. 2016-12-21 14:08:21 +00:00
Torsten Grote
0a9840997f This adds a handleDbException() method to BaseActivity
and a corresponding method for fragments that calls through to the activity.
For now, the method just finishes the activity
and NavDrawerActivity overrides it to do nothing,
and all the error places marked with TODO that finish the activity call the method instead.

That gives us zero functional improvement over the status quo,
but it allows us to change the default behaviour easily,
and then we can start thinking about which cases should have non-default behaviour.
2016-12-21 12:06:20 -02:00
Torsten Grote
6a94785d9a Mark invitation unavailable to answer when creator dissolved the group
after the invitation.

Closes #876
2016-12-21 11:24:08 -02:00
akwizgran
79fc41477c Merge branch '628-bring-protocols-into-line-with-spec' into 'master'
Bring protocols in line with spec

Closes #628

See merge request !465
2016-12-21 12:52:43 +00:00
Torsten Grote
efb89adf41 Merge branch '793-show-open-button-after-accepting-invitations' into 'master'
Show open button in private conversation after accepting invitations

To keep the implementation simple, the Open button does appear where the Accept button had been previously.

In order to make the Open button functional, I had to make the `GroupId` of the invitation target available to the UI. Most code in this MR is due to that.

![device-2016-12-13-105228](/uploads/d0f27fc02f1411596458d9203a0810d2/device-2016-12-13-105228.png)

Closes #793

See merge request !457
2016-12-20 14:07:13 +00:00
Torsten Grote
c04580e321 Don't open unsubscribed shareables 2016-12-20 12:00:01 -02:00
Torsten Grote
2ef9b8f4b6 Show open button in private conversation after accepting invitations 2016-12-20 08:47:27 -02:00
akwizgran
d63d15329c Merge branch '814-enable-QrScanner-after-QrCode-was-created' into 'master'
Ignore QR code results until local QR code is created

* Make scanning only possible after we are "ready" (= our QrCode was created and set).

Signed-off-by: goapunk <noobie@goapunks.net>

Closes #814

See merge request !454
2016-12-19 19:28:14 +00:00
Torsten Grote
5345db0b6b Address review comments 2016-12-19 11:15:53 -02:00
Torsten Grote
501980d8fe Bring protocols in line with spec 2016-12-19 10:26:48 -02:00
akwizgran
cc5c000278 Merge branch '738-older-devices-show-overflow-icon-on-some-screens-but-not-others' into 'master'
Also show overflow icon on devices with menu key by using Toolbar

Closes #738

See merge request !463
2016-12-16 11:58:18 +00:00
akwizgran
3ce0131b8c Merge branch '828-update-briar-logo-in-app' into 'master'
Update all logos

The launcher icons are now in mipmap folders which is the recommended practice, because on a low-res device, the high res drawables are stripped from the app. This is bad when the user decides to show the app icons really big on the launcher and the high-res drawables are not available anymore.

The old launcher icon seemed to have some sort of 3D effect.
![device-2016-12-13-134037](/uploads/84db532df3821ad74ba57719f0763b7b/device-2016-12-13-134037.png)

Navigation Drawer Old:
![device-2016-12-13-124112](/uploads/465b817d2e0bbbd50b461ea32686c933/device-2016-12-13-124112.png)
Navigation Drawer New:
![device-2016-12-13-132428](/uploads/3c3530bfc515525dd8f66abfa52d1142/device-2016-12-13-132428.png)

Closes #828

See merge request !459
2016-12-15 23:25:40 +00:00
akwizgran
008e4f760a Merge branch '795-use-different-notification-icons-for-different-features' into 'master'
Use different notification icons for different features

![device-2016-12-13-151008](/uploads/2c9aa33c230738b5ea20a76ac5e3b214/device-2016-12-13-151008.png)
![device-2016-12-13-150954](/uploads/85acd46fc6afd3aebcc1fcd015b041d7/device-2016-12-13-150954.png)

Closes #795

See merge request !460
2016-12-15 23:16:36 +00:00
akwizgran
fc44268b22 Removed translations of unused strings. 2016-12-15 23:12:24 +00:00
akwizgran
de0a7c75ed Merge branch '697-include-commit-id-in-crash-reports-and-feedback' into 'master'
Include Commit ID in crash reports and feedback

Closes #697

See merge request !461
2016-12-15 23:06:24 +00:00
Torsten Grote
1c6be2fb78 Include Commit ID in crash reports and feedback 2016-12-15 15:40:52 -02:00
Torsten Grote
09b0a8b161 Use different notification icons for different features
and use the primary color for the notification.
2016-12-15 15:29:48 -02:00
Torsten Grote
a6d053a0ea Update all logos 2016-12-15 15:19:38 -02:00
akwizgran
e7a26c42a4 Merge branch '285-plugins-should-throw-exceptions-for-startup-errors' into 'master'
Plugins throw exceptions for startup errors

Please review carefully as I don't know much about the code I have touched here.

Closes #285

See merge request !462
2016-12-15 14:33:35 +00:00
akwizgran
bb5fc35e17 Removed translations of unused strings. 2016-12-15 10:56:04 +00:00
Torsten Grote
ea4e2f09c8 Revert dagger update 2016-12-14 16:52:38 -02:00
Torsten Grote
ffc9fdbb92 Plugins throw exceptions for startup errors 2016-12-14 16:35:23 -02:00
akwizgran
074f5c2faf Fix imports in HashTest. 2016-12-14 17:09:15 +00:00
goapunk
7666b210e4 Ignore results from the QrScanner if task is not ready
* Ignore results until the KeyAgreementTask is ready and returned the local payload

Signed-off-by: goapunk <noobie@goapunks.net>
2016-12-14 17:28:01 +01:00
akwizgran
ab3fcb6219 Merge branch 'add-crypto-hash-test' into 'master'
Add Unit tests for CryptoComponent#hash()

See merge request !464
2016-12-14 16:14:18 +00:00
akwizgran
b7e35ff780 Merge branch '778-move-unit-tests-into-their-respective-modules' into 'master'
Move all unit tests to their modules and remove briar-tests

There are now tests in these modules:
* bramble-api
* bramble-core
* bramble-j2se
* briar-core
* briar-android

In order to run all -core tests together, the following AS run configuration can be used:
![Screenshot_2016-12-12_16-37-53](/uploads/8c706406f015ecd9e2371ebc28e6b34c/Screenshot_2016-12-12_16-37-53.png)

Closes #778

See merge request !456
2016-12-14 15:57:45 +00:00
akwizgran
3c2428449d Moved test utility classes into test package. 2016-12-14 15:42:52 +00:00
Torsten Grote
25a4caec2a Add Unit tests for CryptoComponent#hash() 2016-12-14 13:15:44 -02:00
Torsten Grote
db71472501 Also show overflow icon on devices with menu key by using Toolbar 2016-12-14 11:17:04 -02:00
Torsten Grote
1081a08ea9 Move all unit tests to their modules and remove briar-tests 2016-12-13 17:22:24 -02:00
akwizgran
32be148c7a Merge branch '646-shared-with-subtitle-groups' into 'master'
Add sharing information to private group ActionBar subtitle

![device-2016-12-12-114533](/uploads/b31fc37643ef6e817a80a4ddd767fe98/device-2016-12-12-114533.png)

Closes #646

See merge request !455
2016-12-13 18:01:48 +00:00
Torsten Grote
78000375df Merge branch '155-notification-icon' into 'master'
Make notification icon less similar to superuser icon

Closes #155

See merge request !458
2016-12-13 17:24:05 +00:00
akwizgran
66f8978bb6 Make notification icon less similar to superuser icon. 2016-12-13 17:20:48 +00:00
Torsten Grote
45b5040254 Add sharing information to private group ActionBar subtitle 2016-12-12 13:55:35 -02:00
Torsten Grote
378a8f0a10 Merge branch '813-add-online-status-and-creator-information-to-group-memberlist' into 'master'
Add creator and online information to group member list

![device-2016-12-06-102258](/uploads/90e19a6ca31aaf91c6ebf3ea8e218b3f/device-2016-12-06-102258.png)
![device-2016-12-06-110113](/uploads/3fd62f7cdfe75419a07262356d27b952/device-2016-12-06-110113.png)

Closes #813

See merge request !448
2016-12-12 15:36:02 +00:00
Torsten Grote
562866494b Add creator and online information to group member list 2016-12-12 13:33:23 -02:00
akwizgran
c9cb085a0a Merge branch '777-move-integration-tests-into-their-respective-modules' into 'master'
Move integration tests to their proper packages

Closes #777

See merge request !453
2016-12-12 15:08:26 +00:00
Torsten Grote
97d4c68f43 Move integration tests to their proper packages 2016-12-12 10:27:41 -02:00
Torsten Grote
4226ba40c2 Merge branch '570-consistent-use-of-animations' into 'master'
Make animations more consistent

![animations6](/uploads/0ac694d3561515e04fbb9032d31f183c/animations6.mp4)

Closes #570, #621

See merge request !439
2016-12-09 16:49:26 +00:00
Torsten Grote
3df3d19a07 Address review comments 2016-12-09 14:40:20 -02:00
Torsten Grote
e3dcc62509 Use back transition when backing out of creating private group 2016-12-09 14:22:05 -02:00
Torsten Grote
db3c3eee44 Move OnBlogPostClickListener from activity to fragment 2016-12-09 14:22:03 -02:00
Torsten Grote
5a522d64df Don't show splash screen when signed in
This also removes the BriarFragmentActivity that was only really used by
the NavDrawerActivity.
2016-12-09 14:14:47 -02:00
Torsten Grote
68b216d580 Make animations more consistent 2016-12-09 14:13:18 -02:00
Torsten Grote
d5c6fcc85b Fix merge accident after renaming event 2016-12-09 14:12:27 -02:00
Torsten Grote
a099104d08 Merge branch '646-shared-with-subtitle-forums' into 'master'
Add sharing info to ForumActivity action bar subtitle

This indirectly does also most of the work for adding the same information to private groups. However, completing this is blocked by !448.

![device-2016-12-07-152915](/uploads/5bb42f2e78a87931b0307e7597ba72c5/device-2016-12-07-152915.png)

Second part of #646

See merge request !451
2016-12-09 16:06:21 +00:00
akwizgran
787b3399f7 Merge branch '646-shared-with-subtitle' into 'master'
Add blog sharing information to toolbar subtitle

This MR introduces a new `SharingController` which is supposed to be used in activities that show blogs, groups and forums. Feedback on this approach is welcome before this is used to add "Shared with" support to other parts of the UI.

The toolbar subtitle shows information about how many contacts the current shareable is shared with and how many of those are online.

So far this is implemented for blogs:

![device-2016-12-05-180207](/uploads/13afb4c7c5d10ad29c414865ee02670d/device-2016-12-05-180207.png)

One part of #646

See merge request !447
2016-12-09 16:04:04 +00:00
Torsten Grote
4e159bbb1f Add sharing info to ForumActivity action bar subtitle 2016-12-09 14:02:42 -02:00
Torsten Grote
7c6232db9d Address review comments (rename event, fix annotations, final field) 2016-12-09 13:54:39 -02:00
Torsten Grote
6cf1480d2d Merge branch '766-unit-tests-for-peer-protocol-engine' into 'master'
Add unit tests for PeerProtocolEngine

Although not all classes have unit tests, this

Closes #766

See merge request !450
2016-12-08 16:14:34 +00:00
Torsten Grote
2679e6932f Add unit tests for PeerProtocolEngine 2016-12-08 14:13:00 -02:00
akwizgran
17e149e517 Merge branch '766-unit-tests-for-invitee-protocol-engine' into 'master'
Add unit tests for InviteeProtocolEngine

Next part of #766

See merge request !444
2016-12-08 15:42:05 +00:00
Torsten Grote
d04dda1566 Add sharing information to toolbar subtitle of blogs
The toolbar subtitle shows information about how many contacts the
current blog is shared with and how many of those are online.
2016-12-07 15:16:44 -02:00
Torsten Grote
5588855667 Fix intent of some CreatorProtocolEngine unit tests 2016-12-07 15:07:01 -02:00
Torsten Grote
7df6abbcbe Merge branch '810-fix-sharing-status-screens' into 'master'
Fix Sharing Status screens

* Remove distinction between "shared with" and "shared by"
* Show all contacts a blog is shared with
* Show online status of contacts in sharing screen

![device-2016-12-05-142949](/uploads/703fbd2d52815374e57edd89f754bf6c/device-2016-12-05-142949.png)

Closes #810

See merge request !445
2016-12-07 16:52:29 +00:00
Torsten Grote
001f5faeaa Two small review details: comment and initializing boolean 2016-12-07 14:49:57 -02:00
Torsten Grote
ba1a19d236 Address review issues 2016-12-07 14:31:24 -02:00
Torsten Grote
b7ce7de42a Add unit tests for InviteeProtocolEngine 2016-12-07 14:31:23 -02:00
akwizgran
3f6a8f9341 Merge branch '808-introduction-client-logs-contact-names' into 'master'
Remove verbose logging from introduction client

Closes #808

See merge request !449
2016-12-07 15:49:14 +00:00
akwizgran
9495163016 Merge branch 'onboarding-dialog-style' into 'master'
Introduce Dialog Theme for Onboarding

Currently onboarding dialogs and confirmation dialogs look the same. This MR introduces a new dialog theme for onboarding dialogs that looks like the tap target onboarding, so that the user can immediately spot the purpose of the dialog.

![device-2016-12-06-085539](/uploads/6d75b17c0f20028bb7ffac65e6fba03a/device-2016-12-06-085539.png)

See merge request !446
2016-12-07 15:47:12 +00:00
Torsten Grote
7f5a5d40dc Remove verbose logging from introduction client 2016-12-06 15:36:54 -02:00
Torsten Grote
98dd8ec7f7 Fix Sharing Status screens
* Remove distinction between "shared with" and "shared by"
* Show all contacts a blog is shared with
* Show online status of contacts in sharing screen
2016-12-06 10:53:50 -02:00
akwizgran
27c2ee8d89 Merge branch '548-require-a-label-for-hashing' into 'master'
Require a label for hashing

* Add a string label argument to `CryptoComponent#hash()`
* Convert `DoubleDigest` from implementing `MessageDigest`
  to implementing `org.spongycastle.crypto.Digest`
  (we need to keep `DoubleDigest` for `FortunaGenerator`)
* Convert all other uses of `MessageDigest` to `CryptoComponent#hash()`
* Remove `CryptoComponent#getMessageDigest()`, `MessageDigest` and `DigestWrapper`

Closes #548

See merge request !442
2016-12-06 11:07:58 +00:00
Torsten Grote
b98ab93e77 Merge branch '283-die-bluetooth-die' into 'master'
Ensure key agreement tasks finish if they ignore interrupts

The problem here was that `BluetoothSocket#connect()` was throwing an IOException when the task was interrupted - the task treated this like any other connection failure and retried, so the task never finished.

The fix is to check whether the timeout has expired before retrying, so the task eventually finishes even if it ignores the original interrupt.

Closes #283

See merge request !443
2016-12-06 11:02:19 +00:00
Torsten Grote
81337fe7ad Introduce Dialog Theme for Onboarding 2016-12-05 14:54:39 -02:00
akwizgran
cdd234dfe3 Ensure key agreement tasks finish if they ignore interrupts. 2016-12-05 12:38:45 +00:00
Torsten Grote
062ed4ef4b Require a label for hashing
* Add a string label argument to CryptoComponent#hash()
* Convert DoubleDigest from implementing MessageDigest
  to implementing org.spongycastle.crypto.Digest
  (we need to keep DoubleDigest for FortunaGenerator)
* Convert all other uses of MessageDigest to CryptoComponent#hash()
* Remove CryptoComponent#getMessageDigest(), MessageDigest and DigestWrapper
2016-12-05 09:57:18 -02:00
akwizgran
9c22ea8434 Merge branch '766-unit-tests-for-creator-protocol-engine' into 'master'
Add unit tests for CreatorProtocolEngine

See merge request !441
2016-12-05 09:59:40 +00:00
Torsten Grote
9458b185f8 Add unit test for CreatorProtocolEngine 2016-12-02 10:57:00 -02:00
akwizgran
c2b06536ad Merge branch 'identity-manager-unit-tests' into 'master'
Add missing IdentityManager unit tests

See merge request !440
2016-12-02 10:35:15 +00:00
akwizgran
878b52ef2c Merge branch '771-create-bramble-modules' 2016-12-01 21:48:03 +00:00
Torsten Grote
a9ddb0019e Add missing IdentityManager unit tests 2016-12-01 13:21:09 -02:00
akwizgran
2d7cb7b279 Updated Transifex config. 2016-12-01 10:19:24 +00:00
akwizgran
f25d33b0c8 Move stray resources to the right place. 2016-12-01 10:18:42 +00:00
akwizgran
906dd1bd06 Added .gitignore files for new modules. 2016-12-01 10:08:46 +00:00
akwizgran
ad6016d428 Updated java.library.path. 2016-11-30 18:10:49 +00:00
akwizgran
f6d23b4d1a Merge branch '705-blog-pager-race-conditions' into 'master'
Remove blog pagers

I set out to fix potential race conditions in the blog pagers (the screens you reach by tapping the body of a blog post, that allow you to swipe left and right through the posts in the combined feed or a single blog). The race conditions here are similar to those addressed by !356, but the adapters don't inherit from BriarAdapter so they need to be fixed separately.

While I was looking into this I found a few minor problems with the pagers:
* The feed pager wasn't responding to events - this was fixed in !398
* The feed pager finishes NavDrawerActivity when any blog is removed
* The feed isn't updated when a blog is added (this applies to the list view as well as the pager)
* Posts aren't removed from the feed pager when a blog is removed

The last problem is quite serious - the feed pager's adapter contains posts that are no longer in the DB, so they'll fail to load. To fix that problem, the adapter needs to be cleared in onStop() and repopulated in onStart(). This is the same approach we use for other adapters where items can be removed from the underlying dataset. Unfortunately, FragmentStatePagerAdapter has some odd behaviour when you clear and repopulate it:

1. When reselecting the previously selected item after clearing and repopulating the adapter, the item slides into view instead of just appearing, which makes it look like you've accidentally swiped.
2. Items are sometimes duplicated when clearing and repopulating the adapter, so swiping left or right shows another copy of the same post.

These problems only seem to happen if the adapter is cleared - adding new posts works fine on master, although I think there might be some luck involved - FragmentStatePagerAdapter doesn't seem to be designed to support items changing positions.

I spent a lot of time trying to resolve these problems before concluding that maybe it wasn't worth it, and we should just remove the pagers. That's what's currently implemented in this branch. Tapping the body of a post will show the full-length post, but you won't be able to swipe left or right.

The swiping functionality was nice to have, so if you have ideas for fixing the bugs I'd love to hear them. But I'd rather remove this functionality than keep it in a buggy state with no plan for how to fix it.

Closes #705

See merge request !400
2016-11-30 11:21:03 +00:00
akwizgran
aa064e853a Merge branch '760-integration-tests-for-private-group-invitation-protocol' into 'master'
Add integration tests for GroupInvitationManager

This MR is based on !433. It adds some integration tests for the private group invitation protocol. One of those tests fails at the moment.

It does not yet cover all corner cases, so it does not fully address #760, but addresses a part of it. Suggestions for more scenarios to test are welcome.

[Wording changed to prevent #760 from being closed automatically based on the description.]

See merge request !434
2016-11-30 11:19:05 +00:00
akwizgran
8a139eaf5d Tightened up test expectations. 2016-11-30 11:17:57 +00:00
akwizgran
d51f73151f Fixed a bug in the group invitation protocol, added tests. 2016-11-30 11:12:04 +00:00
akwizgran
6c90204c6e Fixed a broken unit test. 2016-11-30 11:07:30 +00:00
akwizgran
f8266d8a02 Tightened up some tests. 2016-11-30 10:23:43 +00:00
akwizgran
f245b04726 Fixed a failing test. 2016-11-30 10:23:43 +00:00
Torsten Grote
67d9f3a7c2 Add integration tests for GroupInvitationManager 2016-11-30 10:23:35 +00:00
akwizgran
24d68c4f5b Merge branch '727-refactor-integration-tests' into 'master'
Refactor Integration Tests

This is quite a massive MR (currently 1763 additions and 3482 deletions). However, there's not so much happening. The only thing I did was moving redundant code from the various protocol integration tests to the `BriarIntegrationTest` class.

All integration tests are still passing.

Closes #727

See merge request !433
2016-11-29 18:28:11 +00:00
akwizgran
edbd7f4eeb Addressed review comments. 2016-11-29 18:27:19 +00:00
akwizgran
2f7830e73f Merge branch '766-unit-tests-for-group-validators' into 'master'
Add unit tests for group validators

Part of #766

See merge request !436
2016-11-29 18:13:43 +00:00
akwizgran
a82fdca3d4 Added more private group invitation validation tests. 2016-11-29 18:12:32 +00:00
akwizgran
050111a994 Added some more private group validation tests, found a bug. 2016-11-29 17:46:46 +00:00
akwizgran
a22d1d811f Merge branch '766-unit-tests-for-group-invitation-client' into 'master'
Add unit tests for group invitation client

Part of #766

See merge request !429
2016-11-29 11:51:17 +00:00
akwizgran
90124e00ca Addressed review comments. 2016-11-29 11:50:20 +00:00
akwizgran
04323856de Merge branch '782-wrong-item-selected-in-navdrawer-onBackPressed' into 'master'
Fix Contacts Item always beeing selected if Back is pressed in the NavMenu

Signed-off-by: goapunk <noobie@goapunks.net>

Closes #782

See merge request !438
2016-11-28 17:07:24 +00:00
goapunk
cfcd36f21a Fix Contacts Item always beeing selected if Back is pressed in the NavMenu
Signed-off-by: goapunk <noobie@goapunks.net>
2016-11-28 16:29:41 +01:00
Ernir Erlingsson
2b9ccb4c42 Merge branch '782-wrong-item-selected-in-navdrawer-onBackPressed' into 'master'
Select the correct MenuItem when Back is pressed in NawDrawer

Signed-off-by: goapunk <noobie@goapunks.net>

Closes #782

See merge request !437
2016-11-28 08:37:53 +00:00
Ernir Erlingsson
6436e6688d Merge branch '477-private-messaging-text-bubble-and-header-overlap' into 'master'
Bring back the toolbar shadow

![device-2016-11-21-180111](/uploads/7cd5e6a1e7a4b79b6d7cf81377b148a0/device-2016-11-21-180111.png)

Closes #477

See merge request !431
2016-11-27 21:55:24 +00:00
Torsten Grote
8c7a532e2e Update translations before user testing 2016-11-27 13:38:26 -02:00
goapunk
47171f3e18 Select the correct MenuItem when Back is pressed in NawDrawer
Signed-off-by: goapunk <noobie@goapunks.net>
2016-11-26 23:09:07 +01:00
Torsten Grote
b37a7531ca Add unit tests for group validators 2016-11-23 18:53:03 -02:00
Torsten Grote
2850763ec6 Refactor Integration Tests 2016-11-22 13:31:58 -02:00
Torsten Grote
e69139bc24 Bring back the toolbar shadow 2016-11-21 18:32:29 -02:00
Torsten Grote
b0b932a01c Add unit tests for group invitation client 2016-11-21 16:57:28 -02:00
akwizgran
2837bde774 Removed blog post pagers 2016-11-11 13:38:04 +00:00
akwizgran
411549dc0a Code cleanup, use correct fragment class. 2016-11-11 13:37:32 +00:00
1775 changed files with 63713 additions and 45429 deletions

7
.gitignore vendored
View File

@@ -9,15 +9,18 @@ Thumbs.db
.DS_Store
# Eclipse project files
#.classpath
#.project
.classpath
.project
.settings
# Local configuration file (sdk path, etc)
local.properties
# Android Studio
.idea/*
!.idea/runConfigurations/
!.idea/codeStyleSettings.xml
.gradle
build/
*.iml
projectFilesBackup/

29
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,29 @@
image: registry.gitlab.com/fdroid/ci-images-base:latest
cache:
paths:
- .gradle/wrapper
- .gradle/caches
before_script:
- set -e
- export GRADLE_USER_HOME=$PWD/.gradle
# Accept the license for the Android build tools
- echo y | /opt/android-sdk/tools/bin/sdkmanager "build-tools;26.0.2"
# Download OpenJDK 6 so we can compile against its standard library
- JDK_FILE=openjdk-6-jre-headless_6b38-1.13.10-1~deb7u1_amd64.deb
- if [ ! -d openjdk ]
- then
- wget -q http://ftp.uk.debian.org/debian/pool/main/o/openjdk-6/$JDK_FILE
- dpkg-deb -x $JDK_FILE openjdk
- fi
- export JAVA_6_HOME=$PWD/openjdk/usr/lib/jvm/java-6-openjdk-amd64
test:
script:
- ./gradlew test
after_script:
# this file changes every time but should not be cached
- rm -f $GRADLE_USER_HOME/caches/modules-2/modules-2.lock
- rm -fr $GRADLE_USER_HOME/caches/*/plugin-resolution/

28
.idea/runConfigurations/All_tests.xml generated Normal file
View File

@@ -0,0 +1,28 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="briar-android" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-android" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method>
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in bramble-api" run_configuration_type="AndroidJUnit" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in bramble-core" run_configuration_type="AndroidJUnit" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in bramble-j2se" run_configuration_type="AndroidJUnit" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All tests in briar-core" run_configuration_type="AndroidJUnit" />
</method>
</configuration>
</component>

View File

@@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-api" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-api" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-api" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
</component>

View File

@@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-core" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-core" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-core" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
</component>

View File

@@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-j2se" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-j2se" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -Djava.library.path=libs" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-j2se" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
</component>

View File

@@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in briar-android" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="briar-android" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-android" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
</component>

View File

@@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in briar-core" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="briar-core" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-core" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
</component>

View File

@@ -1,5 +1,5 @@
bin
gen
build
local.properties
.settings
src/main/res/raw/*.zip

View File

@@ -0,0 +1,95 @@
import de.undercouch.gradle.tasks.download.Download
import de.undercouch.gradle.tasks.download.Verify
apply plugin: 'com.android.library'
apply plugin: 'witness'
apply plugin: 'de.undercouch.download'
android {
compileSdkVersion 27
buildToolsVersion '26.0.2'
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 1620
versionName "0.16.20"
consumerProguardFiles 'proguard-rules.txt'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation project(path: ':bramble-core', configuration: 'default')
implementation fileTree(dir: 'libs', include: '*.jar')
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
compileOnly 'javax.annotation:jsr250-api:1.0'
}
dependencyVerification {
verify = [
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
'com.h2database:h2:1.4.192:h2-1.4.192.jar:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c',
'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128-runtime.jar:e357a0f1d573c2f702a273992b1b6cb661734f66311854efb3778a888515c5b5',
'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128.jar:47b4bec6df11a1118da3953da8b9fa1e7079d6fec857faa1a3cf912e53a6fd4e',
'org.jacoco:org.jacoco.ant:0.7.4.201502262128:org.jacoco.ant-0.7.4.201502262128.jar:013ce2a68ba57a3c59215ae0dec4df3498c078062a38c3b94c841fc14450f283',
'org.jacoco:org.jacoco.core:0.7.4.201502262128:org.jacoco.core-0.7.4.201502262128.jar:ec4c74554312fac5116350164786f91b35c9e082fa4ea598bfa42b5db05d7abb',
'org.jacoco:org.jacoco.report:0.7.4.201502262128:org.jacoco.report-0.7.4.201502262128.jar:7a3554c605e088e7e323b1084656243f0444fa353e2f2dee1f1a4204eb64ff09',
'org.ow2.asm:asm-debug-all:5.0.1:asm-debug-all-5.0.1.jar:4734de5b515a454b0096db6971fb068e5f70e6f10bbee2b3bd2fdfe5d978ed57',
]
}
ext.torBinaryDir = 'src/main/res/raw'
ext.torVersion = '0.2.9.14'
ext.geoipVersion = '2017-11-06'
ext.torDownloadUrl = 'https://briarproject.org/build/'
def torBinaries = [
"tor_arm" : '1710ea6c47b7f4c1a88bdf4858c7893837635db10e8866854eed8d61629f50e8',
"tor_arm_pie": '974e6949507db8fa2ea45231817c2c3677ed4ccf5488a2252317d744b0be1917',
"tor_x86" : '3a5e45b3f051fcda9353b098b7086e762ffe7ba9242f7d7c8bf6523faaa8b1e9',
"tor_x86_pie": 'd1d96d8ce1a4b68accf04850185780d10cd5563d3552f7e1f040f8ca32cb4e51',
"geoip" : '8239b98374493529a29096e45fc5877d4d6fdad0146ad8380b291f90d61484ea'
]
def downloadBinary(name) {
return tasks.create("downloadBinary${name}", Download) {
src "${torDownloadUrl}${name}.zip"
.replace('tor_', "tor-${torVersion}-")
.replace('geoip', "geoip-${geoipVersion}")
.replaceAll('_', '-')
dest "${torBinaryDir}/${name}.zip"
onlyIfNewer true
}
}
def verifyBinary(name, chksum) {
return tasks.create([
name : "verifyBinary${name}",
type : Verify,
dependsOn: downloadBinary(name)]) {
src "${torBinaryDir}/${name}.zip"
algorithm 'SHA-256'
checksum chksum
}
}
project.afterEvaluate {
torBinaries.every { key, value ->
preBuild.dependsOn.add(verifyBinary(key, value))
}
}

Binary file not shown.

View File

@@ -0,0 +1,15 @@
-keep,includedescriptorclasses class org.briarproject.** { *; }
-keep class org.h2.** { *; }
-dontwarn org.h2.**
-dontnote org.h2.**
-keep class dagger.** { *; }
-dontwarn dagger.**
-dontnote dagger.**
-dontwarn sun.misc.Unsafe
-dontnote com.google.common.**
# UPnP library isn't used
-dontwarn org.bitlet.weupnp.**

View File

@@ -0,0 +1,22 @@
<manifest
package="org.briarproject.bramble"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.hardware.bluetooth"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:allowBackup="false"
android:label="@string/app_name"
android:supportsRtl="true">
</application>
</manifest>

View File

@@ -0,0 +1,13 @@
package org.briarproject.bramble;
import org.briarproject.bramble.plugin.AndroidPluginModule;
import org.briarproject.bramble.system.AndroidSystemModule;
import dagger.Module;
@Module(includes = {
AndroidPluginModule.class,
AndroidSystemModule.class
})
public class BrambleAndroidModule {
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.android.api;
package org.briarproject.bramble.api.system;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

View File

@@ -0,0 +1,69 @@
package org.briarproject.bramble.plugin;
import android.app.Application;
import android.content.Context;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.BackoffFactory;
import org.briarproject.bramble.api.plugin.PluginConfig;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
import org.briarproject.bramble.api.reporting.DevReporter;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.Scheduler;
import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory;
import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory;
import org.briarproject.bramble.plugin.tor.TorPluginFactory;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import javax.net.SocketFactory;
import dagger.Module;
import dagger.Provides;
@Module
public class AndroidPluginModule {
@Provides
PluginConfig providePluginConfig(@IoExecutor Executor ioExecutor,
@Scheduler ScheduledExecutorService scheduler,
AndroidExecutor androidExecutor, SecureRandom random,
SocketFactory torSocketFactory, BackoffFactory backoffFactory,
Application app, LocationUtils locationUtils, DevReporter reporter,
EventBus eventBus) {
Context appContext = app.getApplicationContext();
DuplexPluginFactory bluetooth =
new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor,
appContext, random, eventBus, backoffFactory);
DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, scheduler,
appContext, locationUtils, reporter, eventBus,
torSocketFactory, backoffFactory);
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
scheduler, backoffFactory, appContext);
Collection<DuplexPluginFactory> duplex =
Arrays.asList(bluetooth, tor, lan);
@NotNullByDefault
PluginConfig pluginConfig = new PluginConfig() {
@Override
public Collection<DuplexPluginFactory> getDuplexFactories() {
return duplex;
}
@Override
public Collection<SimplexPluginFactory> getSimplexFactories() {
return Collections.emptyList();
}
};
return pluginConfig;
}
}

View File

@@ -0,0 +1,206 @@
package org.briarproject.bramble.plugin.bluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.PluginException;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.util.AndroidUtils;
import java.io.Closeable;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
import static android.bluetooth.BluetoothAdapter.EXTRA_SCAN_MODE;
import static android.bluetooth.BluetoothAdapter.EXTRA_STATE;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
import static android.bluetooth.BluetoothAdapter.STATE_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static java.util.logging.Level.WARNING;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
private static final Logger LOG =
Logger.getLogger(AndroidBluetoothPlugin.class.getName());
private final AndroidExecutor androidExecutor;
private final Context appContext;
private volatile boolean wasEnabledByUs = false;
private volatile BluetoothStateReceiver receiver = null;
// Non-null if the plugin started successfully
private volatile BluetoothAdapter adapter = null;
AndroidBluetoothPlugin(Executor ioExecutor, AndroidExecutor androidExecutor,
Context appContext, SecureRandom secureRandom, Backoff backoff,
DuplexPluginCallback callback, int maxLatency) {
super(ioExecutor, secureRandom, backoff, callback, maxLatency);
this.androidExecutor = androidExecutor;
this.appContext = appContext;
}
@Override
public void start() throws PluginException {
super.start();
// Listen for changes to the Bluetooth state
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_STATE_CHANGED);
filter.addAction(ACTION_SCAN_MODE_CHANGED);
receiver = new BluetoothStateReceiver();
appContext.registerReceiver(receiver, filter);
}
@Override
public void stop() {
super.stop();
if (receiver != null) appContext.unregisterReceiver(receiver);
}
@Override
void initialiseAdapter() throws IOException {
// BluetoothAdapter.getDefaultAdapter() must be called on a thread
// with a message queue, so submit it to the AndroidExecutor
try {
adapter = androidExecutor.runOnBackgroundThread(
BluetoothAdapter::getDefaultAdapter).get();
} catch (InterruptedException | ExecutionException e) {
throw new IOException(e);
}
if (adapter == null)
throw new IOException("Bluetooth is not supported");
}
@Override
boolean isAdapterEnabled() {
return adapter != null && adapter.isEnabled();
}
@Override
void enableAdapter() {
if (adapter != null && !adapter.isEnabled()) {
if (adapter.enable()) {
LOG.info("Enabling Bluetooth");
wasEnabledByUs = true;
} else {
LOG.info("Could not enable Bluetooth");
}
}
}
@Override
void disableAdapterIfEnabledByUs() {
if (isAdapterEnabled() && wasEnabledByUs) {
if (adapter.disable()) LOG.info("Disabling Bluetooth");
else LOG.info("Could not disable Bluetooth");
wasEnabledByUs = false;
}
}
@Override
void setEnabledByUs() {
wasEnabledByUs = true;
}
@Override
@Nullable
String getBluetoothAddress() {
String address = AndroidUtils.getBluetoothAddress(appContext, adapter);
return address.isEmpty() ? null : address;
}
@Override
BluetoothServerSocket openServerSocket(String uuid) throws IOException {
return adapter.listenUsingInsecureRfcommWithServiceRecord(
"RFCOMM", UUID.fromString(uuid));
}
@Override
void tryToClose(@Nullable BluetoothServerSocket ss) {
try {
if (ss != null) ss.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
}
@Override
DuplexTransportConnection acceptConnection(BluetoothServerSocket ss)
throws IOException {
return wrapSocket(ss.accept());
}
private DuplexTransportConnection wrapSocket(BluetoothSocket s) {
return new AndroidBluetoothTransportConnection(this, s);
}
@Override
boolean isValidAddress(String address) {
return BluetoothAdapter.checkBluetoothAddress(address);
}
@Override
DuplexTransportConnection connectTo(String address, String uuid)
throws IOException {
BluetoothDevice d = adapter.getRemoteDevice(address);
UUID u = UUID.fromString(uuid);
BluetoothSocket s = null;
try {
s = d.createInsecureRfcommSocketToServiceRecord(u);
s.connect();
return wrapSocket(s);
} catch (IOException e) {
tryToClose(s);
throw e;
}
}
private void tryToClose(@Nullable Closeable c) {
try {
if (c != null) c.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
}
private class BluetoothStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context ctx, Intent intent) {
int state = intent.getIntExtra(EXTRA_STATE, 0);
if (state == STATE_ON) onAdapterEnabled();
else if (state == STATE_OFF) onAdapterDisabled();
int scanMode = intent.getIntExtra(EXTRA_SCAN_MODE, 0);
if (scanMode == SCAN_MODE_NONE) {
LOG.info("Scan mode: None");
} else if (scanMode == SCAN_MODE_CONNECTABLE) {
LOG.info("Scan mode: Connectable");
} else if (scanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
LOG.info("Scan mode: Discoverable");
}
}
}
}

View File

@@ -0,0 +1,70 @@
package org.briarproject.bramble.plugin.bluetooth;
import android.content.Context;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.BackoffFactory;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.system.AndroidExecutor;
import java.security.SecureRandom;
import java.util.concurrent.Executor;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
@Immutable
@NotNullByDefault
public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
private static final int MIN_POLLING_INTERVAL = 60 * 1000; // 1 minute
private static final int MAX_POLLING_INTERVAL = 10 * 60 * 1000; // 10 mins
private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor;
private final AndroidExecutor androidExecutor;
private final Context appContext;
private final SecureRandom secureRandom;
private final EventBus eventBus;
private final BackoffFactory backoffFactory;
public AndroidBluetoothPluginFactory(Executor ioExecutor,
AndroidExecutor androidExecutor, Context appContext,
SecureRandom secureRandom, EventBus eventBus,
BackoffFactory backoffFactory) {
this.ioExecutor = ioExecutor;
this.androidExecutor = androidExecutor;
this.appContext = appContext;
this.secureRandom = secureRandom;
this.eventBus = eventBus;
this.backoffFactory = backoffFactory;
}
@Override
public TransportId getId() {
return ID;
}
@Override
public int getMaxLatency() {
return MAX_LATENCY;
}
@Override
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin(ioExecutor,
androidExecutor, appContext, secureRandom, backoff, callback,
MAX_LATENCY);
eventBus.addListener(plugin);
return plugin;
}
}

View File

@@ -1,19 +1,22 @@
package org.briarproject.plugins.droidtooth;
package org.briarproject.bramble.plugin.bluetooth;
import android.bluetooth.BluetoothSocket;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.duplex.AbstractDuplexTransportConnection;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Plugin;
import org.briarproject.bramble.api.plugin.duplex.AbstractDuplexTransportConnection;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
class DroidtoothTransportConnection extends AbstractDuplexTransportConnection {
@NotNullByDefault
class AndroidBluetoothTransportConnection
extends AbstractDuplexTransportConnection {
private final BluetoothSocket socket;
DroidtoothTransportConnection(Plugin plugin, BluetoothSocket socket) {
AndroidBluetoothTransportConnection(Plugin plugin, BluetoothSocket socket) {
super(plugin);
this.socket = socket;
}

View File

@@ -0,0 +1,196 @@
package org.briarproject.bramble.plugin.tcp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.net.SocketFactory;
import static android.content.Context.CONNECTIVITY_SERVICE;
import static android.content.Context.WIFI_SERVICE;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.wifi.WifiManager.EXTRA_WIFI_STATE;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.concurrent.TimeUnit.SECONDS;
@NotNullByDefault
class AndroidLanTcpPlugin extends LanTcpPlugin {
// See android.net.wifi.WifiManager
private static final String WIFI_AP_STATE_CHANGED_ACTION =
"android.net.wifi.WIFI_AP_STATE_CHANGED";
private static final int WIFI_AP_STATE_ENABLED = 13;
private static final byte[] WIFI_AP_ADDRESS_BYTES =
{(byte) 192, (byte) 168, 43, 1};
private static final InetAddress WIFI_AP_ADDRESS;
private static final Logger LOG =
Logger.getLogger(AndroidLanTcpPlugin.class.getName());
static {
try {
WIFI_AP_ADDRESS = InetAddress.getByAddress(WIFI_AP_ADDRESS_BYTES);
} catch (UnknownHostException e) {
// Should only be thrown if the address has an illegal length
throw new AssertionError(e);
}
}
private final ScheduledExecutorService scheduler;
private final Context appContext;
private final ConnectivityManager connectivityManager;
@Nullable
private final WifiManager wifiManager;
@Nullable
private volatile BroadcastReceiver networkStateReceiver = null;
private volatile SocketFactory socketFactory;
AndroidLanTcpPlugin(Executor ioExecutor, ScheduledExecutorService scheduler,
Backoff backoff, Context appContext, DuplexPluginCallback callback,
int maxLatency, int maxIdleTime) {
super(ioExecutor, backoff, callback, maxLatency, maxIdleTime);
this.scheduler = scheduler;
this.appContext = appContext;
ConnectivityManager connectivityManager = (ConnectivityManager)
appContext.getSystemService(CONNECTIVITY_SERVICE);
if (connectivityManager == null) throw new AssertionError();
this.connectivityManager = connectivityManager;
wifiManager = (WifiManager) appContext.getApplicationContext()
.getSystemService(WIFI_SERVICE);
socketFactory = SocketFactory.getDefault();
}
@Override
public void start() {
if (used.getAndSet(true)) throw new IllegalStateException();
running = true;
// Register to receive network status events
networkStateReceiver = new NetworkStateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(CONNECTIVITY_ACTION);
filter.addAction(WIFI_AP_STATE_CHANGED_ACTION);
appContext.registerReceiver(networkStateReceiver, filter);
}
@Override
public void stop() {
running = false;
if (networkStateReceiver != null)
appContext.unregisterReceiver(networkStateReceiver);
tryToClose(socket);
}
@Override
protected Socket createSocket() throws IOException {
return socketFactory.createSocket();
}
@Override
protected Collection<InetAddress> getLocalIpAddresses() {
// If the device doesn't have wifi, don't open any sockets
if (wifiManager == null) return emptyList();
// If we're connected to a wifi network, use that network
WifiInfo info = wifiManager.getConnectionInfo();
if (info != null && info.getIpAddress() != 0)
return singletonList(intToInetAddress(info.getIpAddress()));
// If we're running an access point, return its address
if (super.getLocalIpAddresses().contains(WIFI_AP_ADDRESS))
return singletonList(WIFI_AP_ADDRESS);
// No suitable addresses
return emptyList();
}
private InetAddress intToInetAddress(int ip) {
byte[] ipBytes = new byte[4];
ipBytes[0] = (byte) (ip & 0xFF);
ipBytes[1] = (byte) ((ip >> 8) & 0xFF);
ipBytes[2] = (byte) ((ip >> 16) & 0xFF);
ipBytes[3] = (byte) ((ip >> 24) & 0xFF);
try {
return InetAddress.getByAddress(ipBytes);
} catch (UnknownHostException e) {
// Should only be thrown if address has illegal length
throw new AssertionError(e);
}
}
// On API 21 and later, a socket that is not created with the wifi
// network's socket factory may try to connect via another network
private SocketFactory getSocketFactory() {
if (SDK_INT < 21) return SocketFactory.getDefault();
for (Network net : connectivityManager.getAllNetworks()) {
NetworkInfo info = connectivityManager.getNetworkInfo(net);
if (info != null && info.getType() == TYPE_WIFI)
return net.getSocketFactory();
}
LOG.warning("Could not find suitable socket factory");
return SocketFactory.getDefault();
}
private class NetworkStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context ctx, Intent i) {
if (!running) return;
if (isApEnabledEvent(i)) {
// The state change may be broadcast before the AP address is
// visible, so delay handling the event
scheduler.schedule(this::handleConnectivityChange, 1, SECONDS);
} else {
handleConnectivityChange();
}
}
private void handleConnectivityChange() {
if (!running) return;
Collection<InetAddress> addrs = getLocalIpAddresses();
if (addrs.contains(WIFI_AP_ADDRESS)) {
LOG.info("Providing wifi hotspot");
// There's no corresponding Network object and thus no way
// to get a suitable socket factory, so we won't be able to
// make outgoing connections on API 21+ if another network
// has internet access
socketFactory = SocketFactory.getDefault();
if (socket == null || socket.isClosed()) bind();
} else if (addrs.isEmpty()) {
LOG.info("Not connected to wifi");
socketFactory = SocketFactory.getDefault();
tryToClose(socket);
} else {
LOG.info("Connected to wifi");
socketFactory = getSocketFactory();
if (socket == null || socket.isClosed()) bind();
}
}
private boolean isApEnabledEvent(Intent i) {
return WIFI_AP_STATE_CHANGED_ACTION.equals(i.getAction()) &&
i.getIntExtra(EXTRA_WIFI_STATE, 0) == WIFI_AP_STATE_ENABLED;
}
}
}

View File

@@ -1,18 +1,24 @@
package org.briarproject.plugins.tcp;
package org.briarproject.bramble.plugin.tcp;
import android.content.Context;
import org.briarproject.api.TransportId;
import org.briarproject.api.plugins.Backoff;
import org.briarproject.api.plugins.BackoffFactory;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.BackoffFactory;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import static org.briarproject.api.plugins.LanTcpConstants.ID;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
@Immutable
@NotNullByDefault
public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
@@ -22,12 +28,15 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor;
private final ScheduledExecutorService scheduler;
private final BackoffFactory backoffFactory;
private final Context appContext;
public AndroidLanTcpPluginFactory(Executor ioExecutor,
BackoffFactory backoffFactory, Context appContext) {
ScheduledExecutorService scheduler, BackoffFactory backoffFactory,
Context appContext) {
this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.backoffFactory = backoffFactory;
this.appContext = appContext;
}
@@ -46,7 +55,7 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
return new AndroidLanTcpPlugin(ioExecutor, backoff, appContext,
callback, MAX_LATENCY, MAX_IDLE_TIME);
return new AndroidLanTcpPlugin(ioExecutor, scheduler, backoff,
appContext, callback, MAX_LATENCY, MAX_IDLE_TIME);
}
}

View File

@@ -1,18 +1,18 @@
package org.briarproject.plugins.tor;
package org.briarproject.bramble.plugin.tor;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class TorNetworkMetadata {
class TorNetworkMetadata {
// See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
// and https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki
// TODO: get a more complete list
private static final Set<String> BLOCKED_IN_COUNTRIES =
new HashSet<String>(Arrays.asList("CN", "IR", "SY", "ZZ"));
new HashSet<>(Arrays.asList("CN", "IR", "SY", "ZZ"));
public static boolean isTorProbablyBlocked(String countryCode) {
static boolean isTorProbablyBlocked(String countryCode) {
return BLOCKED_IN_COUNTRIES.contains(countryCode);
}
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.plugins.tor;
package org.briarproject.bramble.plugin.tor;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -7,6 +7,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.FileObserver;
@@ -15,27 +16,29 @@ import android.os.PowerManager;
import net.freehaven.tor.control.EventHandler;
import net.freehaven.tor.control.TorControlConnection;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.keyagreement.KeyAgreementListener;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.plugins.Backoff;
import org.briarproject.api.plugins.TorConstants;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.reporting.DevReporter;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.system.LocationUtils;
import org.briarproject.util.IoUtils;
import org.briarproject.util.StringUtils;
import org.briarproject.bramble.PoliteExecutor;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.keyagreement.KeyAgreementListener;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.PluginException;
import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.reporting.DevReporter;
import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.util.AndroidUtils;
import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.util.StringUtils;
import java.io.Closeable;
import java.io.EOFException;
@@ -53,10 +56,14 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.zip.ZipInputStream;
@@ -67,21 +74,33 @@ import javax.net.SocketFactory;
import static android.content.Context.CONNECTIVITY_SERVICE;
import static android.content.Context.MODE_PRIVATE;
import static android.content.Context.POWER_SERVICE;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static android.content.Intent.ACTION_SCREEN_ON;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
import static org.briarproject.api.plugins.TorConstants.CONTROL_PORT;
import static org.briarproject.util.PrivacyUtils.scrubOnion;
import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.ID;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ALWAYS;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WIFI;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION;
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
@NotNullByDefault
@MethodsNotNullByDefault
@ParametersNotNullByDefault
class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private static final String PROP_ONION = "onion";
private static final String[] EVENTS = {
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
};
@@ -91,7 +110,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private static final Logger LOG =
Logger.getLogger(TorPlugin.class.getName());
private final Executor ioExecutor;
private final Executor ioExecutor, connectionStatusExecutor;
private final ScheduledExecutorService scheduler;
private final Context appContext;
private final LocationUtils locationUtils;
private final DevReporter reporter;
@@ -104,24 +124,23 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final File torDirectory, torFile, geoIpFile, configFile;
private final File doneFile, cookieFile;
private final PowerManager.WakeLock wakeLock;
private final AtomicReference<Future<?>> connectivityCheck =
new AtomicReference<>();
private final AtomicBoolean used = new AtomicBoolean(false);
private volatile boolean running = false;
@Nullable
private volatile ServerSocket socket = null;
@Nullable
private volatile Socket controlSocket = null;
@Nullable
private volatile TorControlConnection controlConnection = null;
@Nullable
private volatile BroadcastReceiver networkStateReceiver = null;
TorPlugin(Executor ioExecutor, Context appContext,
LocationUtils locationUtils, DevReporter reporter,
SocketFactory torSocketFactory, Backoff backoff,
DuplexPluginCallback callback, String architecture, int maxLatency,
int maxIdleTime) {
TorPlugin(Executor ioExecutor, ScheduledExecutorService scheduler,
Context appContext, LocationUtils locationUtils,
DevReporter reporter, SocketFactory torSocketFactory,
Backoff backoff, DuplexPluginCallback callback,
String architecture, int maxLatency, int maxIdleTime) {
this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.appContext = appContext;
this.locationUtils = locationUtils;
this.reporter = reporter;
@@ -143,8 +162,12 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
Object o = appContext.getSystemService(POWER_SERVICE);
PowerManager pm = (PowerManager) o;
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "TorPlugin");
// This tag will prevent Huawei's powermanager from killing us.
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "LocationManagerService");
wakeLock.setReferenceCounted(false);
// Don't execute more than one connection status check at a time
connectionStatusExecutor = new PoliteExecutor("TorPlugin",
ioExecutor, 1);
}
@Override
@@ -163,14 +186,18 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
@Override
public boolean start() throws IOException {
public void start() throws PluginException {
if (used.getAndSet(true)) throw new IllegalStateException();
// Install or update the assets if necessary
if (!assetsAreUpToDate()) installAssets();
LOG.info("Starting Tor");
// Watch for the auth cookie file being updated
cookieFile.getParentFile().mkdirs();
cookieFile.createNewFile();
try {
cookieFile.getParentFile().mkdirs();
cookieFile.createNewFile();
} catch (IOException e) {
throw new PluginException(e);
}
CountDownLatch latch = new CountDownLatch(1);
FileObserver obs = new WriteObserver(cookieFile, latch);
obs.startWatching();
@@ -178,19 +205,31 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
String torPath = torFile.getAbsolutePath();
String configPath = configFile.getAbsolutePath();
String pid = String.valueOf(android.os.Process.myPid());
String[] cmd = {torPath, "-f", configPath, OWNER, pid};
String[] env = {"HOME=" + torDirectory.getAbsolutePath()};
Process torProcess;
ProcessBuilder pb =
new ProcessBuilder(torPath, "-f", configPath, OWNER, pid);
Map<String, String> env = pb.environment();
env.put("HOME", torDirectory.getAbsolutePath());
pb.directory(torDirectory);
try {
torProcess = Runtime.getRuntime().exec(cmd, env, torDirectory);
} catch (SecurityException e) {
throw new IOException(e);
torProcess = pb.start();
} catch (SecurityException | IOException e) {
throw new PluginException(e);
}
// Log the process's standard output until it detaches
if (LOG.isLoggable(INFO)) {
Scanner stdout = new Scanner(torProcess.getInputStream());
while (stdout.hasNextLine()) LOG.info(stdout.nextLine());
Scanner stderr = new Scanner(torProcess.getErrorStream());
while (stdout.hasNextLine() || stderr.hasNextLine()) {
if (stdout.hasNextLine()) {
LOG.info(stdout.nextLine());
}
if (stderr.hasNextLine()) {
LOG.info(stderr.nextLine());
}
}
stdout.close();
stderr.close();
}
try {
// Wait for the process to detach or exit
@@ -198,43 +237,50 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (exit != 0) {
if (LOG.isLoggable(WARNING))
LOG.warning("Tor exited with value " + exit);
return false;
throw new PluginException();
}
// Wait for the auth cookie file to be created/updated
if (!latch.await(COOKIE_TIMEOUT, MILLISECONDS)) {
LOG.warning("Auth cookie not created");
if (LOG.isLoggable(INFO)) listFiles(torDirectory);
return false;
throw new PluginException();
}
} catch (InterruptedException e) {
LOG.warning("Interrupted while starting Tor");
Thread.currentThread().interrupt();
return false;
throw new PluginException();
}
// Open a control connection and authenticate using the cookie file
controlSocket = new Socket("127.0.0.1", CONTROL_PORT);
controlConnection = new TorControlConnection(controlSocket);
controlConnection.authenticate(read(cookieFile));
// Tell Tor to exit when the control connection is closed
controlConnection.takeOwnership();
controlConnection.resetConf(Collections.singletonList(OWNER));
running = true;
// Register to receive events from the Tor process
controlConnection.setEventHandler(this);
controlConnection.setEvents(Arrays.asList(EVENTS));
// Check whether Tor has already bootstrapped
String phase = controlConnection.getInfo("status/bootstrap-phase");
if (phase != null && phase.contains("PROGRESS=100")) {
LOG.info("Tor has already bootstrapped");
connectionStatus.setBootstrapped();
try {
// Open a control connection and authenticate using the cookie file
controlSocket = new Socket("127.0.0.1", CONTROL_PORT);
controlConnection = new TorControlConnection(controlSocket);
controlConnection.authenticate(read(cookieFile));
// Tell Tor to exit when the control connection is closed
controlConnection.takeOwnership();
controlConnection.resetConf(Collections.singletonList(OWNER));
running = true;
// Register to receive events from the Tor process
controlConnection.setEventHandler(this);
controlConnection.setEvents(Arrays.asList(EVENTS));
// Check whether Tor has already bootstrapped
String phase = controlConnection.getInfo("status/bootstrap-phase");
if (phase != null && phase.contains("PROGRESS=100")) {
LOG.info("Tor has already bootstrapped");
connectionStatus.setBootstrapped();
}
} catch (IOException e) {
throw new PluginException(e);
}
// Register to receive network status events
networkStateReceiver = new NetworkStateReceiver();
IntentFilter filter = new IntentFilter(CONNECTIVITY_ACTION);
IntentFilter filter = new IntentFilter();
filter.addAction(CONNECTIVITY_ACTION);
filter.addAction(ACTION_SCREEN_ON);
filter.addAction(ACTION_SCREEN_OFF);
if (SDK_INT >= 23) filter.addAction(ACTION_DEVICE_IDLE_MODE_CHANGED);
appContext.registerReceiver(networkStateReceiver, filter);
// Bind a server socket to receive incoming hidden service connections
bind();
return true;
}
private boolean assetsAreUpToDate() {
@@ -247,7 +293,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
}
private void installAssets() throws IOException {
private void installAssets() throws PluginException {
InputStream in = null;
OutputStream out = null;
try {
@@ -270,30 +316,36 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
} catch (IOException e) {
tryToClose(in);
tryToClose(out);
throw e;
throw new PluginException(e);
}
}
private InputStream getTorInputStream() throws IOException {
if (LOG.isLoggable(INFO))
LOG.info("Installing Tor binary for " + architecture);
String filename = "tor-" + architecture + ".zip";
InputStream in = appContext.getResources().getAssets().open(filename);
int resId = getResourceId("tor_" + architecture);
InputStream in = appContext.getResources().openRawResource(resId);
ZipInputStream zin = new ZipInputStream(in);
if (zin.getNextEntry() == null) throw new IOException();
return zin;
}
private InputStream getGeoIpInputStream() throws IOException {
String filename = "geoip.zip";
InputStream in = appContext.getResources().getAssets().open(filename);
int resId = getResourceId("geoip");
InputStream in = appContext.getResources().openRawResource(resId);
ZipInputStream zin = new ZipInputStream(in);
if (zin.getNextEntry() == null) throw new IOException();
return zin;
}
private InputStream getConfigInputStream() throws IOException {
return appContext.getResources().getAssets().open("torrc");
int resId = getResourceId("torrc");
return appContext.getResources().openRawResource(resId);
}
private int getResourceId(String filename) {
Resources res = appContext.getResources();
return res.getIdentifier(filename, "raw", appContext.getPackageName());
}
private void tryToClose(@Nullable Closeable c) {
@@ -338,57 +390,45 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
private void sendDevReports() {
ioExecutor.execute(new Runnable() {
@Override
public void run() {
// TODO: Trigger this with a TransportEnabledEvent
File reportDir = AndroidUtils.getReportDir(appContext);
reporter.sendReports(reportDir);
}
ioExecutor.execute(() -> {
// TODO: Trigger this with a TransportEnabledEvent
File reportDir = AndroidUtils.getReportDir(appContext);
reporter.sendReports(reportDir);
});
}
private void bind() {
ioExecutor.execute(new Runnable() {
@Override
public void run() {
// If there's already a port number stored in config, reuse it
String portString = callback.getSettings().get("port");
int port;
if (StringUtils.isNullOrEmpty(portString)) port = 0;
else port = Integer.parseInt(portString);
// Bind a server socket to receive connections from Tor
ServerSocket ss = null;
try {
ss = new ServerSocket();
ss.bind(new InetSocketAddress("127.0.0.1", port));
} catch (IOException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
tryToClose(ss);
return;
}
if (!running) {
tryToClose(ss);
return;
}
socket = ss;
// Store the port number
final String localPort = String.valueOf(ss.getLocalPort());
Settings s = new Settings();
s.put("port", localPort);
callback.mergeSettings(s);
// Create a hidden service if necessary
ioExecutor.execute(new Runnable() {
@Override
public void run() {
publishHiddenService(localPort);
}
});
backoff.reset();
// Accept incoming hidden service connections from Tor
acceptContactConnections(ss);
ioExecutor.execute(() -> {
// If there's already a port number stored in config, reuse it
String portString = callback.getSettings().get(PREF_TOR_PORT);
int port;
if (StringUtils.isNullOrEmpty(portString)) port = 0;
else port = Integer.parseInt(portString);
// Bind a server socket to receive connections from Tor
ServerSocket ss = null;
try {
ss = new ServerSocket();
ss.bind(new InetSocketAddress("127.0.0.1", port));
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
tryToClose(ss);
return;
}
if (!running) {
tryToClose(ss);
return;
}
socket = ss;
// Store the port number
String localPort = String.valueOf(ss.getLocalPort());
Settings s = new Settings();
s.put(PREF_TOR_PORT, localPort);
callback.mergeSettings(s);
// Create a hidden service if necessary
ioExecutor.execute(() -> publishHiddenService(localPort));
backoff.reset();
// Accept incoming hidden service connections from Tor
acceptContactConnections(ss);
});
}
@@ -471,7 +511,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
@Override
public void stop() throws IOException {
public void stop() throws PluginException {
running = false;
tryToClose(socket);
if (networkStateReceiver != null)
@@ -508,20 +548,21 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
public void poll(Collection<ContactId> connected) {
if (!isRunning()) return;
backoff.increment();
// TODO: Pass properties to connectAndCallBack()
for (ContactId c : callback.getRemoteProperties().keySet())
if (!connected.contains(c)) connectAndCallBack(c);
Map<ContactId, TransportProperties> remote =
callback.getRemoteProperties();
for (Entry<ContactId, TransportProperties> e : remote.entrySet()) {
ContactId c = e.getKey();
if (!connected.contains(c)) connectAndCallBack(c, e.getValue());
}
}
private void connectAndCallBack(final ContactId c) {
ioExecutor.execute(new Runnable() {
@Override
public void run() {
DuplexTransportConnection d = createConnection(c);
if (d != null) {
backoff.reset();
callback.outgoingConnectionCreated(c, d);
}
private void connectAndCallBack(ContactId c, TransportProperties p) {
ioExecutor.execute(() -> {
if (!isRunning()) return;
DuplexTransportConnection d = createConnection(p);
if (d != null) {
backoff.reset();
callback.outgoingConnectionCreated(c, d);
}
});
}
@@ -529,8 +570,11 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override
public DuplexTransportConnection createConnection(ContactId c) {
if (!isRunning()) return null;
TransportProperties p = callback.getRemoteProperties().get(c);
if (p == null) return null;
return createConnection(callback.getRemoteProperties(c));
}
@Nullable
private DuplexTransportConnection createConnection(TransportProperties p) {
String onion = p.get(PROP_ONION);
if (StringUtils.isNullOrEmpty(onion)) return null;
if (!ONION.matcher(onion).matches()) {
@@ -558,17 +602,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
}
@Override
public boolean supportsInvitations() {
return false;
}
@Override
public DuplexTransportConnection createInvitationConnection(PseudoRandom r,
long timeout, boolean alice) {
throw new UnsupportedOperationException();
}
@Override
public boolean supportsKeyAgreement() {
return false;
@@ -581,7 +614,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override
public DuplexTransportConnection createKeyAgreementConnection(
byte[] commitment, BdfList descriptor, long timeout) {
byte[] commitment, BdfList descriptor) {
throw new UnsupportedOperationException();
}
@@ -605,6 +638,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override
public void orConnStatus(String status, String orName) {
if (LOG.isLoggable(INFO)) LOG.info("OR connection " + status);
if (status.equals("CLOSED") || status.equals("FAILED"))
updateConnectionStatus(); // Check whether we've lost connectivity
}
@Override
@@ -644,7 +679,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
@Override
public void onEvent(int event, String path) {
public void onEvent(int event, @Nullable String path) {
stopWatching();
latch.countDown();
}
@@ -653,7 +688,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override
public void eventOccurred(Event e) {
if (e instanceof SettingsUpdatedEvent) {
if (((SettingsUpdatedEvent) e).getNamespace().equals("tor")) {
SettingsUpdatedEvent s = (SettingsUpdatedEvent) e;
if (s.getNamespace().equals(ID.getString())) {
LOG.info("Tor settings updated");
updateConnectionStatus();
}
@@ -661,58 +697,65 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
private void updateConnectionStatus() {
ioExecutor.execute(new Runnable() {
@Override
public void run() {
if (!running) return;
connectionStatusExecutor.execute(() -> {
if (!running) return;
Object o = appContext.getSystemService(CONNECTIVITY_SERVICE);
ConnectivityManager cm = (ConnectivityManager) o;
NetworkInfo net = cm.getActiveNetworkInfo();
boolean online = net != null && net.isConnected();
boolean wifi = online && net.getType() == TYPE_WIFI;
String country = locationUtils.getCurrentCountry();
boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
country);
Settings s = callback.getSettings();
int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS);
Object o = appContext.getSystemService(CONNECTIVITY_SERVICE);
ConnectivityManager cm = (ConnectivityManager) o;
NetworkInfo net = cm.getActiveNetworkInfo();
boolean online = net != null && net.isConnected();
boolean wifi = online && net.getType() == TYPE_WIFI;
String country = locationUtils.getCurrentCountry();
boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
country);
Settings s = callback.getSettings();
boolean useMobileData = s.getBoolean("torOverMobile", true);
if (LOG.isLoggable(INFO)) {
LOG.info("Online: " + online + ", wifi: " + wifi);
if ("".equals(country)) LOG.info("Country code unknown");
else LOG.info("Country code: " + country);
}
if (LOG.isLoggable(INFO)) {
LOG.info("Online: " + online + ", wifi: " + wifi);
if ("".equals(country)) LOG.info("Country code unknown");
else LOG.info("Country code: " + country);
}
try {
if (!online) {
LOG.info("Disabling network, device is offline");
enableNetwork(false);
} else if (blocked) {
LOG.info("Disabling network, country is blocked");
enableNetwork(false);
} else if (!wifi && !useMobileData) {
LOG.info("Disabling network due to data setting");
enableNetwork(false);
} else {
LOG.info("Enabling network");
enableNetwork(true);
}
} catch (IOException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
try {
if (!online) {
LOG.info("Disabling network, device is offline");
enableNetwork(false);
} else if (blocked) {
LOG.info("Disabling network, country is blocked");
enableNetwork(false);
} else if (network == PREF_TOR_NETWORK_NEVER
|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) {
LOG.info("Disabling network due to data setting");
enableNetwork(false);
} else {
LOG.info("Enabling network");
enableNetwork(true);
}
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
});
}
private void scheduleConnectionStatusUpdate() {
Future<?> newConnectivityCheck =
scheduler.schedule(this::updateConnectionStatus, 1, MINUTES);
Future<?> oldConnectivityCheck =
connectivityCheck.getAndSet(newConnectivityCheck);
if (oldConnectivityCheck != null) oldConnectivityCheck.cancel(false);
}
private class NetworkStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context ctx, Intent i) {
if (!running) return;
if (CONNECTIVITY_ACTION.equals(i.getAction())) {
LOG.info("Detected connectivity change");
updateConnectionStatus();
String action = i.getAction();
if (LOG.isLoggable(INFO)) LOG.info("Received broadcast " + action);
updateConnectionStatus();
if (ACTION_SCREEN_ON.equals(action)
|| ACTION_SCREEN_OFF.equals(action)) {
scheduleConnectionStatusUpdate();
}
}
}

View File

@@ -1,25 +1,30 @@
package org.briarproject.plugins.tor;
package org.briarproject.bramble.plugin.tor;
import android.content.Context;
import android.os.Build;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.api.TransportId;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.plugins.Backoff;
import org.briarproject.api.plugins.BackoffFactory;
import org.briarproject.api.plugins.TorConstants;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
import org.briarproject.api.reporting.DevReporter;
import org.briarproject.api.system.LocationUtils;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.BackoffFactory;
import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.reporting.DevReporter;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.util.AndroidUtils;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import javax.net.SocketFactory;
@Immutable
@NotNullByDefault
public class TorPluginFactory implements DuplexPluginFactory {
private static final Logger LOG =
@@ -32,6 +37,7 @@ public class TorPluginFactory implements DuplexPluginFactory {
private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor;
private final ScheduledExecutorService scheduler;
private final Context appContext;
private final LocationUtils locationUtils;
private final DevReporter reporter;
@@ -39,11 +45,13 @@ public class TorPluginFactory implements DuplexPluginFactory {
private final SocketFactory torSocketFactory;
private final BackoffFactory backoffFactory;
public TorPluginFactory(Executor ioExecutor, Context appContext,
public TorPluginFactory(Executor ioExecutor,
ScheduledExecutorService scheduler, Context appContext,
LocationUtils locationUtils, DevReporter reporter,
EventBus eventBus, SocketFactory torSocketFactory,
BackoffFactory backoffFactory) {
this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.appContext = appContext;
this.locationUtils = locationUtils;
this.reporter = reporter;
@@ -81,13 +89,13 @@ public class TorPluginFactory implements DuplexPluginFactory {
return null;
}
// Use position-independent executable for SDK >= 16
if (Build.VERSION.SDK_INT >= 16) architecture += "-pie";
if (Build.VERSION.SDK_INT >= 16) architecture += "_pie";
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
TorPlugin plugin = new TorPlugin(ioExecutor, appContext, locationUtils,
reporter, torSocketFactory, backoff, callback, architecture,
MAX_LATENCY, MAX_IDLE_TIME);
TorPlugin plugin = new TorPlugin(ioExecutor, scheduler, appContext,
locationUtils, reporter, torSocketFactory, backoff, callback,
architecture, MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin);
return plugin;
}

View File

@@ -1,13 +1,16 @@
package org.briarproject.plugins.tor;
package org.briarproject.bramble.plugin.tor;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.duplex.AbstractDuplexTransportConnection;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Plugin;
import org.briarproject.bramble.api.plugin.duplex.AbstractDuplexTransportConnection;
import org.briarproject.bramble.util.IoUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
@NotNullByDefault
class TorTransportConnection extends AbstractDuplexTransportConnection {
private final Socket socket;
@@ -19,12 +22,12 @@ class TorTransportConnection extends AbstractDuplexTransportConnection {
@Override
protected InputStream getInputStream() throws IOException {
return socket.getInputStream();
return IoUtils.getInputStream(socket);
}
@Override
protected OutputStream getOutputStream() throws IOException {
return socket.getOutputStream();
return IoUtils.getOutputStream(socket);
}
@Override

View File

@@ -1,10 +1,10 @@
package org.briarproject.system;
package org.briarproject.bramble.system;
import android.app.Application;
import android.os.Handler;
import android.os.Looper;
import org.briarproject.android.api.AndroidExecutor;
import org.briarproject.bramble.api.system.AndroidExecutor;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
@@ -27,14 +27,11 @@ class AndroidExecutorImpl implements AndroidExecutor {
@Inject
AndroidExecutorImpl(Application app) {
uiHandler = new Handler(app.getApplicationContext().getMainLooper());
loop = new Runnable() {
@Override
public void run() {
Looper.prepare();
backgroundHandler = new Handler();
startLatch.countDown();
Looper.loop();
}
loop = () -> {
Looper.prepare();
backgroundHandler = new Handler();
startLatch.countDown();
Looper.loop();
};
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.system;
package org.briarproject.bramble.system;
import android.annotation.SuppressLint;
import android.app.Application;
@@ -6,7 +6,8 @@ import android.content.Context;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import org.briarproject.api.system.LocationUtils;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.LocationUtils;
import java.util.Locale;
import java.util.logging.Logger;
@@ -15,6 +16,7 @@ import javax.inject.Inject;
import static android.content.Context.TELEPHONY_SERVICE;
@NotNullByDefault
class AndroidLocationUtils implements LocationUtils {
private static final Logger LOG =
@@ -23,7 +25,7 @@ class AndroidLocationUtils implements LocationUtils {
private final Context appContext;
@Inject
public AndroidLocationUtils(Application app) {
AndroidLocationUtils(Application app) {
appContext = app.getApplicationContext();
}
@@ -44,6 +46,7 @@ class AndroidLocationUtils implements LocationUtils {
* some reason - both that class and {@code Context.COUNTRY_CODE} are
* annotated {@code @hide}.
*/
@Override
@SuppressLint("DefaultLocale")
public String getCurrentCountry() {
String countryCode = getCountryFromPhoneNetwork();

View File

@@ -0,0 +1,93 @@
package org.briarproject.bramble.system;
import android.app.Application;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ContentResolver;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Parcel;
import android.provider.Settings;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static android.content.Context.WIFI_SERVICE;
import static android.provider.Settings.Secure.ANDROID_ID;
@Immutable
@NotNullByDefault
class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
private static final int SEED_LENGTH = 32;
private final Context appContext;
@Inject
AndroidSecureRandomProvider(Application app) {
appContext = app.getApplicationContext();
}
@Override
protected void writeToEntropyPool(DataOutputStream out) throws IOException {
super.writeToEntropyPool(out);
out.writeInt(android.os.Process.myPid());
out.writeInt(android.os.Process.myTid());
out.writeInt(android.os.Process.myUid());
if (Build.FINGERPRINT != null) out.writeUTF(Build.FINGERPRINT);
if (Build.SERIAL != null) out.writeUTF(Build.SERIAL);
ContentResolver contentResolver = appContext.getContentResolver();
String id = Settings.Secure.getString(contentResolver, ANDROID_ID);
if (id != null) out.writeUTF(id);
Parcel parcel = Parcel.obtain();
WifiManager wm =
(WifiManager) appContext.getSystemService(WIFI_SERVICE);
List<WifiConfiguration> configs = wm.getConfiguredNetworks();
if (configs != null) {
for (WifiConfiguration config : configs)
parcel.writeParcelable(config, 0);
}
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
if (bt != null) {
for (BluetoothDevice device : bt.getBondedDevices())
parcel.writeParcelable(device, 0);
}
out.write(parcel.marshall());
parcel.recycle();
}
@Override
protected void writeSeed() {
super.writeSeed();
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT <= 18)
applyOpenSslFix();
}
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
private void applyOpenSslFix() {
byte[] seed = new LinuxSecureRandomSpi().engineGenerateSeed(
SEED_LENGTH);
try {
// Seed the OpenSSL PRNG
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
.getMethod("RAND_seed", byte[].class)
.invoke(null, seed);
// Mix the output of the Linux PRNG into the OpenSSL PRNG
int bytesRead = (Integer) Class.forName(
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
.getMethod("RAND_load_file", String.class, long.class)
.invoke(null, "/dev/urandom", 1024);
if (bytesRead != 1024) throw new IOException();
} catch (Exception e) {
throw new SecurityException(e);
}
}
}

View File

@@ -0,0 +1,33 @@
package org.briarproject.bramble.system;
import android.app.Application;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.SecureRandomProvider;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class AndroidSystemModule {
@Provides
@Singleton
SecureRandomProvider provideSecureRandomProvider(Application app) {
return new AndroidSecureRandomProvider(app);
}
@Provides
LocationUtils provideLocationUtils(Application app) {
return new AndroidLocationUtils(app);
}
@Provides
@Singleton
AndroidExecutor provideAndroidExecutor(Application app) {
return new AndroidExecutorImpl(app);
}
}

View File

@@ -0,0 +1,70 @@
package org.briarproject.bramble.util;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static android.content.Context.MODE_PRIVATE;
public class AndroidUtils {
// Fake Bluetooth address returned by BluetoothAdapter on API 23 and later
private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00";
private static final String STORED_REPORTS = "dev-reports";
@SuppressWarnings("deprecation")
public static Collection<String> getSupportedArchitectures() {
List<String> abis = new ArrayList<>();
if (Build.VERSION.SDK_INT >= 21) {
abis.addAll(Arrays.asList(Build.SUPPORTED_ABIS));
} else {
abis.add(Build.CPU_ABI);
if (Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2);
}
return abis;
}
public static String getBluetoothAddress(Context ctx,
BluetoothAdapter adapter) {
// Return the adapter's address if it's valid and not fake
String address = adapter.getAddress();
if (isValidBluetoothAddress(address)) return address;
// Return the address from settings if it's valid and not fake
address = Settings.Secure.getString(ctx.getContentResolver(),
"bluetooth_address");
if (isValidBluetoothAddress(address)) return address;
// Let the caller know we can't find the address
return "";
}
private static boolean isValidBluetoothAddress(String address) {
return !StringUtils.isNullOrEmpty(address)
&& BluetoothAdapter.checkBluetoothAddress(address)
&& !address.equals(FAKE_BLUETOOTH_ADDRESS);
}
public static void deleteAppData(Context ctx) {
File dataDir = new File(ctx.getApplicationInfo().dataDir);
File[] children = dataDir.listFiles();
if (children != null) {
for (File child : children) {
if (!child.getName().equals("lib"))
IoUtils.deleteFileOrDir(child);
}
}
// Recreate the cache dir as some OpenGL drivers expect it to exist
new File(dataDir, "cache").mkdir();
}
public static File getReportDir(Context ctx) {
return ctx.getDir(STORED_REPORTS, MODE_PRIVATE);
}
}

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">Bramble</string>
</resources>

55
bramble-api/build.gradle Normal file
View File

@@ -0,0 +1,55 @@
apply plugin: 'java-library'
sourceCompatibility = 1.8
targetCompatibility = 1.8
apply plugin: 'witness'
dependencies {
implementation "com.google.dagger:dagger:2.0.2"
implementation 'com.google.code.findbugs:jsr305:3.0.2'
testImplementation 'junit:junit:4.12'
testImplementation "org.jmock:jmock:2.8.2"
testImplementation "org.jmock:jmock-junit4:2.8.2"
testImplementation "org.jmock:jmock-legacy:2.8.2"
testImplementation "org.hamcrest:hamcrest-library:1.3"
testImplementation "org.hamcrest:hamcrest-core:1.3"
}
dependencyVerification {
verify = [
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
'org.jmock:jmock-junit4:2.8.2:jmock-junit4-2.8.2.jar:f7ee4df4f7bd7b7f1cafad3b99eb74d579f109d5992ff625347352edb55e674c',
'org.jmock:jmock-legacy:2.8.2:jmock-legacy-2.8.2.jar:f2b985a5c08a9edb7f37612330c058809da3f6a6d63ce792426ebf8ff0d6d31b',
'org.jmock:jmock-testjar:2.8.2:jmock-testjar-2.8.2.jar:8900860f72c474e027cf97fe78dcbf154a1aa7fc62b6845c5fb4e4f3c7bc8760',
'org.jmock:jmock:2.8.2:jmock-2.8.2.jar:6c73cb4a2e6dbfb61fd99c9a768539c170ab6568e57846bd60dbf19596b65b16',
'org.objenesis:objenesis:2.1:objenesis-2.1.jar:c74330cc6b806c804fd37e74487b4fe5d7c2750c5e15fbc6efa13bdee1bdef80',
'org.ow2.asm:asm:5.0.4:asm-5.0.4.jar:896618ed8ae62702521a78bc7be42b7c491a08e6920a15f89a3ecdec31e9a220',
]
}
// needed to make test output available to bramble-core and briar-core
configurations {
testOutput.extendsFrom(testCompile)
}
task jarTest(type: Jar, dependsOn: testClasses) {
from sourceSets.test.output
classifier = 'test'
}
artifacts {
testOutput jarTest
}
// If a Java 6 JRE is available, check we're not using any Java 7 or 8 APIs
tasks.withType(JavaCompile) {
useJava6StandardLibrary(it)
}

View File

@@ -1,11 +1,18 @@
package org.briarproject.api;
package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import java.util.Arrays;
import java.util.Comparator;
import javax.annotation.concurrent.ThreadSafe;
/**
* A wrapper around a byte array, to allow it to be stored in maps etc.
*/
@ThreadSafe
@NotNullByDefault
public class Bytes implements Comparable<Bytes> {
public static final BytesComparator COMPARATOR = new BytesComparator();
@@ -47,6 +54,12 @@ public class Bytes implements Comparable<Bytes> {
return aBytes.length - bBytes.length;
}
@Override
public String toString() {
return getClass().getSimpleName() +
"(" + StringUtils.toHexString(getBytes()) + ")";
}
public static class BytesComparator implements Comparator<Bytes> {
@Override

View File

@@ -0,0 +1,9 @@
package org.briarproject.bramble.api;
import java.io.IOException;
/**
* An exception that indicates an unrecoverable formatting error.
*/
public class FormatException extends IOException {
}

View File

@@ -1,12 +1,10 @@
package org.briarproject.api;
package org.briarproject.bramble.api;
import java.util.Hashtable;
import java.util.Map;
public abstract class StringMap extends Hashtable<String, String> {
private static final long serialVersionUID = 2497176435908100448L;
protected StringMap(Map<String, String> m) {
super(m);
}

View File

@@ -0,0 +1,20 @@
package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe
@NotNullByDefault
public abstract class UniqueId extends Bytes {
/**
* The length of a unique identifier in bytes.
*/
public static final int LENGTH = 32;
protected UniqueId(byte[] id) {
super(id);
if (id.length != LENGTH) throw new IllegalArgumentException();
}
}

View File

@@ -1,8 +1,8 @@
package org.briarproject.api.clients;
package org.briarproject.bramble.api.client;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.MessageId;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId;
import java.util.Collection;
import java.util.Collections;
@@ -23,7 +23,7 @@ public class BdfMessageContext {
}
public BdfMessageContext(BdfDictionary dictionary) {
this(dictionary, Collections.<MessageId>emptyList());
this(dictionary, Collections.emptyList());
}
public BdfDictionary getDictionary() {

View File

@@ -0,0 +1,66 @@
package org.briarproject.bramble.api.client;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.InvalidMessageException;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageContext;
import org.briarproject.bramble.api.sync.ValidationManager.MessageValidator;
import org.briarproject.bramble.api.system.Clock;
import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
@Immutable
@NotNullByDefault
public abstract class BdfMessageValidator implements MessageValidator {
protected static final Logger LOG =
Logger.getLogger(BdfMessageValidator.class.getName());
protected final ClientHelper clientHelper;
protected final MetadataEncoder metadataEncoder;
protected final Clock clock;
protected BdfMessageValidator(ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock) {
this.clientHelper = clientHelper;
this.metadataEncoder = metadataEncoder;
this.clock = clock;
}
protected abstract BdfMessageContext validateMessage(Message m, Group g,
BdfList body) throws InvalidMessageException, FormatException;
@Override
public MessageContext validateMessage(Message m, Group g)
throws InvalidMessageException {
// Reject the message if it's too far in the future
long now = clock.currentTimeMillis();
if (m.getTimestamp() - now > MAX_CLOCK_DIFFERENCE) {
throw new InvalidMessageException(
"Timestamp is too far in the future");
}
byte[] raw = m.getRaw();
if (raw.length <= MESSAGE_HEADER_LENGTH) {
throw new InvalidMessageException("Message is too short");
}
try {
BdfList body = clientHelper.toList(raw, MESSAGE_HEADER_LENGTH,
raw.length - MESSAGE_HEADER_LENGTH);
BdfMessageContext result = validateMessage(m, g, body);
Metadata meta = metadataEncoder.encode(result.getDictionary());
return new MessageContext(meta, result.getDependencies());
} catch (FormatException e) {
throw new InvalidMessageException(e);
}
}
}

View File

@@ -1,14 +1,14 @@
package org.briarproject.api.clients;
package org.briarproject.bramble.api.client;
import org.briarproject.api.FormatException;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import java.security.GeneralSecurityException;
import java.util.Map;
@@ -48,7 +48,8 @@ public interface ClientHelper {
BdfDictionary getGroupMetadataAsDictionary(Transaction txn, GroupId g)
throws DbException, FormatException;
BdfDictionary getMessageMetadataAsDictionary(MessageId m) throws DbException,
BdfDictionary getMessageMetadataAsDictionary(MessageId m)
throws DbException,
FormatException;
BdfDictionary getMessageMetadataAsDictionary(Transaction txn, MessageId m)

View File

@@ -0,0 +1,29 @@
package org.briarproject.bramble.api.client;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.Group;
@NotNullByDefault
public interface ContactGroupFactory {
/**
* Creates a group that is not shared with any contacts.
*/
Group createLocalGroup(ClientId clientId);
/**
* Creates a group for the given client to share with the given contact.
*/
Group createContactGroup(ClientId clientId, Contact contact);
/**
* Creates a group for the given client to share between the given authors
* identified by their AuthorIds.
*/
Group createContactGroup(ClientId clientId, AuthorId authorId1,
AuthorId authorId2);
}

View File

@@ -1,8 +1,13 @@
package org.briarproject.api.contact;
package org.briarproject.bramble.api.contact;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class Contact {
private final ContactId id;

View File

@@ -0,0 +1,20 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface ContactExchangeListener {
void contactExchangeSucceeded(Author remoteAuthor);
/**
* The exchange failed because the contact already exists.
*/
void duplicateContact(Author remoteAuthor);
/**
* A general failure.
*/
void contactExchangeFailed();
}

View File

@@ -0,0 +1,22 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
/**
* A task for conducting a contact information exchange with a remote peer.
*/
@NotNullByDefault
public interface ContactExchangeTask {
/**
* Exchanges contact information with a remote peer.
*/
void startExchange(ContactExchangeListener listener,
LocalAuthor localAuthor, SecretKey masterSecret,
DuplexTransportConnection conn, TransportId transportId,
boolean alice);
}

View File

@@ -1,9 +1,15 @@
package org.briarproject.api.contact;
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* Type-safe wrapper for an integer that uniquely identifies a contact within
* the scope of a single node.
*/
@Immutable
@NotNullByDefault
public class ContactId {
private final int id;

View File

@@ -0,0 +1,104 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Collection;
@NotNullByDefault
public interface ContactManager {
/**
* Registers a hook to be called whenever a contact is added.
*/
void registerAddContactHook(AddContactHook hook);
/**
* Registers a hook to be called whenever a contact is removed.
*/
void registerRemoveContactHook(RemoveContactHook hook);
/**
* Stores a contact within the given transaction associated with the given
* local and remote pseudonyms, and returns an ID for the contact.
*/
ContactId addContact(Transaction txn, Author remote, AuthorId local,
SecretKey master, long timestamp, boolean alice, boolean verified,
boolean active) throws DbException;
/**
* Stores a contact associated with the given local and remote pseudonyms,
* and returns an ID for the contact.
*/
ContactId addContact(Author remote, AuthorId local,
SecretKey master, long timestamp, boolean alice, boolean verified,
boolean active) throws DbException;
/**
* Returns the contact with the given ID.
*/
Contact getContact(ContactId c) throws DbException;
/**
* Returns the contact with the given remoteAuthorId
* that was added by the LocalAuthor with the given localAuthorId
*
* @throws org.briarproject.bramble.api.db.NoSuchContactException
*/
Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId)
throws DbException;
/**
* Returns the contact with the given remoteAuthorId
* that was added by the LocalAuthor with the given localAuthorId
*
* @throws org.briarproject.bramble.api.db.NoSuchContactException
*/
Contact getContact(Transaction txn, AuthorId remoteAuthorId,
AuthorId localAuthorId) throws DbException;
/**
* Returns all active contacts.
*/
Collection<Contact> getActiveContacts() throws DbException;
/**
* Removes a contact and all associated state.
*/
void removeContact(ContactId c) throws DbException;
/**
* Removes a contact and all associated state.
*/
void removeContact(Transaction txn, ContactId c) throws DbException;
/**
* Marks a contact as active or inactive.
*/
void setContactActive(Transaction txn, ContactId c, boolean active)
throws DbException;
/**
* Return true if a contact with this name and public key already exists
*/
boolean contactExists(Transaction txn, AuthorId remoteAuthorId,
AuthorId localAuthorId) throws DbException;
/**
* Return true if a contact with this name and public key already exists
*/
boolean contactExists(AuthorId remoteAuthorId, AuthorId localAuthorId)
throws DbException;
interface AddContactHook {
void addingContact(Transaction txn, Contact c) throws DbException;
}
interface RemoveContactHook {
void removingContact(Transaction txn, Contact c) throws DbException;
}
}

View File

@@ -0,0 +1,31 @@
package org.briarproject.bramble.api.contact.event;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a contact is added.
*/
@Immutable
@NotNullByDefault
public class ContactAddedEvent extends Event {
private final ContactId contactId;
private final boolean active;
public ContactAddedEvent(ContactId contactId, boolean active) {
this.contactId = contactId;
this.active = active;
}
public ContactId getContactId() {
return contactId;
}
public boolean isActive() {
return active;
}
}

View File

@@ -0,0 +1,25 @@
package org.briarproject.bramble.api.contact.event;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a contact is removed.
*/
@Immutable
@NotNullByDefault
public class ContactRemovedEvent extends Event {
private final ContactId contactId;
public ContactRemovedEvent(ContactId contactId) {
this.contactId = contactId;
}
public ContactId getContactId() {
return contactId;
}
}

View File

@@ -0,0 +1,31 @@
package org.briarproject.bramble.api.contact.event;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a contact is marked active or inactive.
*/
@Immutable
@NotNullByDefault
public class ContactStatusChangedEvent extends Event {
private final ContactId contactId;
private final boolean active;
public ContactStatusChangedEvent(ContactId contactId, boolean active) {
this.contactId = contactId;
this.active = active;
}
public ContactId getContactId() {
return contactId;
}
public boolean isActive() {
return active;
}
}

View File

@@ -0,0 +1,26 @@
package org.briarproject.bramble.api.contact.event;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a contact is verified.
*/
@Immutable
@NotNullByDefault
public class ContactVerifiedEvent extends Event {
private final ContactId contactId;
public ContactVerifiedEvent(ContactId contactId) {
this.contactId = contactId;
}
public ContactId getContactId() {
return contactId;
}
}

View File

@@ -1,7 +1,7 @@
package org.briarproject.api.crypto;
package org.briarproject.bramble.api.crypto;
import org.briarproject.api.TransportId;
import org.briarproject.api.transport.TransportKeys;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.transport.TransportKeys;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
@@ -10,10 +10,6 @@ public interface CryptoComponent {
SecretKey generateSecretKey();
MessageDigest getMessageDigest();
PseudoRandom getPseudoRandom(int seed1, int seed2);
SecureRandom getSecureRandom();
KeyPair generateAgreementKeyPair();
@@ -26,15 +22,6 @@ public interface CryptoComponent {
KeyParser getMessageKeyParser();
/** Generates a random invitation code. */
int generateBTInvitationCode();
/**
* Derives a confirmation code from the given master secret.
* @param alice whether the code is for use by Alice or Bob.
*/
int deriveBTConfirmationCode(SecretKey master, boolean alice);
/**
* Derives a stream header key from the given master secret.
* @param alice whether the key is for use by Alice or Bob.
@@ -139,7 +126,8 @@ public interface CryptoComponent {
TransportKeys rotateTransportKeys(TransportKeys k, long rotationPeriod);
/** Encodes the pseudo-random tag that is used to recognise a stream. */
void encodeTag(byte[] tag, SecretKey tagKey, long streamNumber);
void encodeTag(byte[] tag, SecretKey tagKey, int protocolVersion,
long streamNumber);
/**
* Signs the given byte[] with the given PrivateKey.
@@ -164,8 +152,17 @@ public interface CryptoComponent {
/**
* Returns the hash of the given inputs. The inputs are unambiguously
* combined by prefixing each input with its length.
*
* @param label A label specific to this hash to ensure that hashes
* calculated for distinct purposes don't collide.
*/
byte[] hash(byte[]... inputs);
byte[] hash(String label, byte[]... inputs);
/**
* Returns the length of hashes produced by
* the {@link CryptoComponent#hash(String, byte[]...)} method.
*/
int getHashLength();
/**
* Returns a message authentication code with the given key over the

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.crypto;
package org.briarproject.bramble.api.crypto;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

View File

@@ -1,6 +1,14 @@
package org.briarproject.api.crypto;
package org.briarproject.bramble.api.crypto;
/** A key pair consisting of a {@link PublicKey} and a {@link PrivateKey). */
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* A key pair consisting of a {@link PublicKey} and a {@link PrivateKey).
*/
@Immutable
@NotNullByDefault
public class KeyPair {
private final PublicKey publicKey;

View File

@@ -1,7 +1,10 @@
package org.briarproject.api.crypto;
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.security.GeneralSecurityException;
@NotNullByDefault
public interface KeyParser {
PublicKey parsePublicKey(byte[] encodedKey) throws GeneralSecurityException;

View File

@@ -1,11 +1,14 @@
package org.briarproject.api.crypto;
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface PasswordStrengthEstimator {
float NONE = 0;
float WEAK = 0.4f;
float QUITE_WEAK = 0.6f;
float QUITE_STRONG = 0.8f;
float WEAK = 0.25f;
float QUITE_WEAK = 0.5f;
float QUITE_STRONG = 0.75f;
float STRONG = 1;
/**

View File

@@ -0,0 +1,15 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
/**
* The private half of a public/private {@link KeyPair}.
*/
@NotNullByDefault
public interface PrivateKey {
/**
* Returns the encoded representation of this key.
*/
byte[] getEncoded();
}

View File

@@ -0,0 +1,15 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
/**
* The public half of a public/private {@link KeyPair}.
*/
@NotNullByDefault
public interface PublicKey {
/**
* Returns the encoded representation of this key.
*/
byte[] getEncoded();
}

View File

@@ -1,9 +1,14 @@
package org.briarproject.api.crypto;
package org.briarproject.bramble.api.crypto;
/** A secret key used for encryption and/or authentication. */
/**
* A secret key used for encryption and/or authentication.
*/
public class SecretKey {
public static final int LENGTH = 32; // Bytes
/**
* The length of a secret key in bytes.
*/
public static final int LENGTH = 32;
private final byte[] key;

View File

@@ -1,13 +1,17 @@
package org.briarproject.api.crypto;
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.IOException;
@NotNullByDefault
public interface StreamDecrypter {
/**
* Reads a frame, decrypts its payload into the given buffer and returns
* the payload length, or -1 if no more frames can be read from the stream.
* @throws java.io.IOException if an error occurs while reading the frame,
*
* @throws IOException if an error occurs while reading the frame,
* or if authenticated decryption fails.
*/
int readFrame(byte[] payload) throws IOException;

View File

@@ -0,0 +1,22 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.transport.StreamContext;
import java.io.InputStream;
@NotNullByDefault
public interface StreamDecrypterFactory {
/**
* Creates a {@link StreamDecrypter} for decrypting a transport stream.
*/
StreamDecrypter createStreamDecrypter(InputStream in, StreamContext ctx);
/**
* Creates a {@link StreamDecrypter} for decrypting a contact exchange
* stream.
*/
StreamDecrypter createContactExchangeStreamDecrypter(InputStream in,
SecretKey headerKey);
}

View File

@@ -0,0 +1,20 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.IOException;
@NotNullByDefault
public interface StreamEncrypter {
/**
* Encrypts the given frame and writes it to the stream.
*/
void writeFrame(byte[] payload, int payloadLength, int paddingLength,
boolean finalFrame) throws IOException;
/**
* Flushes the stream.
*/
void flush() throws IOException;
}

View File

@@ -0,0 +1,22 @@
package org.briarproject.bramble.api.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.transport.StreamContext;
import java.io.OutputStream;
@NotNullByDefault
public interface StreamEncrypterFactory {
/**
* Creates a {@link StreamEncrypter} for encrypting a transport stream.
*/
StreamEncrypter createStreamEncrypter(OutputStream out, StreamContext ctx);
/**
* Creates a {@link StreamEncrypter} for encrypting a contact exchange
* stream.
*/
StreamEncrypter createContactExchangeStreamDecrypter(OutputStream out,
SecretKey headerKey);
}

View File

@@ -1,14 +1,17 @@
package org.briarproject.api.data;
package org.briarproject.bramble.api.data;
import org.briarproject.api.Bytes;
import org.briarproject.api.FormatException;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
public class BdfDictionary extends ConcurrentSkipListMap<String, Object> {
@NotThreadSafe
public class BdfDictionary extends TreeMap<String, Object> {
public static final Object NULL_VALUE = new Object();

View File

@@ -1,7 +1,13 @@
package org.briarproject.api.data;
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Map.Entry;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class BdfEntry implements Entry<String, Object>, Comparable<BdfEntry> {
private final String key;

View File

@@ -1,16 +1,19 @@
package org.briarproject.api.data;
package org.briarproject.bramble.api.data;
import org.briarproject.api.Bytes;
import org.briarproject.api.FormatException;
import org.jetbrains.annotations.Nullable;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import static org.briarproject.api.data.BdfDictionary.NULL_VALUE;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
public class BdfList extends Vector<Object> {
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
@NotThreadSafe
public class BdfList extends ArrayList<Object> {
/**
* Factory method for constructing lists inline.

View File

@@ -1,49 +1,75 @@
package org.briarproject.api.data;
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.IOException;
@NotNullByDefault
public interface BdfReader {
int DEFAULT_NESTED_LIMIT = 5;
boolean eof() throws IOException;
void close() throws IOException;
boolean hasNull() throws IOException;
void readNull() throws IOException;
void skipNull() throws IOException;
boolean hasBoolean() throws IOException;
boolean readBoolean() throws IOException;
void skipBoolean() throws IOException;
boolean hasLong() throws IOException;
long readLong() throws IOException;
void skipLong() throws IOException;
boolean hasDouble() throws IOException;
double readDouble() throws IOException;
void skipDouble() throws IOException;
boolean hasString() throws IOException;
String readString(int maxLength) throws IOException;
void skipString() throws IOException;
boolean hasRaw() throws IOException;
byte[] readRaw(int maxLength) throws IOException;
void skipRaw() throws IOException;
boolean hasList() throws IOException;
BdfList readList() throws IOException;
void readListStart() throws IOException;
boolean hasListEnd() throws IOException;
void readListEnd() throws IOException;
void skipList() throws IOException;
boolean hasDictionary() throws IOException;
BdfDictionary readDictionary() throws IOException;
void readDictionaryStart() throws IOException;
boolean hasDictionaryEnd() throws IOException;
void readDictionaryEnd() throws IOException;
void skipDictionary() throws IOException;
}

View File

@@ -1,7 +1,10 @@
package org.briarproject.api.data;
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.InputStream;
@NotNullByDefault
public interface BdfReaderFactory {
BdfReader createReader(InputStream in);

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.data;
package org.briarproject.bramble.api.data;
import java.io.IOException;
import java.util.Collection;
@@ -7,20 +7,30 @@ import java.util.Map;
public interface BdfWriter {
void flush() throws IOException;
void close() throws IOException;
void writeNull() throws IOException;
void writeBoolean(boolean b) throws IOException;
void writeLong(long l) throws IOException;
void writeDouble(double d) throws IOException;
void writeString(String s) throws IOException;
void writeRaw(byte[] b) throws IOException;
void writeList(Collection<?> c) throws IOException;
void writeListStart() throws IOException;
void writeListEnd() throws IOException;
void writeDictionary(Map<?, ?> m) throws IOException;
void writeDictionaryStart() throws IOException;
void writeDictionaryEnd() throws IOException;
}

View File

@@ -0,0 +1,11 @@
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.OutputStream;
@NotNullByDefault
public interface BdfWriterFactory {
BdfWriter createWriter(OutputStream out);
}

View File

@@ -0,0 +1,11 @@
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface MetadataEncoder {
Metadata encode(BdfDictionary d) throws FormatException;
}

View File

@@ -0,0 +1,11 @@
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface MetadataParser {
BdfDictionary parse(Metadata m) throws FormatException;
}

View File

@@ -0,0 +1,11 @@
package org.briarproject.bramble.api.data;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.IOException;
@NotNullByDefault
public interface ObjectReader<T> {
T readObject(BdfReader r) throws IOException;
}

View File

@@ -1,9 +1,8 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
/**
* Thrown when a duplicate contact is added to the database. This exception may
* occur due to concurrent updates and does not indicate a database error.
*/
public class ContactExistsException extends DbException {
}

View File

@@ -0,0 +1,7 @@
package org.briarproject.bramble.api.db;
/**
* Thrown when the database uses a newer schema than the current code.
*/
public class DataTooNewException extends DbException {
}

View File

@@ -0,0 +1,8 @@
package org.briarproject.bramble.api.db;
/**
* Thrown when the database uses an older schema than the current code and
* cannot be migrated.
*/
public class DataTooOldException extends DbException {
}

View File

@@ -1,40 +1,49 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.Ack;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.Group.Visibility;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.MessageStatus;
import org.briarproject.api.sync.Offer;
import org.briarproject.api.sync.Request;
import org.briarproject.api.transport.TransportKeys;
import org.jetbrains.annotations.Nullable;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.sync.Ack;
import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.Group.Visibility;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.MessageStatus;
import org.briarproject.bramble.api.sync.Offer;
import org.briarproject.bramble.api.sync.Request;
import org.briarproject.bramble.api.sync.ValidationManager;
import org.briarproject.bramble.api.transport.TransportKeys;
import java.util.Collection;
import java.util.Map;
import static org.briarproject.api.sync.ValidationManager.State;
import javax.annotation.Nullable;
import static org.briarproject.bramble.api.sync.ValidationManager.State;
/**
* Encapsulates the database implementation and exposes high-level operations
* to other components.
*/
@NotNullByDefault
public interface DatabaseComponent {
/**
* Opens the database and returns true if the database already existed.
*
* @throws DataTooNewException if the data uses a newer schema than the
* current code
* @throws DataTooOldException if the data uses an older schema than the
* current code and cannot be migrated
*/
boolean open() throws DbException;
boolean open(@Nullable MigrationListener listener) throws DbException;
/**
* Waits for any open transactions to finish and closes the database.
@@ -118,8 +127,9 @@ public interface DatabaseComponent {
throws DbException;
/**
* Deletes the message with the given ID. The message ID and any other
* associated data are not deleted.
* Deletes the message with the given ID. Unlike
* {@link #removeMessage(Transaction, MessageId)}, the message ID and any
* other associated data are not deleted.
*/
void deleteMessage(Transaction txn, MessageId m) throws DbException;
@@ -249,31 +259,30 @@ public interface DatabaseComponent {
Collection<LocalAuthor> getLocalAuthors(Transaction txn) throws DbException;
/**
* Returns the IDs of any messages that need to be validated by the given
* client.
* Returns the IDs of any messages that need to be validated.
* <p/>
* Read-only.
*/
Collection<MessageId> getMessagesToValidate(Transaction txn, ClientId c)
Collection<MessageId> getMessagesToValidate(Transaction txn)
throws DbException;
/**
* Returns the IDs of any messages that are valid but pending delivery due
* to dependencies on other messages for the given client.
* Returns the IDs of any messages that are pending delivery due to
* dependencies on other messages.
* <p/>
* Read-only.
*/
Collection<MessageId> getPendingMessages(Transaction txn, ClientId c)
Collection<MessageId> getPendingMessages(Transaction txn)
throws DbException;
/**
* Returns the IDs of any messages from the given client
* that have a shared dependent, but are still not shared themselves.
* Returns the IDs of any messages that have shared dependents but have
* not yet been shared themselves.
* <p/>
* Read-only.
*/
Collection<MessageId> getMessagesToShare(Transaction txn,
ClientId c) throws DbException;
Collection<MessageId> getMessagesToShare(Transaction txn)
throws DbException;
/**
* Returns the message with the given ID, in serialised form, or null if
@@ -330,10 +339,10 @@ public interface DatabaseComponent {
/**
* Returns the IDs and states of all dependencies of the given message.
* Missing dependencies have the state {@link
* org.briarproject.api.sync.ValidationManager.State UNKNOWN}.
* Dependencies in other groups have the state {@link
* org.briarproject.api.sync.ValidationManager.State INVALID}.
* Missing dependencies have the state
* {@link ValidationManager.State UNKNOWN}.
* Dependencies in other groups have the state
* {@link ValidationManager.State INVALID}.
* Note that these states are not set on the dependencies themselves; the
* returned states should only be taken in the context of the given message.
* <p/>
@@ -368,6 +377,16 @@ public interface DatabaseComponent {
MessageStatus getMessageStatus(Transaction txn, ContactId c, MessageId m)
throws DbException;
/*
* Returns the next time (in milliseconds since the Unix epoch) when a
* message is due to be sent to the given contact. The returned value may
* be zero if a message is due to be sent immediately, or Long.MAX_VALUE if
* no messages are scheduled to be sent.
* <p/>
* Read-only.
*/
long getNextSendTime(Transaction txn, ContactId c) throws DbException;
/**
* Returns all settings in the given namespace.
* <p/>
@@ -448,6 +467,11 @@ public interface DatabaseComponent {
*/
void removeLocalAuthor(Transaction txn, AuthorId a) throws DbException;
/**
* Removes a message (and all associated state) from the database.
*/
void removeMessage(Transaction txn, MessageId m) throws DbException;
/**
* Removes a transport (and all associated state) from the database.
*/

View File

@@ -1,9 +1,13 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.File;
import javax.annotation.Nullable;
@NotNullByDefault
public interface DatabaseConfig {
boolean databaseExists();
@@ -12,10 +16,12 @@ public interface DatabaseConfig {
void setEncryptionKey(SecretKey key);
@Nullable
SecretKey getEncryptionKey();
void setLocalAuthorName(String nickname);
@Nullable
String getLocalAuthorName();
long getMaxSize();

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -20,6 +20,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* discarded.
*/
@Qualifier
@Target({ FIELD, METHOD, PARAMETER })
@Target({FIELD, METHOD, PARAMETER})
@Retention(RUNTIME)
public @interface DatabaseExecutor {}
public @interface DatabaseExecutor {
}

View File

@@ -1,8 +1,7 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
/**
* Thrown when a database operation is attempted and the database is closed.
*/
public class DbClosedException extends DbException {
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
public class DbException extends Exception {

View File

@@ -0,0 +1,14 @@
package org.briarproject.bramble.api.db;
import java.util.TreeMap;
import javax.annotation.concurrent.NotThreadSafe;
@NotThreadSafe
public class Metadata extends TreeMap<String, byte[]> {
/**
* Special value to indicate that a key is being removed.
*/
public static final byte[] REMOVE = new byte[0];
}

View File

@@ -0,0 +1,11 @@
package org.briarproject.bramble.api.db;
public interface MigrationListener {
/**
* This is called when a migration is started while opening the database.
* It will be called once for each migration being applied.
*/
void onMigrationRun();
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
/**
* Thrown when a database operation is attempted for a contact that is not in
@@ -6,5 +6,4 @@ package org.briarproject.api.db;
* not indicate a database error.
*/
public class NoSuchContactException extends DbException {
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
/**
* Thrown when a database operation is attempted for a group that is not in the
@@ -6,5 +6,4 @@ package org.briarproject.api.db;
* indicate a database error.
*/
public class NoSuchGroupException extends DbException {
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
/**
* Thrown when a database operation is attempted for a pseudonym that is not in
@@ -6,5 +6,4 @@ package org.briarproject.api.db;
* not indicate a database error.
*/
public class NoSuchLocalAuthorException extends DbException {
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
/**
* Thrown when a database operation is attempted for a message that is not in
@@ -6,5 +6,4 @@ package org.briarproject.api.db;
* not indicate a database error.
*/
public class NoSuchMessageException extends DbException {
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
/**
* Thrown when a database operation is attempted for a transport that is not in
@@ -6,5 +6,4 @@ package org.briarproject.api.db;
* not indicate a database error.
*/
public class NoSuchTransportException extends DbException {
}

View File

@@ -1,14 +1,17 @@
package org.briarproject.api.db;
package org.briarproject.bramble.api.db;
import org.briarproject.api.event.Event;
import org.briarproject.bramble.api.event.Event;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.concurrent.NotThreadSafe;
/**
* A wrapper around a database transaction. Transactions are not thread-safe.
*/
@NotThreadSafe
public class Transaction {
private final Object txn;
@@ -42,7 +45,7 @@ public class Transaction {
* committed.
*/
public void attach(Event e) {
if (events == null) events = new ArrayList<Event>();
if (events == null) events = new ArrayList<>();
events.add(e);
}

View File

@@ -0,0 +1,7 @@
package org.briarproject.bramble.api.event;
/**
* An abstract superclass for events.
*/
public abstract class Event {
}

View File

@@ -0,0 +1,22 @@
package org.briarproject.bramble.api.event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface EventBus {
/**
* Adds a listener to be notified when events occur.
*/
void addListener(EventListener l);
/**
* Removes a listener.
*/
void removeListener(EventListener l);
/**
* Notifies all listeners of an event.
*/
void broadcast(Event e);
}

View File

@@ -0,0 +1,16 @@
package org.briarproject.bramble.api.event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
/**
* An interface for receiving notifications when events occur.
*/
@NotNullByDefault
public interface EventListener {
/**
* Called when an event is broadcast. Implementations of this method must
* not block.
*/
void eventOccurred(Event e);
}

View File

@@ -1,11 +1,21 @@
package org.briarproject.api.identity;
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.UnsupportedEncodingException;
/** A pseudonym for a user. */
import javax.annotation.concurrent.Immutable;
/**
* A pseudonym for a user.
*/
@Immutable
@NotNullByDefault
public class Author {
public enum Status { ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES }
public enum Status {
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES
}
private final AuthorId id;
private final String name;
@@ -25,17 +35,23 @@ public class Author {
this.publicKey = publicKey;
}
/** Returns the author's unique identifier. */
/**
* Returns the author's unique identifier.
*/
public AuthorId getId() {
return id;
}
/** Returns the author's name. */
/**
* Returns the author's name.
*/
public String getName() {
return name;
}
/** Returns the public key used to verify the pseudonym's signatures. */
/**
* Returns the public key used to verify the pseudonym's signatures.
*/
public byte[] getPublicKey() {
return publicKey;
}

View File

@@ -1,8 +1,10 @@
package org.briarproject.api.identity;
package org.briarproject.bramble.api.identity;
public interface AuthorConstants {
/** The maximum length of an author's name in UTF-8 bytes. */
/**
* The maximum length of an author's name in UTF-8 bytes.
*/
int MAX_AUTHOR_NAME_LENGTH = 50;
/**

View File

@@ -1,5 +1,8 @@
package org.briarproject.api.identity;
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface AuthorFactory {
Author createAuthor(String name, byte[] publicKey);

View File

@@ -1,20 +1,22 @@
package org.briarproject.api.identity;
package org.briarproject.bramble.api.identity;
import org.briarproject.api.UniqueId;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.nio.charset.Charset;
import javax.annotation.concurrent.ThreadSafe;
/**
* Type-safe wrapper for a byte array that uniquely identifies an
* {@link org.briarproject.api.identity.Author Author}.
* {@link Author}.
*/
@ThreadSafe
@NotNullByDefault
public class AuthorId extends UniqueId {
/**
* Label for hashing authors to calculate their identities.
*/
public static final byte[] LABEL =
"AUTHOR_ID".getBytes(Charset.forName("US-ASCII"));
public static final String LABEL = "org.briarproject.bramble.AUTHOR_ID";
public AuthorId(byte[] id) {
super(id);

View File

@@ -0,0 +1,38 @@
package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author.Status;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface IdentityManager {
/**
* Stores the local pseudonym.
*/
void registerLocalAuthor(LocalAuthor a) throws DbException;
/**
* Returns the cached main local identity, non-blocking, or loads it from
* the db, blocking
*/
LocalAuthor getLocalAuthor() throws DbException;
/**
* Returns the cached main local identity, non-blocking, or loads it from
* the db, blocking, within the given Transaction.
*/
LocalAuthor getLocalAuthor(Transaction txn) throws DbException;
/**
* Returns the trust-level status of the author
*/
Status getAuthorStatus(AuthorId a) throws DbException;
/**
* Returns the trust-level status of the author
*/
Status getAuthorStatus(Transaction txn, AuthorId a) throws DbException;
}

View File

@@ -1,6 +1,14 @@
package org.briarproject.api.identity;
package org.briarproject.bramble.api.identity;
/** A pseudonym for the local user. */
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* A pseudonym for the local user.
*/
@Immutable
@NotNullByDefault
public class LocalAuthor extends Author {
private final byte[] privateKey;
@@ -13,7 +21,9 @@ public class LocalAuthor extends Author {
this.created = created;
}
/** Returns the private key used to generate the pseudonym's signatures. */
/**
* Returns the private key used to generate the pseudonym's signatures.
*/
public byte[] getPrivateKey() {
return privateKey;
}

View File

@@ -0,0 +1,25 @@
package org.briarproject.bramble.api.identity.event;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a local pseudonym is added.
*/
@Immutable
@NotNullByDefault
public class LocalAuthorAddedEvent extends Event {
private final AuthorId authorId;
public LocalAuthorAddedEvent(AuthorId authorId) {
this.authorId = authorId;
}
public AuthorId getAuthorId() {
return authorId;
}
}

View File

@@ -0,0 +1,25 @@
package org.briarproject.bramble.api.identity.event;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a local pseudonym is removed.
*/
@Immutable
@NotNullByDefault
public class LocalAuthorRemovedEvent extends Event {
private final AuthorId authorId;
public LocalAuthorRemovedEvent(AuthorId authorId) {
this.authorId = authorId;
}
public AuthorId getAuthorId() {
return authorId;
}
}

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